mirror of
https://github.com/aaronjmars/opendia.git
synced 2025-12-29 16:16:00 +00:00
fix tools
This commit is contained in:
@@ -213,17 +213,6 @@ function getAvailableTools() {
|
|||||||
required: ["condition_type"]
|
required: ["condition_type"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "browser_navigate",
|
|
||||||
description: "Navigate to a URL in the active tab",
|
|
||||||
inputSchema: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
url: { type: "string", description: "URL to navigate to" },
|
|
||||||
},
|
|
||||||
required: ["url"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// Tab Management Tools
|
// Tab Management Tools
|
||||||
{
|
{
|
||||||
@@ -521,9 +510,6 @@ async function handleMCPRequest(message) {
|
|||||||
case "page_wait_for":
|
case "page_wait_for":
|
||||||
result = await sendToContentScript('wait_for', params);
|
result = await sendToContentScript('wait_for', params);
|
||||||
break;
|
break;
|
||||||
case "browser_navigate":
|
|
||||||
result = await navigateToUrl(params.url);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Tab management tools
|
// Tab management tools
|
||||||
case "tab_create":
|
case "tab_create":
|
||||||
|
|||||||
@@ -201,179 +201,6 @@ const PATTERN_DATABASE = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Token usage tracking and performance optimization
|
|
||||||
class TokenOptimizer {
|
|
||||||
constructor() {
|
|
||||||
this.metrics = JSON.parse(localStorage.getItem("opendia_metrics") || "[]");
|
|
||||||
this.successRates = JSON.parse(
|
|
||||||
localStorage.getItem("opendia_success_rates") || "{}"
|
|
||||||
);
|
|
||||||
this.recommendedMaxResults = 5;
|
|
||||||
this.lastCleanup = Date.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
trackUsage(
|
|
||||||
operation,
|
|
||||||
tokenCount,
|
|
||||||
success,
|
|
||||||
pageType = "unknown",
|
|
||||||
method = "unknown"
|
|
||||||
) {
|
|
||||||
const metric = {
|
|
||||||
operation,
|
|
||||||
tokens: tokenCount,
|
|
||||||
success,
|
|
||||||
pageType,
|
|
||||||
method,
|
|
||||||
timestamp: Date.now(),
|
|
||||||
};
|
|
||||||
|
|
||||||
this.metrics.push(metric);
|
|
||||||
|
|
||||||
// Keep only last 100 metrics to prevent storage bloat
|
|
||||||
if (this.metrics.length > 100) {
|
|
||||||
this.metrics = this.metrics.slice(-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-adjust limits based on success rates
|
|
||||||
this.adjustLimits();
|
|
||||||
|
|
||||||
// Periodic cleanup (once per hour)
|
|
||||||
if (Date.now() - this.lastCleanup > 3600000) {
|
|
||||||
this.cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Persist to localStorage
|
|
||||||
localStorage.setItem("opendia_metrics", JSON.stringify(this.metrics));
|
|
||||||
}
|
|
||||||
|
|
||||||
adjustLimits() {
|
|
||||||
const recent = this.metrics.slice(-20);
|
|
||||||
if (recent.length < 10) return;
|
|
||||||
|
|
||||||
const avgTokens =
|
|
||||||
recent.reduce((sum, m) => sum + m.tokens, 0) / recent.length;
|
|
||||||
const successRate = recent.filter((m) => m.success).length / recent.length;
|
|
||||||
|
|
||||||
// If using too many tokens but success rate is high, reduce max results
|
|
||||||
if (avgTokens > 200 && successRate > 0.8) {
|
|
||||||
this.recommendedMaxResults = Math.max(3, this.recommendedMaxResults - 1);
|
|
||||||
}
|
|
||||||
// If success rate is low, increase max results to get better matches
|
|
||||||
else if (successRate < 0.6) {
|
|
||||||
this.recommendedMaxResults = Math.min(10, this.recommendedMaxResults + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
// Remove metrics older than 7 days
|
|
||||||
const cutoff = Date.now() - 7 * 24 * 60 * 60 * 1000;
|
|
||||||
this.metrics = this.metrics.filter((m) => m.timestamp > cutoff);
|
|
||||||
|
|
||||||
// Clean up success rates for rarely used combinations
|
|
||||||
const recentPageTypes = new Set(this.metrics.map((m) => m.pageType));
|
|
||||||
Object.keys(this.successRates).forEach((key) => {
|
|
||||||
const [pageType] = key.split(":");
|
|
||||||
if (!recentPageTypes.has(pageType)) {
|
|
||||||
delete this.successRates[key];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
localStorage.setItem("opendia_metrics", JSON.stringify(this.metrics));
|
|
||||||
localStorage.setItem(
|
|
||||||
"opendia_success_rates",
|
|
||||||
JSON.stringify(this.successRates)
|
|
||||||
);
|
|
||||||
this.lastCleanup = Date.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
trackMethodSuccess(pageType, intent, method, success) {
|
|
||||||
const key = `${pageType}:${intent}:${method}`;
|
|
||||||
if (!this.successRates[key]) {
|
|
||||||
this.successRates[key] = { attempts: 0, successes: 0 };
|
|
||||||
}
|
|
||||||
|
|
||||||
this.successRates[key].attempts++;
|
|
||||||
if (success) {
|
|
||||||
this.successRates[key].successes++;
|
|
||||||
}
|
|
||||||
|
|
||||||
localStorage.setItem(
|
|
||||||
"opendia_success_rates",
|
|
||||||
JSON.stringify(this.successRates)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
getBestMethod(pageType, intent) {
|
|
||||||
const methods = [
|
|
||||||
"anti_detection_bypass",
|
|
||||||
"enhanced_pattern_match",
|
|
||||||
"pattern_database",
|
|
||||||
"viewport_scan",
|
|
||||||
"semantic_analysis",
|
|
||||||
];
|
|
||||||
|
|
||||||
return methods.sort((a, b) => {
|
|
||||||
const aKey = `${pageType}:${intent}:${a}`;
|
|
||||||
const bKey = `${pageType}:${intent}:${b}`;
|
|
||||||
const aRate = this.getSuccessRate(aKey);
|
|
||||||
const bRate = this.getSuccessRate(bKey);
|
|
||||||
return bRate - aRate;
|
|
||||||
})[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
getSuccessRate(key) {
|
|
||||||
const data = this.successRates[key];
|
|
||||||
if (!data || data.attempts === 0) return 0;
|
|
||||||
return data.successes / data.attempts;
|
|
||||||
}
|
|
||||||
|
|
||||||
getRecommendedMaxResults() {
|
|
||||||
return this.recommendedMaxResults;
|
|
||||||
}
|
|
||||||
|
|
||||||
getAnalytics() {
|
|
||||||
const recent = this.metrics.slice(-50);
|
|
||||||
if (recent.length === 0) return { message: "No metrics available" };
|
|
||||||
|
|
||||||
const avgTokens =
|
|
||||||
recent.reduce((sum, m) => sum + m.tokens, 0) / recent.length;
|
|
||||||
const successRate = recent.filter((m) => m.success).length / recent.length;
|
|
||||||
const operationBreakdown = {};
|
|
||||||
const methodBreakdown = {};
|
|
||||||
|
|
||||||
recent.forEach((m) => {
|
|
||||||
operationBreakdown[m.operation] =
|
|
||||||
(operationBreakdown[m.operation] || 0) + 1;
|
|
||||||
methodBreakdown[m.method] = (methodBreakdown[m.method] || 0) + 1;
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
totalOperations: recent.length,
|
|
||||||
avgTokensPerOperation: Math.round(avgTokens),
|
|
||||||
successRate: Math.round(successRate * 100),
|
|
||||||
recommendedMaxResults: this.recommendedMaxResults,
|
|
||||||
operationBreakdown,
|
|
||||||
methodBreakdown,
|
|
||||||
tokenSavings: this.calculateTokenSavings(recent),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateTokenSavings(metrics) {
|
|
||||||
// Estimate token savings vs naive approach
|
|
||||||
const actualTokens = metrics.reduce((sum, m) => sum + m.tokens, 0);
|
|
||||||
const estimatedNaiveTokens = metrics.length * 300; // Estimate for non-optimized approach
|
|
||||||
const savings = estimatedNaiveTokens - actualTokens;
|
|
||||||
const percentage = Math.round((savings / estimatedNaiveTokens) * 100);
|
|
||||||
|
|
||||||
return {
|
|
||||||
actualTokens,
|
|
||||||
estimatedNaiveTokens,
|
|
||||||
tokensSaved: savings,
|
|
||||||
percentageSaved: percentage,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class BrowserAutomation {
|
class BrowserAutomation {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -381,7 +208,6 @@ class BrowserAutomation {
|
|||||||
this.quickRegistry = new Map(); // For phase 1 quick matches
|
this.quickRegistry = new Map(); // For phase 1 quick matches
|
||||||
this.idCounter = 0;
|
this.idCounter = 0;
|
||||||
this.quickIdCounter = 0;
|
this.quickIdCounter = 0;
|
||||||
this.tokenOptimizer = new TokenOptimizer();
|
|
||||||
this.setupMessageListener();
|
this.setupMessageListener();
|
||||||
this.setupViewportAnalyzer();
|
this.setupViewportAnalyzer();
|
||||||
}
|
}
|
||||||
@@ -439,22 +265,6 @@ class BrowserAutomation {
|
|||||||
case "wait_for":
|
case "wait_for":
|
||||||
result = await this.waitForCondition(data);
|
result = await this.waitForCondition(data);
|
||||||
break;
|
break;
|
||||||
case "getPageInfo":
|
|
||||||
result = {
|
|
||||||
title: document.title,
|
|
||||||
url: window.location.href,
|
|
||||||
content: document.body.innerText,
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case "get_analytics":
|
|
||||||
result = this.tokenOptimizer.getAnalytics();
|
|
||||||
break;
|
|
||||||
case "clear_analytics":
|
|
||||||
localStorage.removeItem("opendia_metrics");
|
|
||||||
localStorage.removeItem("opendia_success_rates");
|
|
||||||
this.tokenOptimizer = new TokenOptimizer();
|
|
||||||
result = { message: "Analytics cleared successfully" };
|
|
||||||
break;
|
|
||||||
case "get_element_state":
|
case "get_element_state":
|
||||||
const element = this.getElementById(data.element_id);
|
const element = this.getElementById(data.element_id);
|
||||||
if (!element) {
|
if (!element) {
|
||||||
@@ -811,13 +621,8 @@ class BrowserAutomation {
|
|||||||
const pageType = this.detectPageType();
|
const pageType = this.detectPageType();
|
||||||
const viewportElements = this.countViewportElements();
|
const viewportElements = this.countViewportElements();
|
||||||
|
|
||||||
// Use token optimizer recommendations
|
// Use default max results limit
|
||||||
const recommendedMaxResults =
|
max_results = Math.min(max_results, 5);
|
||||||
this.tokenOptimizer.getRecommendedMaxResults();
|
|
||||||
max_results = Math.min(max_results, recommendedMaxResults);
|
|
||||||
|
|
||||||
// Get best method based on historical performance
|
|
||||||
const bestMethod = this.tokenOptimizer.getBestMethod(pageType, intent_hint);
|
|
||||||
|
|
||||||
// Try to find obvious matches using enhanced patterns
|
// Try to find obvious matches using enhanced patterns
|
||||||
let quickMatches = [];
|
let quickMatches = [];
|
||||||
@@ -893,22 +698,6 @@ class BrowserAutomation {
|
|||||||
elements: quickMatches, // Add this for backward compatibility
|
elements: quickMatches, // Add this for backward compatibility
|
||||||
};
|
};
|
||||||
|
|
||||||
// Track token usage and success
|
|
||||||
const tokenCount = this.estimateTokenUsage(result);
|
|
||||||
const success = quickMatches.length > 0 && intentMatch !== "none";
|
|
||||||
this.tokenOptimizer.trackUsage(
|
|
||||||
"page_analyze_discover",
|
|
||||||
tokenCount,
|
|
||||||
success,
|
|
||||||
pageType,
|
|
||||||
usedMethod
|
|
||||||
);
|
|
||||||
this.tokenOptimizer.trackMethodSuccess(
|
|
||||||
pageType,
|
|
||||||
intent_hint,
|
|
||||||
usedMethod,
|
|
||||||
success
|
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -968,10 +757,8 @@ class BrowserAutomation {
|
|||||||
const startTime = performance.now();
|
const startTime = performance.now();
|
||||||
const pageType = this.detectPageType();
|
const pageType = this.detectPageType();
|
||||||
|
|
||||||
// Use token optimizer recommendations
|
// Use default max results limit
|
||||||
const recommendedMaxResults =
|
max_results = Math.min(max_results, 7); // Allow slightly more for detailed analysis
|
||||||
this.tokenOptimizer.getRecommendedMaxResults();
|
|
||||||
max_results = Math.min(max_results, recommendedMaxResults + 2); // Allow slightly more for detailed analysis
|
|
||||||
|
|
||||||
let elements = [];
|
let elements = [];
|
||||||
let method = "detailed_analysis";
|
let method = "detailed_analysis";
|
||||||
@@ -1016,22 +803,6 @@ class BrowserAutomation {
|
|||||||
intent_hint: intent_hint, // Add this for server.js compatibility
|
intent_hint: intent_hint, // Add this for server.js compatibility
|
||||||
};
|
};
|
||||||
|
|
||||||
// Track token usage and success
|
|
||||||
const tokenCount = this.estimateTokenUsage(result);
|
|
||||||
const success = elements.length > 0 && elements.some((el) => el.conf > 70);
|
|
||||||
this.tokenOptimizer.trackUsage(
|
|
||||||
"page_analyze_detailed",
|
|
||||||
tokenCount,
|
|
||||||
success,
|
|
||||||
pageType,
|
|
||||||
method
|
|
||||||
);
|
|
||||||
this.tokenOptimizer.trackMethodSuccess(
|
|
||||||
pageType,
|
|
||||||
intent_hint,
|
|
||||||
method,
|
|
||||||
success
|
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -743,35 +743,6 @@ function getFallbackTools() {
|
|||||||
required: ["condition_type"],
|
required: ["condition_type"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "get_analytics",
|
|
||||||
description: "📊 Get performance analytics and token usage metrics",
|
|
||||||
inputSchema: {
|
|
||||||
type: "object",
|
|
||||||
properties: {},
|
|
||||||
additionalProperties: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "clear_analytics",
|
|
||||||
description: "🗑️ Clear analytics data and reset performance tracking",
|
|
||||||
inputSchema: {
|
|
||||||
type: "object",
|
|
||||||
properties: {},
|
|
||||||
additionalProperties: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "browser_navigate",
|
|
||||||
description: "🌐 Navigate to URLs - legacy (Extension required)",
|
|
||||||
inputSchema: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
url: { type: "string", description: "URL to navigate to" },
|
|
||||||
},
|
|
||||||
required: ["url"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Tab Management Tools
|
// Tab Management Tools
|
||||||
{
|
{
|
||||||
name: "tab_create",
|
name: "tab_create",
|
||||||
@@ -866,18 +837,6 @@ function getFallbackTools() {
|
|||||||
required: ["element_id"]
|
required: ["element_id"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "browser_execute_script",
|
|
||||||
description:
|
|
||||||
"⚡ Execute JavaScript (Extension required - limited by CSP)",
|
|
||||||
inputSchema: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
code: { type: "string", description: "JavaScript code" },
|
|
||||||
},
|
|
||||||
required: ["code"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Workspace and Reference Management Tools
|
// Workspace and Reference Management Tools
|
||||||
{
|
{
|
||||||
name: "get_bookmarks",
|
name: "get_bookmarks",
|
||||||
|
|||||||
Reference in New Issue
Block a user