@agentdao/core
Version:
Core functionality, skills, and ready-made UI components for AgentDAO - Web3 subscriptions, content generation, social media, help support, live chat, RSS fetching, web search, and agent pricing integration
300 lines (299 loc) • 11.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebSearchSkill = void 0;
const search_utils_1 = require("./search-utils");
const robust_utils_1 = require("./robust-utils");
const AnalyticsService_1 = require("./AnalyticsService");
class WebSearchSkill {
constructor(config) {
if (!config.ai?.apiKey) {
throw new Error('No OpenAI API key provided. Please add your key in Settings > API Keys.');
}
this.config = {
...config,
search: {
provider: 'google', // Default to Google, fallback to OpenAI if no API key
maxResults: 10,
includeImages: false,
includeNews: false,
...config.search
},
ai: {
maxTokens: 2000,
temperature: 0.7,
...config.ai
},
robust: {
enableRetry: true,
enableRateLimit: true,
enableCache: true,
enableCircuitBreaker: true,
...config.robust
}
};
if (this.config.robust?.enableCache) {
this.cache = robust_utils_1.RobustUtils.createCache(300000);
}
if (this.config.robust?.enableCircuitBreaker) {
this.circuitBreaker = robust_utils_1.RobustUtils.createCircuitBreaker(5, 60000);
}
}
async searchWeb(options) {
const startTime = Date.now();
try {
// Track skill usage
await (0, AnalyticsService_1.trackSkillUsage)('WebSearchSkill', this.config.agentId, {
query: options.query,
provider: options.provider || this.config.search.provider,
maxResults: options.maxResults
});
// Validate input
const validation = robust_utils_1.RobustUtils.validateSearchQuery(options.query);
if (!validation.isValid) {
throw new Error(`Invalid search query: ${validation.errors.join(', ')}`);
}
const sanitizedQuery = robust_utils_1.RobustUtils.sanitizeInput(options.query);
const cacheKey = `web_search_${sanitizedQuery}_${JSON.stringify(options)}`;
// Check cache first
if (this.config.robust?.enableCache && this.cache) {
const cached = this.cache.get(cacheKey);
if (cached) {
// Track cache hit
await (0, AnalyticsService_1.trackApiCall)('cache_hit', true, Date.now() - startTime, {
skill: 'WebSearchSkill',
query: options.query
});
return cached;
}
}
const searchOptions = {
maxResults: options.maxResults || this.config.search.maxResults,
includeImages: options.includeImages || this.config.search.includeImages,
includeNews: options.includeNews || this.config.search.includeNews,
language: options.language,
region: options.region,
timeRange: options.timeRange,
provider: options.provider || this.config.search.provider
};
// Execute search with robust features
const searchFn = () => search_utils_1.SearchProviders.searchWeb(sanitizedQuery, searchOptions);
let results;
if (this.config.robust?.enableCircuitBreaker && this.circuitBreaker) {
results = await this.circuitBreaker.execute(searchFn);
}
else if (this.config.robust?.enableRetry && this.config.robust?.enableRateLimit) {
results = await robust_utils_1.RobustUtils.withRetryAndRateLimit(`web_search_${this.config.agentId}`, searchFn);
}
else if (this.config.robust?.enableRetry) {
results = await robust_utils_1.RobustUtils.withRetry(searchFn);
}
else if (this.config.robust?.enableRateLimit) {
results = await robust_utils_1.RobustUtils.withRateLimit(`web_search_${this.config.agentId}`, searchFn);
}
else {
results = await searchFn();
}
// Cache results
if (this.config.robust?.enableCache && this.cache) {
this.cache.set(cacheKey, results);
}
// Track successful API call
await (0, AnalyticsService_1.trackApiCall)('web_search', true, Date.now() - startTime, {
skill: 'WebSearchSkill',
query: options.query,
resultCount: results.length,
provider: searchOptions.provider
});
return results;
}
catch (error) {
// Track error
await (0, AnalyticsService_1.trackError)(error, 'WebSearchSkill.searchWeb', this.config.agentId, {
query: options.query,
provider: options.provider || this.config.search.provider
});
// Track failed API call
await (0, AnalyticsService_1.trackApiCall)('web_search', false, Date.now() - startTime, {
skill: 'WebSearchSkill',
query: options.query,
error: error.message
});
throw error;
}
}
async searchNews(query, options = {}) {
const validation = robust_utils_1.RobustUtils.validateSearchQuery(query);
if (!validation.isValid) {
throw new Error(`Invalid search query: ${validation.errors.join(', ')}`);
}
const sanitizedQuery = robust_utils_1.RobustUtils.sanitizeInput(query);
const cacheKey = `news_search_${sanitizedQuery}_${JSON.stringify(options)}`;
if (this.config.robust?.enableCache && this.cache) {
const cached = this.cache.get(cacheKey);
if (cached) {
return cached;
}
}
const searchFn = () => search_utils_1.SearchProviders.searchNews(sanitizedQuery, {
maxResults: 5,
timeRange: 'week',
...options
});
let results;
if (this.config.robust?.enableCircuitBreaker && this.circuitBreaker) {
results = await this.circuitBreaker.execute(searchFn);
}
else if (this.config.robust?.enableRetry) {
results = await robust_utils_1.RobustUtils.withRetry(searchFn);
}
else {
results = await searchFn();
}
if (this.config.robust?.enableCache && this.cache) {
this.cache.set(cacheKey, results);
}
return results;
}
async searchImages(query, options = {}) {
const validation = robust_utils_1.RobustUtils.validateSearchQuery(query);
if (!validation.isValid) {
throw new Error(`Invalid search query: ${validation.errors.join(', ')}`);
}
const sanitizedQuery = robust_utils_1.RobustUtils.sanitizeInput(query);
const cacheKey = `image_search_${sanitizedQuery}_${JSON.stringify(options)}`;
if (this.config.robust?.enableCache && this.cache) {
const cached = this.cache.get(cacheKey);
if (cached) {
return cached;
}
}
const searchFn = () => search_utils_1.SearchProviders.searchImages(sanitizedQuery, {
maxResults: 10,
...options
});
let results;
if (this.config.robust?.enableCircuitBreaker && this.circuitBreaker) {
results = await this.circuitBreaker.execute(searchFn);
}
else if (this.config.robust?.enableRetry) {
results = await robust_utils_1.RobustUtils.withRetry(searchFn);
}
else {
results = await searchFn();
}
if (this.config.robust?.enableCache && this.cache) {
this.cache.set(cacheKey, results);
}
return results;
}
async searchWithAI(query, context) {
const validation = robust_utils_1.RobustUtils.validateSearchQuery(query);
if (!validation.isValid) {
throw new Error(`Invalid search query: ${validation.errors.join(', ')}`);
}
const sanitizedQuery = robust_utils_1.RobustUtils.sanitizeInput(query);
const sanitizedContext = context ? robust_utils_1.RobustUtils.sanitizeInput(context) : undefined;
const cacheKey = `ai_search_${sanitizedQuery}_${sanitizedContext || 'no_context'}`;
if (this.config.robust?.enableCache && this.cache) {
const cached = this.cache.get(cacheKey);
if (cached) {
// Return cached AI search result
return {
searchResults: cached,
aiAnalysis: 'Cached analysis',
summary: 'Cached summary',
recommendations: ['Use cached results']
};
}
}
const searchFn = () => search_utils_1.SearchProviders.searchWithAI(sanitizedQuery, sanitizedContext);
let results;
if (this.config.robust?.enableCircuitBreaker && this.circuitBreaker) {
results = await this.circuitBreaker.execute(searchFn);
}
else if (this.config.robust?.enableRetry) {
results = await robust_utils_1.RobustUtils.withRetry(searchFn);
}
else {
results = await searchFn();
}
if (this.config.robust?.enableCache && this.cache) {
this.cache.set(cacheKey, results.searchResults);
}
return results;
}
/**
* Validate search query
*/
async validateQuery(query) {
const validation = robust_utils_1.RobustUtils.validateSearchQuery(query);
if (!validation.isValid) {
return {
isValid: false,
errors: validation.errors,
suggestions: [
'Keep queries between 3-100 characters',
'Avoid special characters except basic punctuation',
'Use descriptive keywords',
'Check spelling and grammar'
]
};
}
// Additional validation logic could go here
const suggestions = [];
if (query.length < 10) {
suggestions.push('Consider adding more specific keywords for better results');
}
if (!query.includes(' ') && query.length > 20) {
suggestions.push('Consider breaking down long queries into multiple words');
}
return {
isValid: true,
errors: [],
suggestions
};
}
/**
* Save search results to database (if configured)
*/
async saveSearch(query, results) {
if (!this.config.database?.endpoint) {
return; // No database configured
}
try {
// This would save to the database
// Implementation depends on the database setup
console.log(`Saving search results for query: "${query}"`);
}
catch (error) {
console.error('Failed to save search results:', error);
}
}
/**
* Clear the search cache
*/
clearCache() {
if (this.cache) {
this.cache.clear();
}
}
/**
* Get circuit breaker state
*/
getCircuitBreakerState() {
if (!this.circuitBreaker) {
return 'disabled';
}
return this.circuitBreaker.getState();
}
/**
* Get cache size
*/
getCacheSize() {
if (!this.cache) {
return 0;
}
return this.cache.size();
}
}
exports.WebSearchSkill = WebSearchSkill;