brave-real-browser-mcp-server 2.8.4 → 2.8.6
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.
|
@@ -120,11 +120,13 @@ export async function handleContentClassification(args) {
|
|
|
120
120
|
return { category: cat.name, score };
|
|
121
121
|
});
|
|
122
122
|
scores.sort((a, b) => b.score - a.score);
|
|
123
|
+
const confidence = scores[0].score / (scores.reduce((sum, s) => sum + s.score, 0) || 1);
|
|
124
|
+
const resultText = `✅ Content Classification\n\nPrimary Category: ${scores[0].category} (Score: ${scores[0].score})\nConfidence: ${(confidence * 100).toFixed(2)}%\n\nAll Categories:\n${JSON.stringify(scores.slice(0, 5), null, 2)}`;
|
|
123
125
|
return {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
content: [{
|
|
127
|
+
type: 'text',
|
|
128
|
+
text: resultText
|
|
129
|
+
}]
|
|
128
130
|
};
|
|
129
131
|
}
|
|
130
132
|
catch (error) {
|
|
@@ -173,23 +175,18 @@ export async function handleSentimentAnalysis(args) {
|
|
|
173
175
|
sentiment: s.score > 0 ? 'positive' : s.score < 0 ? 'negative' : 'neutral'
|
|
174
176
|
};
|
|
175
177
|
});
|
|
178
|
+
const stats = {
|
|
179
|
+
totalSentences: sentences.length,
|
|
180
|
+
positiveSentences: sentenceSentiments.filter(s => s.sentiment === 'positive').length,
|
|
181
|
+
negativeSentences: sentenceSentiments.filter(s => s.sentiment === 'negative').length,
|
|
182
|
+
neutralSentences: sentenceSentiments.filter(s => s.sentiment === 'neutral').length
|
|
183
|
+
};
|
|
184
|
+
const resultText = `✅ Sentiment Analysis\n\nOverall Sentiment: ${result.score > 0 ? 'Positive' : result.score < 0 ? 'Negative' : 'Neutral'}\nScore: ${result.score}\nComparative: ${result.comparative.toFixed(4)}\n\nStatistics:\n- Total Sentences: ${stats.totalSentences}\n- Positive: ${stats.positiveSentences}\n- Negative: ${stats.negativeSentences}\n- Neutral: ${stats.neutralSentences}\n\nPositive Words: ${result.positive.join(', ')}\nNegative Words: ${result.negative.join(', ')}`;
|
|
176
185
|
return {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
sentiment: result.score > 0 ? 'positive' : result.score < 0 ? 'negative' : 'neutral',
|
|
182
|
-
tokens: result.tokens.length,
|
|
183
|
-
positive: result.positive,
|
|
184
|
-
negative: result.negative
|
|
185
|
-
},
|
|
186
|
-
sentences: sentenceSentiments,
|
|
187
|
-
statistics: {
|
|
188
|
-
totalSentences: sentences.length,
|
|
189
|
-
positiveSentences: sentenceSentiments.filter(s => s.sentiment === 'positive').length,
|
|
190
|
-
negativeSentences: sentenceSentiments.filter(s => s.sentiment === 'negative').length,
|
|
191
|
-
neutralSentences: sentenceSentiments.filter(s => s.sentiment === 'neutral').length
|
|
192
|
-
}
|
|
186
|
+
content: [{
|
|
187
|
+
type: 'text',
|
|
188
|
+
text: resultText
|
|
189
|
+
}]
|
|
193
190
|
};
|
|
194
191
|
}
|
|
195
192
|
catch (error) {
|
|
@@ -254,20 +251,13 @@ export async function handleSummaryGenerator(args) {
|
|
|
254
251
|
// Sort by original order
|
|
255
252
|
topSentences.sort((a, b) => a.index - b.index);
|
|
256
253
|
const summary = topSentences.map(s => s.sentence).join(' ');
|
|
254
|
+
const compressionRatio = (summary.length / content.length * 100).toFixed(2);
|
|
255
|
+
const resultText = `✅ Summary Generated\n\nSummary:\n${summary}\n\nStatistics:\n- Original Length: ${content.length} characters\n- Summary Length: ${summary.length} characters\n- Compression Ratio: ${compressionRatio}%\n- Original Sentences: ${sentences.length}\n- Summary Sentences: ${topSentences.length}`;
|
|
257
256
|
return {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
compressionRatio: (summary.length / content.length * 100).toFixed(2) + '%',
|
|
263
|
-
sentenceCount: {
|
|
264
|
-
original: sentences.length,
|
|
265
|
-
summary: topSentences.length
|
|
266
|
-
},
|
|
267
|
-
topScoredSentences: topSentences.map(s => ({
|
|
268
|
-
sentence: s.sentence,
|
|
269
|
-
score: s.score.toFixed(2)
|
|
270
|
-
}))
|
|
257
|
+
content: [{
|
|
258
|
+
type: 'text',
|
|
259
|
+
text: resultText
|
|
260
|
+
}]
|
|
271
261
|
};
|
|
272
262
|
}
|
|
273
263
|
catch (error) {
|
|
@@ -328,18 +318,13 @@ export async function handleTranslationSupport(args) {
|
|
|
328
318
|
const keyPhrases = tfidf.listTerms(0)
|
|
329
319
|
.slice(0, 10)
|
|
330
320
|
.map(term => term.term);
|
|
321
|
+
const needsTranslation = detectedLang !== targetLanguage && detectedLang !== 'und';
|
|
322
|
+
const resultText = `✅ Translation Support\n\nDetected Language: ${languageName} (${detectedLang})\nTarget Language: ${targetLanguage}\nNeeds Translation: ${needsTranslation ? 'Yes' : 'No'}\n\nContent Length: ${contentToTranslate.length} characters\nContent Preview: ${contentToTranslate.substring(0, 200)}...\n\nKey Phrases: ${keyPhrases.join(', ')}\n\nNote: Use external translation API (Google Translate, DeepL) for actual translation`;
|
|
331
323
|
return {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
},
|
|
337
|
-
targetLanguage,
|
|
338
|
-
needsTranslation: detectedLang !== targetLanguage && detectedLang !== 'und',
|
|
339
|
-
contentPreview: contentToTranslate.substring(0, 200),
|
|
340
|
-
contentLength: contentToTranslate.length,
|
|
341
|
-
keyPhrases,
|
|
342
|
-
translationNote: 'Use external translation API (Google Translate, DeepL) for actual translation'
|
|
324
|
+
content: [{
|
|
325
|
+
type: 'text',
|
|
326
|
+
text: resultText
|
|
327
|
+
}]
|
|
343
328
|
};
|
|
344
329
|
}
|
|
345
330
|
catch (error) {
|
|
@@ -47,18 +47,23 @@ export async function handleOCREngine(args) {
|
|
|
47
47
|
bbox: word.bbox
|
|
48
48
|
}));
|
|
49
49
|
return {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
content: [
|
|
51
|
+
{
|
|
52
|
+
type: "text",
|
|
53
|
+
text: `OCR Results:\n- Extracted Text: ${text}\n- Confidence: ${confidence.toFixed(2)}%\n- Words Found: ${words.length}\n- Lines: ${result.data.lines.length}\n- Language: ${language}\n\nWords Detail:\n${words.map((w) => ` "${w.text}" (confidence: ${w.confidence.toFixed(2)}%)`).join('\n')}`
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
58
|
catch (error) {
|
|
59
59
|
return {
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
content: [
|
|
61
|
+
{
|
|
62
|
+
type: "text",
|
|
63
|
+
text: `OCR Engine Error: ${error.message}`
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
isError: true
|
|
62
67
|
};
|
|
63
68
|
}
|
|
64
69
|
}
|
|
@@ -106,17 +111,23 @@ export async function handleAudioCaptchaSolver(args) {
|
|
|
106
111
|
}
|
|
107
112
|
}
|
|
108
113
|
return {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
content: [
|
|
115
|
+
{
|
|
116
|
+
type: "text",
|
|
117
|
+
text: `Audio Captcha Analysis:\n- Audio URL: ${audioSource}\n- Downloaded: ${downloaded ? 'Yes' : 'No'}${downloaded ? `\n- Download Path: ${downloadPath}` : ''}\n\nNote: Audio captcha solving requires external speech-to-text API (Google Speech, AWS Transcribe, etc.)`
|
|
118
|
+
}
|
|
119
|
+
]
|
|
114
120
|
};
|
|
115
121
|
}
|
|
116
122
|
catch (error) {
|
|
117
123
|
return {
|
|
118
|
-
|
|
119
|
-
|
|
124
|
+
content: [
|
|
125
|
+
{
|
|
126
|
+
type: "text",
|
|
127
|
+
text: `Audio Captcha Solver Error: ${error.message}`
|
|
128
|
+
}
|
|
129
|
+
],
|
|
130
|
+
isError: true
|
|
120
131
|
};
|
|
121
132
|
}
|
|
122
133
|
}
|
|
@@ -208,16 +219,38 @@ export async function handlePuzzleCaptchaHandler(args) {
|
|
|
208
219
|
result.solveError = solveError.message;
|
|
209
220
|
}
|
|
210
221
|
}
|
|
222
|
+
let summary = `Puzzle Captcha Analysis:\n- Puzzle Found: ${result.puzzleFound ? 'Yes' : 'No'}\n- Slider Found: ${result.sliderFound ? 'Yes' : 'No'}`;
|
|
223
|
+
if (result.puzzle) {
|
|
224
|
+
summary += `\n\nPuzzle Details:\n- Dimensions: ${result.puzzle.width}x${result.puzzle.height}\n- Position: (${result.puzzle.left}, ${result.puzzle.top})\n- Visible: ${result.puzzle.visible ? 'Yes' : 'No'}`;
|
|
225
|
+
}
|
|
226
|
+
if (result.puzzlePiece) {
|
|
227
|
+
summary += `\n\nPuzzle Piece:\n- Dimensions: ${result.puzzlePiece.width}x${result.puzzlePiece.height}\n- Position: (${result.puzzlePiece.left}, ${result.puzzlePiece.top})`;
|
|
228
|
+
}
|
|
229
|
+
if (result.slider) {
|
|
230
|
+
summary += `\n\nSlider Details:\n- Dimensions: ${result.slider.width}x${result.slider.height}\n- Position: (${result.slider.left}, ${result.slider.top})\n- Visible: ${result.slider.visible ? 'Yes' : 'No'}\n- Tag: ${result.slider.tagName}`;
|
|
231
|
+
}
|
|
232
|
+
if (result.attemptedSolve) {
|
|
233
|
+
summary += `\n\nSolve Attempt:\n- Method: ${result.method}\n- Status: ${result.solveError ? 'Failed' : 'Completed'}${result.solveError ? `\n- Error: ${result.solveError}` : ''}`;
|
|
234
|
+
}
|
|
235
|
+
summary += `\n\nNote: Advanced puzzle solving requires computer vision libraries (OpenCV, TensorFlow)`;
|
|
211
236
|
return {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
237
|
+
content: [
|
|
238
|
+
{
|
|
239
|
+
type: "text",
|
|
240
|
+
text: summary
|
|
241
|
+
}
|
|
242
|
+
]
|
|
215
243
|
};
|
|
216
244
|
}
|
|
217
245
|
catch (error) {
|
|
218
246
|
return {
|
|
219
|
-
|
|
220
|
-
|
|
247
|
+
content: [
|
|
248
|
+
{
|
|
249
|
+
type: "text",
|
|
250
|
+
text: `Puzzle Captcha Handler Error: ${error.message}`
|
|
251
|
+
}
|
|
252
|
+
],
|
|
253
|
+
isError: true
|
|
221
254
|
};
|
|
222
255
|
}
|
|
223
256
|
}
|
|
@@ -240,19 +240,23 @@ export async function handleVideoRecording(args) {
|
|
|
240
240
|
}
|
|
241
241
|
}
|
|
242
242
|
return {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
note: 'For actual video file, use ffmpeg or puppeteer-screen-recorder library to combine frames'
|
|
243
|
+
content: [
|
|
244
|
+
{
|
|
245
|
+
type: "text",
|
|
246
|
+
text: `Video Recording Complete:\n- Duration: ${duration} seconds\n- FPS: ${fps}\n- Frames Captured: ${frames.length}\n- Output Path: ${outputPath}\n- Sample Frames:\n${frames.slice(0, 5).map((f, i) => ` ${i + 1}. ${f}`).join('\n')}\n\nNote: For actual video file, use ffmpeg or puppeteer-screen-recorder library to combine frames`
|
|
247
|
+
}
|
|
248
|
+
]
|
|
250
249
|
};
|
|
251
250
|
}
|
|
252
251
|
catch (error) {
|
|
253
252
|
return {
|
|
254
|
-
|
|
255
|
-
|
|
253
|
+
content: [
|
|
254
|
+
{
|
|
255
|
+
type: "text",
|
|
256
|
+
text: `Video Recording Error: ${error.message}`
|
|
257
|
+
}
|
|
258
|
+
],
|
|
259
|
+
isError: true
|
|
256
260
|
};
|
|
257
261
|
}
|
|
258
262
|
}
|
|
@@ -273,10 +277,13 @@ export async function handleVisualComparison(args) {
|
|
|
273
277
|
// Check if dimensions match
|
|
274
278
|
if (img1.width !== img2.width || img1.height !== img2.height) {
|
|
275
279
|
return {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
+
content: [
|
|
281
|
+
{
|
|
282
|
+
type: "text",
|
|
283
|
+
text: `Image dimensions do not match:\n- Image 1: ${img1.width}x${img1.height}\n- Image 2: ${img2.width}x${img2.height}`
|
|
284
|
+
}
|
|
285
|
+
],
|
|
286
|
+
isError: true
|
|
280
287
|
};
|
|
281
288
|
}
|
|
282
289
|
// Create diff image
|
|
@@ -291,27 +298,25 @@ export async function handleVisualComparison(args) {
|
|
|
291
298
|
}
|
|
292
299
|
const totalPixels = img1.width * img1.height;
|
|
293
300
|
const diffPercentage = (numDiffPixels / totalPixels) * 100;
|
|
301
|
+
const similarity = ((1 - (numDiffPixels / totalPixels)) * 100).toFixed(2);
|
|
294
302
|
return {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
},
|
|
302
|
-
dimensions: {
|
|
303
|
-
width: img1.width,
|
|
304
|
-
height: img1.height
|
|
305
|
-
},
|
|
306
|
-
threshold,
|
|
307
|
-
diffImagePath: diffOutputPath,
|
|
308
|
-
similarity: ((1 - (numDiffPixels / totalPixels)) * 100).toFixed(2) + '%'
|
|
303
|
+
content: [
|
|
304
|
+
{
|
|
305
|
+
type: "text",
|
|
306
|
+
text: `Visual Comparison Results:\n- Identical: ${numDiffPixels === 0 ? 'Yes' : 'No'}\n- Similarity: ${similarity}%\n- Different Pixels: ${numDiffPixels} (${diffPercentage.toFixed(2)}%)\n- Total Pixels: ${totalPixels}\n- Image Dimensions: ${img1.width}x${img1.height}\n- Threshold: ${threshold}${diffOutputPath ? `\n- Diff Image Saved: ${diffOutputPath}` : ''}`
|
|
307
|
+
}
|
|
308
|
+
]
|
|
309
309
|
};
|
|
310
310
|
}
|
|
311
311
|
catch (error) {
|
|
312
312
|
return {
|
|
313
|
-
|
|
314
|
-
|
|
313
|
+
content: [
|
|
314
|
+
{
|
|
315
|
+
type: "text",
|
|
316
|
+
text: `Visual Comparison Error: ${error.message}`
|
|
317
|
+
}
|
|
318
|
+
],
|
|
319
|
+
isError: true
|
|
315
320
|
};
|
|
316
321
|
}
|
|
317
322
|
}
|