@memoryblock/plugin-web-search 0.1.0-beta

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.
package/LICENSE ADDED
File without changes
package/README.md ADDED
File without changes
package/dist/base.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Search provider contract.
3
+ * All search providers (Brave, Google, etc.) must implement this.
4
+ */
5
+ export interface SearchResult {
6
+ title: string;
7
+ url: string;
8
+ snippet: string;
9
+ }
10
+ export interface SearchOptions {
11
+ count?: number;
12
+ language?: string;
13
+ }
14
+ export interface SearchProvider {
15
+ readonly name: string;
16
+ search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
17
+ }
18
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CAC3E"}
package/dist/base.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ import type { SearchProvider, SearchResult, SearchOptions } from '../base.js';
2
+ /**
3
+ * Brave Search API provider.
4
+ * Uses native fetch() (Node 18+ built-in).
5
+ */
6
+ export declare class BraveSearchProvider implements SearchProvider {
7
+ readonly name = "brave";
8
+ search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
9
+ }
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/brave/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAU9E;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,cAAc;IACtD,QAAQ,CAAC,IAAI,WAAW;IAElB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAsChF"}
@@ -0,0 +1,40 @@
1
+ import { loadAuth } from 'memoryblock';
2
+ const BRAVE_API_URL = 'https://api.search.brave.com/res/v1/web/search';
3
+ /**
4
+ * Brave Search API provider.
5
+ * Uses native fetch() (Node 18+ built-in).
6
+ */
7
+ export class BraveSearchProvider {
8
+ name = 'brave';
9
+ async search(query, options) {
10
+ const auth = await loadAuth();
11
+ const apiKey = auth.brave?.apiKey;
12
+ if (!apiKey) {
13
+ throw new Error('Brave API key not configured. Add it to ~/.memoryblock/auth.json:\n' +
14
+ ' { "brave": { "apiKey": "..." } }');
15
+ }
16
+ const count = options?.count || 5;
17
+ const params = new URLSearchParams({
18
+ q: query,
19
+ count: String(count),
20
+ });
21
+ const response = await fetch(`${BRAVE_API_URL}?${params}`, {
22
+ headers: {
23
+ 'Accept': 'application/json',
24
+ 'Accept-Encoding': 'gzip',
25
+ 'X-Subscription-Token': apiKey,
26
+ },
27
+ });
28
+ if (!response.ok) {
29
+ throw new Error(`Brave Search API error: ${response.status} ${response.statusText}`);
30
+ }
31
+ const data = await response.json();
32
+ const results = data.web?.results || [];
33
+ return results.map((r) => ({
34
+ title: r.title || '',
35
+ url: r.url || '',
36
+ snippet: r.description || '',
37
+ }));
38
+ }
39
+ }
40
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/brave/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,MAAM,aAAa,GAAG,gDAAgD,CAAC;AAQvE;;;GAGG;AACH,MAAM,OAAO,mBAAmB;IACnB,IAAI,GAAG,OAAO,CAAC;IAExB,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,OAAuB;QAC/C,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC;QAElC,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CACX,qEAAqE;gBACrE,oCAAoC,CACvC,CAAC;QACN,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YAC/B,CAAC,EAAE,KAAK;YACR,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;SACvB,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,aAAa,IAAI,MAAM,EAAE,EAAE;YACvD,OAAO,EAAE;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,iBAAiB,EAAE,MAAM;gBACzB,sBAAsB,EAAE,MAAM;aACjC;SACJ,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,2BAA2B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACzF,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA8C,CAAC;QAC/E,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,OAAO,IAAI,EAAE,CAAC;QAExC,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAiB,EAAE,EAAE,CAAC,CAAC;YACvC,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE;YACpB,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE;YAChB,OAAO,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE;SAC/B,CAAC,CAAC,CAAC;IACR,CAAC;CACJ"}
@@ -0,0 +1,14 @@
1
+ import type { ToolExecutionResult, ToolContext, ToolDefinition } from 'memoryblock';
2
+ export type { SearchProvider, SearchResult, SearchOptions } from './base.js';
3
+ export { BraveSearchProvider } from './brave/index.js';
4
+ /** Web search tool — usable by the tool registry. */
5
+ export declare const webSearchTool: {
6
+ definition: ToolDefinition;
7
+ execute(params: Record<string, unknown>, _context: ToolContext): Promise<ToolExecutionResult>;
8
+ };
9
+ /** Export as array for registry plugin loading. */
10
+ export declare const tools: {
11
+ definition: ToolDefinition;
12
+ execute(params: Record<string, unknown>, _context: ToolContext): Promise<ToolExecutionResult>;
13
+ }[];
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGpF,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAsBvD,qDAAqD;AACrD,eAAO,MAAM,aAAa;;oBAEA,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,WAAW,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAoBtG,CAAC;AAEF,mDAAmD;AACnD,eAAO,MAAM,KAAK;;oBAvBQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,WAAW,GAAG,OAAO,CAAC,mBAAmB,CAAC;GAuBnE,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,45 @@
1
+ import { BraveSearchProvider } from './brave/index.js';
2
+ export { BraveSearchProvider } from './brave/index.js';
3
+ const braveProvider = new BraveSearchProvider();
4
+ /**
5
+ * Web search tool definition — registers as a tool in the registry.
6
+ */
7
+ const webSearchToolDefinition = {
8
+ name: 'web_search',
9
+ description: 'Search the web for current information. Returns titles, URLs, and snippets.',
10
+ parameters: {
11
+ type: 'object',
12
+ properties: {
13
+ query: { type: 'string', description: 'The search query.' },
14
+ count: { type: 'number', description: 'Number of results (default: 5, max: 10).' },
15
+ },
16
+ required: ['query'],
17
+ additionalProperties: false,
18
+ },
19
+ requiresApproval: false,
20
+ };
21
+ /** Web search tool — usable by the tool registry. */
22
+ export const webSearchTool = {
23
+ definition: webSearchToolDefinition,
24
+ async execute(params, _context) {
25
+ try {
26
+ const query = params.query;
27
+ const count = Math.min(params.count || 5, 10);
28
+ const results = await braveProvider.search(query, { count });
29
+ if (results.length === 0) {
30
+ return { content: 'No results found.', isError: false };
31
+ }
32
+ const formatted = results
33
+ .map((r, i) => `${i + 1}. **${r.title}**\n ${r.url}\n ${r.snippet}`)
34
+ .join('\n\n');
35
+ return { content: formatted, isError: false };
36
+ }
37
+ catch (err) {
38
+ const message = err instanceof Error ? err.message : String(err);
39
+ return { content: `Web search failed: ${message}`, isError: true };
40
+ }
41
+ },
42
+ };
43
+ /** Export as array for registry plugin loading. */
44
+ export const tools = [webSearchTool];
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,aAAa,GAAG,IAAI,mBAAmB,EAAE,CAAC;AAEhD;;GAEG;AACH,MAAM,uBAAuB,GAAmB;IAC5C,IAAI,EAAE,YAAY;IAClB,WAAW,EAAE,6EAA6E;IAC1F,UAAU,EAAE;QACR,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACR,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mBAAmB,EAAE;YAC3D,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0CAA0C,EAAE;SACrF;QACD,QAAQ,EAAE,CAAC,OAAO,CAAC;QACnB,oBAAoB,EAAE,KAAK;KAC9B;IACD,gBAAgB,EAAE,KAAK;CAC1B,CAAC;AAEF,qDAAqD;AACrD,MAAM,CAAC,MAAM,aAAa,GAAG;IACzB,UAAU,EAAE,uBAAuB;IACnC,KAAK,CAAC,OAAO,CAAC,MAA+B,EAAE,QAAqB;QAChE,IAAI,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAe,CAAC;YACrC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAE,MAAM,CAAC,KAAgB,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YAC1D,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YAE7D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YAC5D,CAAC;YAED,MAAM,SAAS,GAAG,OAAO;iBACpB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;iBACvE,IAAI,CAAC,MAAM,CAAC,CAAC;YAElB,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAClD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,EAAE,OAAO,EAAE,sBAAsB,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACvE,CAAC;IACL,CAAC;CACJ,CAAC;AAEF,mDAAmD;AACnD,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,aAAa,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "@memoryblock/plugin-web-search",
3
+ "version": "0.1.0-beta",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "import": "./dist/index.js"
9
+ }
10
+ },
11
+ "dependencies": {
12
+ "memoryblock": "0.1.0-beta"
13
+ },
14
+ "scripts": {
15
+ "build": "tsc -p tsconfig.json"
16
+ }
17
+ }
package/src/base.ts ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Search provider contract.
3
+ * All search providers (Brave, Google, etc.) must implement this.
4
+ */
5
+ export interface SearchResult {
6
+ title: string;
7
+ url: string;
8
+ snippet: string;
9
+ }
10
+
11
+ export interface SearchOptions {
12
+ count?: number;
13
+ language?: string;
14
+ }
15
+
16
+ export interface SearchProvider {
17
+ readonly name: string;
18
+ search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
19
+ }
@@ -0,0 +1,57 @@
1
+ import { loadAuth } from 'memoryblock';
2
+ import type { SearchProvider, SearchResult, SearchOptions } from '../base.js';
3
+
4
+ const BRAVE_API_URL = 'https://api.search.brave.com/res/v1/web/search';
5
+
6
+ interface BraveWebResult {
7
+ title?: string;
8
+ url?: string;
9
+ description?: string;
10
+ }
11
+
12
+ /**
13
+ * Brave Search API provider.
14
+ * Uses native fetch() (Node 18+ built-in).
15
+ */
16
+ export class BraveSearchProvider implements SearchProvider {
17
+ readonly name = 'brave';
18
+
19
+ async search(query: string, options?: SearchOptions): Promise<SearchResult[]> {
20
+ const auth = await loadAuth();
21
+ const apiKey = auth.brave?.apiKey;
22
+
23
+ if (!apiKey) {
24
+ throw new Error(
25
+ 'Brave API key not configured. Add it to ~/.memoryblock/auth.json:\n' +
26
+ ' { "brave": { "apiKey": "..." } }',
27
+ );
28
+ }
29
+
30
+ const count = options?.count || 5;
31
+ const params = new URLSearchParams({
32
+ q: query,
33
+ count: String(count),
34
+ });
35
+
36
+ const response = await fetch(`${BRAVE_API_URL}?${params}`, {
37
+ headers: {
38
+ 'Accept': 'application/json',
39
+ 'Accept-Encoding': 'gzip',
40
+ 'X-Subscription-Token': apiKey,
41
+ },
42
+ });
43
+
44
+ if (!response.ok) {
45
+ throw new Error(`Brave Search API error: ${response.status} ${response.statusText}`);
46
+ }
47
+
48
+ const data = await response.json() as { web?: { results?: BraveWebResult[] } };
49
+ const results = data.web?.results || [];
50
+
51
+ return results.map((r: BraveWebResult) => ({
52
+ title: r.title || '',
53
+ url: r.url || '',
54
+ snippet: r.description || '',
55
+ }));
56
+ }
57
+ }
package/src/index.ts ADDED
@@ -0,0 +1,53 @@
1
+ import type { ToolExecutionResult, ToolContext, ToolDefinition } from 'memoryblock';
2
+ import { BraveSearchProvider } from './brave/index.js';
3
+
4
+ export type { SearchProvider, SearchResult, SearchOptions } from './base.js';
5
+ export { BraveSearchProvider } from './brave/index.js';
6
+
7
+ const braveProvider = new BraveSearchProvider();
8
+
9
+ /**
10
+ * Web search tool definition — registers as a tool in the registry.
11
+ */
12
+ const webSearchToolDefinition: ToolDefinition = {
13
+ name: 'web_search',
14
+ description: 'Search the web for current information. Returns titles, URLs, and snippets.',
15
+ parameters: {
16
+ type: 'object',
17
+ properties: {
18
+ query: { type: 'string', description: 'The search query.' },
19
+ count: { type: 'number', description: 'Number of results (default: 5, max: 10).' },
20
+ },
21
+ required: ['query'],
22
+ additionalProperties: false,
23
+ },
24
+ requiresApproval: false,
25
+ };
26
+
27
+ /** Web search tool — usable by the tool registry. */
28
+ export const webSearchTool = {
29
+ definition: webSearchToolDefinition,
30
+ async execute(params: Record<string, unknown>, _context: ToolContext): Promise<ToolExecutionResult> {
31
+ try {
32
+ const query = params.query as string;
33
+ const count = Math.min((params.count as number) || 5, 10);
34
+ const results = await braveProvider.search(query, { count });
35
+
36
+ if (results.length === 0) {
37
+ return { content: 'No results found.', isError: false };
38
+ }
39
+
40
+ const formatted = results
41
+ .map((r, i) => `${i + 1}. **${r.title}**\n ${r.url}\n ${r.snippet}`)
42
+ .join('\n\n');
43
+
44
+ return { content: formatted, isError: false };
45
+ } catch (err) {
46
+ const message = err instanceof Error ? err.message : String(err);
47
+ return { content: `Web search failed: ${message}`, isError: true };
48
+ }
49
+ },
50
+ };
51
+
52
+ /** Export as array for registry plugin loading. */
53
+ export const tools = [webSearchTool];
package/tsconfig.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "rootDir": "src"
6
+ },
7
+ "include": [
8
+ "src"
9
+ ]
10
+ }