@framers/agentos-ext-web-search 1.1.0 → 1.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.
@@ -1,70 +1,79 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WebSearchTool = void 0;
4
1
  /**
5
- * Web search tool that queries multiple search providers
2
+ * Web Search Tool — multi-provider search via SearchProviderService.
6
3
  *
7
- * @class WebSearchTool
8
- * @implements {ITool}
4
+ * Updated to conform to AgentOS `ITool` (inputSchema + ToolExecutionContext).
9
5
  *
10
- * @example
11
- * ```typescript
12
- * const tool = new WebSearchTool(searchService);
13
- * const result = await tool.execute({
14
- * query: 'AgentOS extensions',
15
- * maxResults: 10,
16
- * provider: 'serper'
17
- * });
18
- * ```
6
+ * @module @framers/agentos-ext-web-search
19
7
  */
20
- class WebSearchTool {
8
+ export class WebSearchTool {
21
9
  searchService;
22
- id = 'webSearch';
23
- name = 'Web Search';
24
- description = 'Search the web using multiple providers';
25
- /**
26
- * Creates an instance of WebSearchTool
27
- * @param {SearchProviderService} searchService - The search provider service
28
- */
29
- constructor(searchService) {
10
+ defaultMultiSearch;
11
+ id = 'web-search-v1';
12
+ /** Tool call name used by the LLM / ToolExecutor. */
13
+ name = 'web_search';
14
+ displayName = 'Web Search';
15
+ description = 'Search the web using multiple providers (Serper, SerpAPI, Brave, SearXNG, DuckDuckGo fallback). Set multiSearch=true to query ALL providers in parallel for higher-confidence, deduplicated results.';
16
+ category = 'research';
17
+ hasSideEffects = false;
18
+ inputSchema = {
19
+ type: 'object',
20
+ required: ['query'],
21
+ properties: {
22
+ query: {
23
+ type: 'string',
24
+ description: 'The search query',
25
+ },
26
+ maxResults: {
27
+ type: 'integer',
28
+ description: 'Maximum number of results to return',
29
+ default: 10,
30
+ minimum: 1,
31
+ maximum: 50,
32
+ },
33
+ provider: {
34
+ type: 'string',
35
+ description: 'Specific search provider to use (ignored when multiSearch is true)',
36
+ enum: ['serper', 'serpapi', 'brave', 'searxng', 'duckduckgo'],
37
+ },
38
+ multiSearch: {
39
+ type: 'boolean',
40
+ description: 'When true, searches ALL available providers in parallel and returns merged, deduplicated results ranked by cross-provider agreement. Useful for deep research or fact verification.',
41
+ default: false,
42
+ },
43
+ category: {
44
+ type: 'string',
45
+ description: 'Search category (SearXNG only). Options: general, news, images, videos, it, science, files, social_media',
46
+ enum: ['general', 'news', 'images', 'videos', 'it', 'science', 'files', 'social_media'],
47
+ },
48
+ },
49
+ additionalProperties: false,
50
+ };
51
+ requiredCapabilities = ['capability:web_search'];
52
+ constructor(searchService, defaultMultiSearch = false) {
30
53
  this.searchService = searchService;
54
+ this.defaultMultiSearch = defaultMultiSearch;
31
55
  }
32
- /**
33
- * Executes a web search query
34
- *
35
- * @param {Object} input - The search parameters
36
- * @param {string} input.query - The search query string
37
- * @param {number} [input.maxResults=10] - Maximum number of results to return
38
- * @param {string} [input.provider] - Specific provider to use (serper, serpapi, brave, duckduckgo)
39
- * @returns {Promise<{success: boolean, output?: any, error?: string}>} The search results
40
- *
41
- * @throws {Error} Throws if all providers fail
42
- */
43
- async execute(input) {
56
+ async execute(input, _context) {
44
57
  try {
58
+ const useMultiSearch = input.multiSearch ?? this.defaultMultiSearch;
59
+ if (useMultiSearch && !input.provider) {
60
+ const results = await this.searchService.multiSearch(input.query, {
61
+ maxResults: input.maxResults || 10,
62
+ });
63
+ return { success: true, output: results };
64
+ }
45
65
  const results = await this.searchService.search(input.query, {
46
66
  maxResults: input.maxResults || 10,
47
- provider: input.provider
67
+ provider: input.provider,
68
+ category: input.category,
48
69
  });
49
- return {
50
- success: true,
51
- output: results
52
- };
70
+ return { success: true, output: results };
53
71
  }
54
72
  catch (error) {
55
- return {
56
- success: false,
57
- error: error.message
58
- };
73
+ return { success: false, error: error?.message || String(error) };
59
74
  }
60
75
  }
61
- /**
62
- * Validates input parameters for the web search
63
- *
64
- * @param {any} input - The input to validate
65
- * @returns {{valid: boolean, errors: string[]}} Validation result
66
- */
67
- validate(input) {
76
+ validateArgs(input) {
68
77
  const errors = [];
69
78
  if (!input.query) {
70
79
  errors.push('Query is required');
@@ -78,45 +87,18 @@ class WebSearchTool {
78
87
  }
79
88
  }
80
89
  if (input.provider !== undefined) {
81
- const validProviders = ['serper', 'serpapi', 'brave', 'duckduckgo'];
90
+ const validProviders = ['serper', 'serpapi', 'brave', 'searxng', 'duckduckgo'];
82
91
  if (!validProviders.includes(input.provider)) {
83
92
  errors.push('Invalid provider');
84
93
  }
85
94
  }
86
- return {
87
- valid: errors.length === 0,
88
- errors
89
- };
90
- }
91
- /**
92
- * Returns the JSON schema for the tool's input
93
- *
94
- * @returns {Object} JSON Schema object
95
- */
96
- getSchema() {
97
- return {
98
- type: 'object',
99
- required: ['query'],
100
- properties: {
101
- query: {
102
- type: 'string',
103
- description: 'The search query'
104
- },
105
- maxResults: {
106
- type: 'number',
107
- description: 'Maximum number of results to return',
108
- default: 10,
109
- minimum: 1,
110
- maximum: 50
111
- },
112
- provider: {
113
- type: 'string',
114
- description: 'Specific search provider to use',
115
- enum: ['serper', 'serpapi', 'brave', 'duckduckgo']
116
- }
117
- }
118
- };
95
+ if (input.multiSearch !== undefined && typeof input.multiSearch !== 'boolean') {
96
+ errors.push('multiSearch must be a boolean');
97
+ }
98
+ if (input.multiSearch && input.provider) {
99
+ errors.push('Cannot specify both multiSearch and a specific provider');
100
+ }
101
+ return errors.length === 0 ? { isValid: true } : { isValid: false, errors };
119
102
  }
120
103
  }
121
- exports.WebSearchTool = WebSearchTool;
122
104
  //# sourceMappingURL=webSearch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"webSearch.js","sourceRoot":"","sources":["../../src/tools/webSearch.ts"],"names":[],"mappings":";;;AAGA;;;;;;;;;;;;;;;GAeG;AACH,MAAa,aAAa;IASJ;IARJ,EAAE,GAAG,WAAW,CAAC;IACjB,IAAI,GAAG,YAAY,CAAC;IACpB,WAAW,GAAG,yCAAyC,CAAC;IAExE;;;OAGG;IACH,YAAoB,aAAoC;QAApC,kBAAa,GAAb,aAAa,CAAuB;IAAG,CAAC;IAE5D;;;;;;;;;;OAUG;IACH,KAAK,CAAC,OAAO,CAAC,KAIb;QACC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE;gBAC3D,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,EAAE;gBAClC,QAAQ,EAAE,KAAK,CAAC,QAAQ;aACzB,CAAC,CAAC;YAEH,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,OAAO;aAChB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,KAAK,CAAC,OAAO;aACrB,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,QAAQ,CAAC,KAAU;QACjB,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACjB,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC3C,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACxC,CAAC;QAED,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACnC,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,EAAE,CAAC;gBAClE,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QAED,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;YACpE,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7C,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QAED,OAAO;YACL,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;YAC1B,MAAM;SACP,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,SAAS;QACP,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,OAAO,CAAC;YACnB,UAAU,EAAE;gBACV,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,kBAAkB;iBAChC;gBACD,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,qCAAqC;oBAClD,OAAO,EAAE,EAAE;oBACX,OAAO,EAAE,CAAC;oBACV,OAAO,EAAE,EAAE;iBACZ;gBACD,QAAQ,EAAE;oBACR,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,iCAAiC;oBAC9C,IAAI,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,CAAC;iBACnD;aACF;SACF,CAAC;IACJ,CAAC;CACF;AA5GD,sCA4GC"}
1
+ {"version":3,"file":"webSearch.js","sourceRoot":"","sources":["../../src/tools/webSearch.ts"],"names":[],"mappings":"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"}
package/dist/types.js CHANGED
@@ -1,6 +1,5 @@
1
- "use strict";
2
1
  /**
3
2
  * @file Type definitions for search extension
4
3
  */
5
- Object.defineProperty(exports, "__esModule", { value: true });
4
+ export {};
6
5
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/manifest.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://agentos.sh/schemas/extension-manifest-v1.json",
3
3
  "id": "com.framers.research.web-search",
4
4
  "name": "Web Search Extension",
5
- "version": "1.0.0",
5
+ "version": "1.1.0",
6
6
  "description": "Professional web search, research aggregation, and fact-checking capabilities for AgentOS",
7
7
  "author": {
8
8
  "name": "Frame.dev",
@@ -10,7 +10,7 @@
10
10
  "url": "https://github.com/framersai"
11
11
  },
12
12
  "license": "MIT",
13
- "keywords": ["search", "web", "research", "fact-check", "serper", "serpapi", "brave"],
13
+ "keywords": ["search", "web", "research", "fact-check", "serper", "serpapi", "brave", "searxng"],
14
14
  "agentosVersion": "^2.0.0",
15
15
  "categories": ["productivity", "research"],
16
16
  "repository": {
@@ -20,21 +20,21 @@
20
20
  "extensions": [
21
21
  {
22
22
  "kind": "tool",
23
- "id": "webSearch",
23
+ "id": "web_search",
24
24
  "displayName": "Web Search",
25
25
  "description": "Search the web for information",
26
26
  "entry": "./dist/tools/webSearch.js"
27
27
  },
28
28
  {
29
29
  "kind": "tool",
30
- "id": "researchAggregator",
30
+ "id": "research_aggregate",
31
31
  "displayName": "Research Aggregator",
32
32
  "description": "Aggregate research from multiple searches",
33
33
  "entry": "./dist/tools/researchAggregator.js"
34
34
  },
35
35
  {
36
36
  "kind": "tool",
37
- "id": "factCheck",
37
+ "id": "fact_check",
38
38
  "displayName": "Fact Checker",
39
39
  "description": "Verify facts across multiple sources",
40
40
  "entry": "./dist/tools/factCheck.js"
@@ -44,7 +44,7 @@
44
44
  "properties": {
45
45
  "search.provider": {
46
46
  "type": "string",
47
- "enum": ["serper", "serpapi", "brave", "duckduckgo"],
47
+ "enum": ["serper", "serpapi", "brave", "searxng", "duckduckgo"],
48
48
  "default": "duckduckgo",
49
49
  "description": "Search API provider to use"
50
50
  },
@@ -59,6 +59,11 @@
59
59
  "minimum": 1,
60
60
  "maximum": 20,
61
61
  "description": "Maximum requests per second"
62
+ },
63
+ "search.multiSearch": {
64
+ "type": "boolean",
65
+ "default": false,
66
+ "description": "Default multi-provider parallel search for all search tools. When enabled, queries fan out to ALL available providers, results are deduplicated and reranked by cross-provider agreement."
62
67
  }
63
68
  }
64
69
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@framers/agentos-ext-web-search",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Web search, research aggregation, and fact-checking tools for AgentOS",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -59,7 +59,7 @@
59
59
  "axios": "^1.7.7"
60
60
  },
61
61
  "devDependencies": {
62
- "@framers/agentos": "^0.1.0",
62
+ "@framers/agentos": "^0.1.29",
63
63
  "@types/node": "^20.12.12",
64
64
  "@typescript-eslint/eslint-plugin": "^7.0.0",
65
65
  "@typescript-eslint/parser": "^7.0.0",
package/src/index.ts CHANGED
@@ -4,15 +4,15 @@
4
4
  * Provides web search capabilities through multiple providers with automatic fallback.
5
5
  *
6
6
  * @module @framers/agentos-ext-web-search
7
- * @version 1.0.0
7
+ * @version 1.1.0
8
8
  * @license MIT
9
9
  */
10
10
 
11
- import { ExtensionContext, ExtensionPack } from '@framers/agentos';
12
- import { WebSearchTool } from './tools/webSearch';
13
- import { ResearchAggregatorTool } from './tools/researchAggregator';
14
- import { FactCheckTool } from './tools/factCheck';
15
- import { SearchProviderService } from './services/searchProvider';
11
+ import type { ExtensionPackContext, ExtensionPack, ExtensionLifecycleContext } from '@framers/agentos';
12
+ import { WebSearchTool } from './tools/webSearch.js';
13
+ import { ResearchAggregatorTool } from './tools/researchAggregator.js';
14
+ import { FactCheckTool } from './tools/factCheck.js';
15
+ import { SearchProviderService } from './services/searchProvider.js';
16
16
 
17
17
  /**
18
18
  * Extension configuration options
@@ -24,6 +24,8 @@ export interface WebSearchExtensionOptions {
24
24
  serpApiKey?: string;
25
25
  /** Brave Search API key */
26
26
  braveApiKey?: string;
27
+ /** SearXNG instance URL (e.g. http://searxng:8080 or http://localhost:8888) */
28
+ searxngUrl?: string;
27
29
  /** Default maximum results for searches */
28
30
  defaultMaxResults?: number;
29
31
  /** Rate limiting configuration */
@@ -31,6 +33,8 @@ export interface WebSearchExtensionOptions {
31
33
  maxRequests: number;
32
34
  windowMs: number;
33
35
  };
36
+ /** Default multi-provider parallel search for all search tools */
37
+ defaultMultiSearch?: boolean;
34
38
  /** Extension priority in the stack */
35
39
  priority?: number;
36
40
  }
@@ -38,86 +42,100 @@ export interface WebSearchExtensionOptions {
38
42
  /**
39
43
  * Creates the web search extension pack
40
44
  *
41
- * @param {ExtensionContext} context - The extension context
45
+ * @param {ExtensionPackContext} context - The extension context
42
46
  * @returns {ExtensionPack} The configured extension pack
43
- *
47
+ *
44
48
  * @example
45
49
  * ```typescript
46
50
  * import { createExtensionPack } from '@framers/agentos-ext-web-search';
47
- *
51
+ *
48
52
  * const pack = createExtensionPack({
49
53
  * options: {
50
54
  * serperApiKey: process.env.SERPER_API_KEY,
51
55
  * defaultMaxResults: 10
52
- * },
53
- * logger: console
56
+ * }
54
57
  * });
55
58
  * ```
56
59
  */
57
- export function createExtensionPack(context: ExtensionContext): ExtensionPack {
58
- const options = context.options as WebSearchExtensionOptions || {};
59
-
60
+ export function createExtensionPack(context: ExtensionPackContext): ExtensionPack {
61
+ const options = (context.options ?? {}) as WebSearchExtensionOptions;
62
+
63
+ const serperApiKey =
64
+ options.serperApiKey || process.env.SERPER_API_KEY;
65
+ const serpApiKey =
66
+ options.serpApiKey || process.env.SERPAPI_API_KEY;
67
+ const braveApiKey =
68
+ options.braveApiKey || process.env.BRAVE_API_KEY;
69
+ const searxngUrl =
70
+ options.searxngUrl || process.env.SEARXNG_URL;
71
+
60
72
  // Initialize search service with configuration
61
73
  const searchService = new SearchProviderService({
62
- serperApiKey: options.serperApiKey,
63
- serpApiKey: options.serpApiKey,
64
- braveApiKey: options.braveApiKey,
74
+ serperApiKey,
75
+ serpApiKey,
76
+ braveApiKey,
77
+ searxngUrl,
65
78
  rateLimit: options.rateLimit
66
79
  });
67
80
 
81
+ const defaultMultiSearch = options.defaultMultiSearch ?? false;
82
+
68
83
  // Create tool instances
69
- const webSearchTool = new WebSearchTool(searchService);
70
- const researchAggregator = new ResearchAggregatorTool(searchService);
71
- const factCheckTool = new FactCheckTool(searchService);
84
+ const webSearchTool = new WebSearchTool(searchService, defaultMultiSearch);
85
+ const researchAggregator = new ResearchAggregatorTool(searchService, defaultMultiSearch);
86
+ const factCheckTool = new FactCheckTool(searchService, defaultMultiSearch);
72
87
 
73
88
  return {
74
89
  name: '@framers/agentos-ext-web-search',
75
- version: '1.0.0',
90
+ version: '1.1.0',
76
91
  descriptors: [
77
92
  {
78
- id: 'webSearch',
93
+ id: webSearchTool.name,
79
94
  kind: 'tool',
80
95
  priority: options.priority || 50,
81
- payload: webSearchTool
96
+ payload: webSearchTool,
97
+ requiredSecrets: [
98
+ { id: 'serper.apiKey', optional: true },
99
+ { id: 'serpapi.apiKey', optional: true },
100
+ { id: 'brave.apiKey', optional: true },
101
+ ],
82
102
  },
83
103
  {
84
- id: 'researchAggregator',
104
+ id: researchAggregator.name,
85
105
  kind: 'tool',
86
106
  priority: options.priority || 50,
87
- payload: researchAggregator
107
+ payload: researchAggregator,
108
+ requiredSecrets: [
109
+ { id: 'serper.apiKey', optional: true },
110
+ { id: 'serpapi.apiKey', optional: true },
111
+ { id: 'brave.apiKey', optional: true },
112
+ ],
88
113
  },
89
114
  {
90
- id: 'factCheck',
115
+ id: factCheckTool.name,
91
116
  kind: 'tool',
92
117
  priority: options.priority || 50,
93
- payload: factCheckTool
118
+ payload: factCheckTool,
119
+ requiredSecrets: [
120
+ { id: 'serper.apiKey', optional: true },
121
+ { id: 'serpapi.apiKey', optional: true },
122
+ { id: 'brave.apiKey', optional: true },
123
+ ],
94
124
  }
95
125
  ],
96
- /**
97
- * Called when extension is activated
98
- */
99
- onActivate: async () => {
100
- if (context.onActivate) {
101
- await context.onActivate();
102
- }
103
- context.logger?.info('Web Search Extension activated');
126
+ onActivate: async (lc: ExtensionLifecycleContext) => {
127
+ lc.logger?.info('Web Search Extension activated');
104
128
  },
105
- /**
106
- * Called when extension is deactivated
107
- */
108
- onDeactivate: async () => {
109
- if (context.onDeactivate) {
110
- await context.onDeactivate();
111
- }
112
- context.logger?.info('Web Search Extension deactivated');
129
+ onDeactivate: async (lc: ExtensionLifecycleContext) => {
130
+ lc.logger?.info('Web Search Extension deactivated');
113
131
  }
114
132
  };
115
133
  }
116
134
 
117
135
  // Export types for consumers
118
136
  export { WebSearchTool, ResearchAggregatorTool, FactCheckTool };
119
- export { SearchProviderService, SearchResult, ProviderResponse } from './services/searchProvider';
120
- export type { SearchProviderConfig } from './services/searchProvider';
137
+ export { SearchProviderService, SearchResult, ProviderResponse } from './services/searchProvider.js';
138
+ export type { SearchProviderConfig, MultiSearchResult, MultiSearchResponse } from './services/searchProvider.js';
121
139
 
122
140
  // Default export for convenience
123
- export default createExtensionPack;
141
+ export default createExtensionPack;