@rivetos/tool-web-search 0.4.0-beta.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.
- package/dist/index.d.ts +102 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +418 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @rivetos/tool-web-search
|
|
3
|
+
*
|
|
4
|
+
* Web search + URL fetch tools.
|
|
5
|
+
*
|
|
6
|
+
* Two tools:
|
|
7
|
+
* web_search — search the web (Google CSE → DuckDuckGo fallback)
|
|
8
|
+
* web_fetch — fetch and extract readable content from a URL
|
|
9
|
+
*
|
|
10
|
+
* Features:
|
|
11
|
+
* - Multi-provider search with automatic failover
|
|
12
|
+
* - Retry with exponential backoff on transient errors
|
|
13
|
+
* - In-memory result/content caching
|
|
14
|
+
* - Structured HTML → markdown extraction
|
|
15
|
+
* - PDF detection, GitHub raw content handling
|
|
16
|
+
*/
|
|
17
|
+
import type { Tool } from '@rivetos/types';
|
|
18
|
+
/** A search provider that can return results for a query. */
|
|
19
|
+
export interface SearchProvider {
|
|
20
|
+
name: string;
|
|
21
|
+
search(query: string, count: number): Promise<SearchResult[]>;
|
|
22
|
+
}
|
|
23
|
+
interface SearchResult {
|
|
24
|
+
title: string;
|
|
25
|
+
snippet: string;
|
|
26
|
+
url: string;
|
|
27
|
+
source: string;
|
|
28
|
+
}
|
|
29
|
+
interface CacheEntry<T> {
|
|
30
|
+
data: T;
|
|
31
|
+
expires: number;
|
|
32
|
+
}
|
|
33
|
+
export interface WebSearchConfig {
|
|
34
|
+
/** Google Custom Search API key */
|
|
35
|
+
googleApiKey?: string;
|
|
36
|
+
/** Google Custom Search Engine ID */
|
|
37
|
+
googleCseId?: string;
|
|
38
|
+
/** Max results per search (default: 5) */
|
|
39
|
+
maxResults?: number;
|
|
40
|
+
}
|
|
41
|
+
export interface WebFetchConfig {
|
|
42
|
+
/** Custom user agent string */
|
|
43
|
+
userAgent?: string;
|
|
44
|
+
/** Default max chars (default: 5000) */
|
|
45
|
+
defaultMaxChars?: number;
|
|
46
|
+
}
|
|
47
|
+
export declare class WebSearchTool implements Tool {
|
|
48
|
+
name: string;
|
|
49
|
+
description: string;
|
|
50
|
+
parameters: {
|
|
51
|
+
type: string;
|
|
52
|
+
properties: {
|
|
53
|
+
query: {
|
|
54
|
+
type: string;
|
|
55
|
+
description: string;
|
|
56
|
+
};
|
|
57
|
+
count: {
|
|
58
|
+
type: string;
|
|
59
|
+
description: string;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
required: string[];
|
|
63
|
+
};
|
|
64
|
+
private providers;
|
|
65
|
+
private maxResults;
|
|
66
|
+
private cache;
|
|
67
|
+
constructor(config?: WebSearchConfig);
|
|
68
|
+
execute(args: Record<string, unknown>): Promise<string>;
|
|
69
|
+
/** Expose cache for testing. */
|
|
70
|
+
_getCache(): Map<string, CacheEntry<string>>;
|
|
71
|
+
}
|
|
72
|
+
export declare class WebFetchTool implements Tool {
|
|
73
|
+
name: string;
|
|
74
|
+
description: string;
|
|
75
|
+
parameters: {
|
|
76
|
+
type: string;
|
|
77
|
+
properties: {
|
|
78
|
+
url: {
|
|
79
|
+
type: string;
|
|
80
|
+
description: string;
|
|
81
|
+
};
|
|
82
|
+
max_chars: {
|
|
83
|
+
type: string;
|
|
84
|
+
description: string;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
required: string[];
|
|
88
|
+
};
|
|
89
|
+
private userAgent;
|
|
90
|
+
private defaultMaxChars;
|
|
91
|
+
private cache;
|
|
92
|
+
constructor(config?: WebFetchConfig);
|
|
93
|
+
execute(args: Record<string, unknown>): Promise<string>;
|
|
94
|
+
/** Expose cache for testing. */
|
|
95
|
+
_getCache(): Map<string, CacheEntry<string>>;
|
|
96
|
+
}
|
|
97
|
+
/** Create web search and fetch tools. */
|
|
98
|
+
export declare function createWebTools(config?: WebSearchConfig & WebFetchConfig): Tool[];
|
|
99
|
+
import type { ToolPlugin } from '@rivetos/types';
|
|
100
|
+
export declare function createPlugin(config?: WebSearchConfig & WebFetchConfig): ToolPlugin;
|
|
101
|
+
export {};
|
|
102
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAM1C,6DAA6D;AAC7D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAA;CAC9D;AAED,UAAU,YAAY;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,UAAU,CAAC,CAAC;IACpB,IAAI,EAAE,CAAC,CAAA;IACP,OAAO,EAAE,MAAM,CAAA;CAChB;AAMD,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,wCAAwC;IACxC,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAwKD,qBAAa,aAAc,YAAW,IAAI;IACxC,IAAI,SAAe;IACnB,WAAW,SAE4D;IACvE,UAAU;;;;;;;;;;;;;MAOT;IAED,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,KAAK,CAAwC;gBAEzC,MAAM,CAAC,EAAE,eAAe;IAgB9B,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IA+C7D,gCAAgC;IAChC,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;CAG7C;AAMD,qBAAa,YAAa,YAAW,IAAI;IACvC,IAAI,SAAc;IAClB,WAAW,SAEsC;IACjD,UAAU;;;;;;;;;;;;;MAOT;IAED,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,KAAK,CAAwC;gBAEzC,MAAM,CAAC,EAAE,cAAc;IAM7B,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IA0E7D,gCAAgC;IAChC,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;CAG7C;AA+GD,yCAAyC;AACzC,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,cAAc,GAAG,IAAI,EAAE,CAEhF;AAMD,OAAO,KAAK,EAAE,UAAU,EAAgB,MAAM,gBAAgB,CAAA;AAE9D,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,cAAc,GAAG,UAAU,CAWlF"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @rivetos/tool-web-search
|
|
4
|
+
*
|
|
5
|
+
* Web search + URL fetch tools.
|
|
6
|
+
*
|
|
7
|
+
* Two tools:
|
|
8
|
+
* web_search — search the web (Google CSE → DuckDuckGo fallback)
|
|
9
|
+
* web_fetch — fetch and extract readable content from a URL
|
|
10
|
+
*
|
|
11
|
+
* Features:
|
|
12
|
+
* - Multi-provider search with automatic failover
|
|
13
|
+
* - Retry with exponential backoff on transient errors
|
|
14
|
+
* - In-memory result/content caching
|
|
15
|
+
* - Structured HTML → markdown extraction
|
|
16
|
+
* - PDF detection, GitHub raw content handling
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.WebFetchTool = exports.WebSearchTool = void 0;
|
|
20
|
+
exports.createWebTools = createWebTools;
|
|
21
|
+
exports.createPlugin = createPlugin;
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Shared helpers
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
const SEARCH_CACHE_TTL = 5 * 60 * 1000; // 5 minutes
|
|
26
|
+
const FETCH_CACHE_TTL = 10 * 60 * 1000; // 10 minutes
|
|
27
|
+
function cacheGet(cache, key) {
|
|
28
|
+
const entry = cache.get(key);
|
|
29
|
+
if (!entry)
|
|
30
|
+
return undefined;
|
|
31
|
+
if (Date.now() > entry.expires) {
|
|
32
|
+
cache.delete(key);
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
return entry.data;
|
|
36
|
+
}
|
|
37
|
+
function cacheSet(cache, key, data, ttl) {
|
|
38
|
+
cache.set(key, { data, expires: Date.now() + ttl });
|
|
39
|
+
}
|
|
40
|
+
/** Retry a function with exponential backoff on transient errors. */
|
|
41
|
+
async function withRetry(fn, isTransient, maxRetries = 2) {
|
|
42
|
+
let lastError;
|
|
43
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
44
|
+
try {
|
|
45
|
+
return await fn();
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
lastError = err;
|
|
49
|
+
if (!isTransient(err) || attempt === maxRetries)
|
|
50
|
+
throw err;
|
|
51
|
+
await new Promise((r) => setTimeout(r, 1000 * (attempt + 1)));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
throw lastError;
|
|
55
|
+
}
|
|
56
|
+
function isTransientError(err) {
|
|
57
|
+
if (err instanceof Error) {
|
|
58
|
+
// Network errors
|
|
59
|
+
if (err.message.includes('fetch failed') || err.message.includes('ECONNREFUSED'))
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
function isTransientStatus(status) {
|
|
65
|
+
return status >= 500 || status === 429;
|
|
66
|
+
}
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
// Google CSE Provider
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
function createGoogleProvider(apiKey, cseId) {
|
|
71
|
+
return {
|
|
72
|
+
name: 'Google',
|
|
73
|
+
async search(query, count) {
|
|
74
|
+
const params = new URLSearchParams({
|
|
75
|
+
key: apiKey,
|
|
76
|
+
cx: cseId,
|
|
77
|
+
q: query,
|
|
78
|
+
num: String(count),
|
|
79
|
+
});
|
|
80
|
+
const response = await fetch(`https://www.googleapis.com/customsearch/v1?${params.toString()}`, {
|
|
81
|
+
signal: AbortSignal.timeout(10_000),
|
|
82
|
+
});
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
if (response.status === 403 || response.status === 429 || response.status >= 500) {
|
|
85
|
+
throw Object.assign(new Error(`Google CSE ${response.status}`), {
|
|
86
|
+
status: response.status,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const body = await response.text().catch(() => '');
|
|
90
|
+
throw new Error(`Google CSE failed (${response.status}): ${body.slice(0, 200)}`);
|
|
91
|
+
}
|
|
92
|
+
const data = (await response.json());
|
|
93
|
+
const items = data.items ?? [];
|
|
94
|
+
return items.map((item) => ({
|
|
95
|
+
title: item.title ?? '',
|
|
96
|
+
snippet: item.snippet ?? '',
|
|
97
|
+
url: item.link ?? '',
|
|
98
|
+
source: 'Google',
|
|
99
|
+
}));
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
// DuckDuckGo HTML Provider (fallback)
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
function createDdgProvider() {
|
|
107
|
+
return {
|
|
108
|
+
name: 'DuckDuckGo',
|
|
109
|
+
async search(query, count) {
|
|
110
|
+
const params = new URLSearchParams({ q: query });
|
|
111
|
+
const response = await fetch(`https://html.duckduckgo.com/html/?${params.toString()}`, {
|
|
112
|
+
method: 'POST',
|
|
113
|
+
headers: {
|
|
114
|
+
'User-Agent': 'RivetOS/0.1.0 (web-search)',
|
|
115
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
116
|
+
},
|
|
117
|
+
body: params.toString(),
|
|
118
|
+
signal: AbortSignal.timeout(10_000),
|
|
119
|
+
});
|
|
120
|
+
if (!response.ok) {
|
|
121
|
+
throw Object.assign(new Error(`DuckDuckGo ${response.status}`), { status: response.status });
|
|
122
|
+
}
|
|
123
|
+
const html = await response.text();
|
|
124
|
+
return parseDdgResults(html, count);
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/** Parse DuckDuckGo HTML search results. */
|
|
129
|
+
function parseDdgResults(html, maxResults) {
|
|
130
|
+
const results = [];
|
|
131
|
+
// Match result blocks — each result is in a div with class "result"
|
|
132
|
+
const resultBlocks = html.match(/<div[^>]*class="[^"]*result[^"]*"[^>]*>[\s\S]*?<\/div>\s*<\/div>/gi) ?? [];
|
|
133
|
+
for (const block of resultBlocks) {
|
|
134
|
+
if (results.length >= maxResults)
|
|
135
|
+
break;
|
|
136
|
+
// Extract title and URL from result__a
|
|
137
|
+
const titleMatch = block.match(/<a[^>]*class="result__a"[^>]*href="([^"]*)"[^>]*>([\s\S]*?)<\/a>/i);
|
|
138
|
+
// Extract snippet from result__snippet
|
|
139
|
+
const snippetMatch = block.match(/<a[^>]*class="result__snippet"[^>]*>([\s\S]*?)<\/a>/i) ??
|
|
140
|
+
block.match(/<td[^>]*class="result__snippet"[^>]*>([\s\S]*?)<\/td>/i);
|
|
141
|
+
if (titleMatch) {
|
|
142
|
+
const url = decodeURIComponent(titleMatch[1].replace(/.*uddg=/, '').replace(/&.*/, ''));
|
|
143
|
+
const title = titleMatch[2].replace(/<[^>]+>/g, '').trim();
|
|
144
|
+
const snippet = snippetMatch ? snippetMatch[1].replace(/<[^>]+>/g, '').trim() : '';
|
|
145
|
+
if (url && title && !url.includes('duckduckgo.com')) {
|
|
146
|
+
results.push({ title, snippet, url, source: 'DuckDuckGo' });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return results;
|
|
151
|
+
}
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
// Web Search Tool
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
class WebSearchTool {
|
|
156
|
+
name = 'web_search';
|
|
157
|
+
description = 'Search the web using Google. Returns titles, snippets, and URLs. ' +
|
|
158
|
+
'Use when you need current information, facts, or to find resources.';
|
|
159
|
+
parameters = {
|
|
160
|
+
type: 'object',
|
|
161
|
+
properties: {
|
|
162
|
+
query: { type: 'string', description: 'Search query' },
|
|
163
|
+
count: { type: 'number', description: 'Number of results (default: 5, max: 10)' },
|
|
164
|
+
},
|
|
165
|
+
required: ['query'],
|
|
166
|
+
};
|
|
167
|
+
providers;
|
|
168
|
+
maxResults;
|
|
169
|
+
cache = new Map();
|
|
170
|
+
constructor(config) {
|
|
171
|
+
this.maxResults = config?.maxResults ?? 5;
|
|
172
|
+
this.providers = [];
|
|
173
|
+
const apiKey = config?.googleApiKey ?? process.env.GOOGLE_CSE_API_KEY ?? process.env.GOOGLE_API_KEY ?? '';
|
|
174
|
+
const cseId = config?.googleCseId ?? process.env.GOOGLE_CSE_ID ?? '';
|
|
175
|
+
if (apiKey && cseId) {
|
|
176
|
+
this.providers.push(createGoogleProvider(apiKey, cseId));
|
|
177
|
+
}
|
|
178
|
+
// DuckDuckGo is always available as fallback
|
|
179
|
+
this.providers.push(createDdgProvider());
|
|
180
|
+
}
|
|
181
|
+
async execute(args) {
|
|
182
|
+
const query = args.query ?? ''.trim();
|
|
183
|
+
const count = Math.min(Number(args.count) || this.maxResults, 10);
|
|
184
|
+
if (!query)
|
|
185
|
+
return 'Error: No search query provided';
|
|
186
|
+
// Check cache
|
|
187
|
+
const cacheKey = `${query}::${count}`;
|
|
188
|
+
const cached = cacheGet(this.cache, cacheKey);
|
|
189
|
+
if (cached)
|
|
190
|
+
return cached;
|
|
191
|
+
// Try each provider in order
|
|
192
|
+
const errors = [];
|
|
193
|
+
for (const provider of this.providers) {
|
|
194
|
+
try {
|
|
195
|
+
const results = await withRetry(() => provider.search(query, count), (err) => {
|
|
196
|
+
if (isTransientError(err))
|
|
197
|
+
return true;
|
|
198
|
+
const status = err.status;
|
|
199
|
+
return typeof status === 'number' && isTransientStatus(status);
|
|
200
|
+
});
|
|
201
|
+
if (results.length === 0) {
|
|
202
|
+
errors.push(`${provider.name}: no results`);
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
const output = results
|
|
206
|
+
.map((r, i) => `${i + 1}. **${r.title}**\n ${r.snippet}\n ${r.url}\n [Source: ${r.source}]`)
|
|
207
|
+
.join('\n\n');
|
|
208
|
+
cacheSet(this.cache, cacheKey, output, SEARCH_CACHE_TTL);
|
|
209
|
+
return output;
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
errors.push(`${provider.name}: ${err.message}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return `Search failed. All providers exhausted:\n${errors.map((e) => ` - ${e}`).join('\n')}`;
|
|
216
|
+
}
|
|
217
|
+
/** Expose cache for testing. */
|
|
218
|
+
_getCache() {
|
|
219
|
+
return this.cache;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
exports.WebSearchTool = WebSearchTool;
|
|
223
|
+
// ---------------------------------------------------------------------------
|
|
224
|
+
// Web Fetch Tool
|
|
225
|
+
// ---------------------------------------------------------------------------
|
|
226
|
+
class WebFetchTool {
|
|
227
|
+
name = 'web_fetch';
|
|
228
|
+
description = 'Fetch and extract readable content from a URL. Returns the text/markdown content of a web page. ' +
|
|
229
|
+
'Use when you need to read a specific webpage.';
|
|
230
|
+
parameters = {
|
|
231
|
+
type: 'object',
|
|
232
|
+
properties: {
|
|
233
|
+
url: { type: 'string', description: 'URL to fetch' },
|
|
234
|
+
max_chars: { type: 'number', description: 'Max characters to return (default: 5000)' },
|
|
235
|
+
},
|
|
236
|
+
required: ['url'],
|
|
237
|
+
};
|
|
238
|
+
userAgent;
|
|
239
|
+
defaultMaxChars;
|
|
240
|
+
cache = new Map();
|
|
241
|
+
constructor(config) {
|
|
242
|
+
this.userAgent =
|
|
243
|
+
config?.userAgent ?? process.env.RIVETOS_USER_AGENT ?? 'RivetOS/0.1.0 (web-fetch)';
|
|
244
|
+
this.defaultMaxChars = config?.defaultMaxChars ?? 5000;
|
|
245
|
+
}
|
|
246
|
+
async execute(args) {
|
|
247
|
+
const url = args.url ?? ''.trim();
|
|
248
|
+
const maxChars = Number(args.max_chars) || this.defaultMaxChars;
|
|
249
|
+
if (!url)
|
|
250
|
+
return 'Error: No URL provided';
|
|
251
|
+
// Check cache
|
|
252
|
+
const cacheKey = `${url}::${maxChars}`;
|
|
253
|
+
const cached = cacheGet(this.cache, cacheKey);
|
|
254
|
+
if (cached)
|
|
255
|
+
return cached;
|
|
256
|
+
try {
|
|
257
|
+
const headers = {
|
|
258
|
+
'User-Agent': this.userAgent,
|
|
259
|
+
Accept: 'text/html,application/xhtml+xml,text/plain,application/json',
|
|
260
|
+
};
|
|
261
|
+
// GitHub raw content
|
|
262
|
+
if (url.includes('raw.githubusercontent.com')) {
|
|
263
|
+
headers.Accept = 'text/plain';
|
|
264
|
+
}
|
|
265
|
+
const response = await fetch(url, {
|
|
266
|
+
headers,
|
|
267
|
+
signal: AbortSignal.timeout(15_000),
|
|
268
|
+
redirect: 'follow',
|
|
269
|
+
});
|
|
270
|
+
if (!response.ok) {
|
|
271
|
+
return `Fetch failed (${response.status}): ${response.statusText}`;
|
|
272
|
+
}
|
|
273
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
274
|
+
// PDF detection
|
|
275
|
+
if (contentType.includes('application/pdf')) {
|
|
276
|
+
return 'PDF content detected. PDF text extraction is not yet supported. Download the file and extract text locally using pdftotext or similar tools.';
|
|
277
|
+
}
|
|
278
|
+
const rawText = await response.text();
|
|
279
|
+
let result;
|
|
280
|
+
// JSON — return formatted
|
|
281
|
+
if (contentType.includes('application/json')) {
|
|
282
|
+
try {
|
|
283
|
+
result = JSON.stringify(JSON.parse(rawText), null, 2);
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
result = rawText;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// HTML — structured extraction
|
|
290
|
+
else if (contentType.includes('text/html')) {
|
|
291
|
+
result = extractMarkdown(rawText);
|
|
292
|
+
}
|
|
293
|
+
// Plain text / markdown
|
|
294
|
+
else {
|
|
295
|
+
result = rawText;
|
|
296
|
+
}
|
|
297
|
+
// Truncation
|
|
298
|
+
if (result.length > maxChars) {
|
|
299
|
+
result =
|
|
300
|
+
result.slice(0, maxChars) +
|
|
301
|
+
`\n\n[Truncated at ${maxChars} chars. Use max_chars parameter to see more.]`;
|
|
302
|
+
}
|
|
303
|
+
cacheSet(this.cache, cacheKey, result, FETCH_CACHE_TTL);
|
|
304
|
+
return result;
|
|
305
|
+
}
|
|
306
|
+
catch (err) {
|
|
307
|
+
return `Fetch error: ${err.message}`;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/** Expose cache for testing. */
|
|
311
|
+
_getCache() {
|
|
312
|
+
return this.cache;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
exports.WebFetchTool = WebFetchTool;
|
|
316
|
+
// ---------------------------------------------------------------------------
|
|
317
|
+
// HTML → Markdown extraction
|
|
318
|
+
// ---------------------------------------------------------------------------
|
|
319
|
+
/** Extract readable content from HTML and convert to markdown. */
|
|
320
|
+
function extractMarkdown(html) {
|
|
321
|
+
// Step 1: Remove non-content elements entirely
|
|
322
|
+
let content = html
|
|
323
|
+
.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
|
|
324
|
+
.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
|
|
325
|
+
.replace(/<nav[^>]*>[\s\S]*?<\/nav>/gi, '')
|
|
326
|
+
.replace(/<footer[^>]*>[\s\S]*?<\/footer>/gi, '')
|
|
327
|
+
.replace(/<aside[^>]*>[\s\S]*?<\/aside>/gi, '');
|
|
328
|
+
// Remove header elements but be more careful (they can be nested)
|
|
329
|
+
content = content.replace(/<header[^>]*>[\s\S]*?<\/header>/gi, '');
|
|
330
|
+
// Step 2: Try to find the main content area
|
|
331
|
+
const articleMatch = content.match(/<article[^>]*>([\s\S]*?)<\/article>/i);
|
|
332
|
+
const mainMatch = content.match(/<main[^>]*>([\s\S]*?)<\/main>/i);
|
|
333
|
+
const bodyMatch = content.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
|
|
334
|
+
content = articleMatch?.[1] ?? mainMatch?.[1] ?? bodyMatch?.[1] ?? content;
|
|
335
|
+
// Step 3: Convert HTML elements to markdown
|
|
336
|
+
// Code blocks (pre/code)
|
|
337
|
+
content = content.replace(/<pre[^>]*><code[^>]*>([\s\S]*?)<\/code><\/pre>/gi, '\n```\n$1\n```\n');
|
|
338
|
+
content = content.replace(/<pre[^>]*>([\s\S]*?)<\/pre>/gi, '\n```\n$1\n```\n');
|
|
339
|
+
content = content.replace(/<code[^>]*>([\s\S]*?)<\/code>/gi, '`$1`');
|
|
340
|
+
// Headings
|
|
341
|
+
content = content.replace(/<h1[^>]*>([\s\S]*?)<\/h1>/gi, '\n# $1\n');
|
|
342
|
+
content = content.replace(/<h2[^>]*>([\s\S]*?)<\/h2>/gi, '\n## $1\n');
|
|
343
|
+
content = content.replace(/<h3[^>]*>([\s\S]*?)<\/h3>/gi, '\n### $1\n');
|
|
344
|
+
content = content.replace(/<h4[^>]*>([\s\S]*?)<\/h4>/gi, '\n#### $1\n');
|
|
345
|
+
content = content.replace(/<h5[^>]*>([\s\S]*?)<\/h5>/gi, '\n##### $1\n');
|
|
346
|
+
content = content.replace(/<h6[^>]*>([\s\S]*?)<\/h6>/gi, '\n###### $1\n');
|
|
347
|
+
// Links
|
|
348
|
+
content = content.replace(/<a[^>]*href="([^"]*)"[^>]*>([\s\S]*?)<\/a>/gi, '[$2]($1)');
|
|
349
|
+
// Lists
|
|
350
|
+
content = content.replace(/<li[^>]*>([\s\S]*?)<\/li>/gi, '- $1\n');
|
|
351
|
+
content = content.replace(/<\/?[ou]l[^>]*>/gi, '\n');
|
|
352
|
+
// Paragraphs and line breaks
|
|
353
|
+
content = content.replace(/<p[^>]*>([\s\S]*?)<\/p>/gi, '\n\n$1\n\n');
|
|
354
|
+
content = content.replace(/<br\s*\/?>/gi, '\n');
|
|
355
|
+
content = content.replace(/<hr\s*\/?>/gi, '\n---\n');
|
|
356
|
+
// Bold and italic
|
|
357
|
+
content = content.replace(/<(?:strong|b)[^>]*>([\s\S]*?)<\/(?:strong|b)>/gi, '**$1**');
|
|
358
|
+
content = content.replace(/<(?:em|i)[^>]*>([\s\S]*?)<\/(?:em|i)>/gi, '*$1*');
|
|
359
|
+
// Strip remaining tags
|
|
360
|
+
content = content.replace(/<[^>]+>/g, '');
|
|
361
|
+
// Decode HTML entities
|
|
362
|
+
content = decodeHtmlEntities(content);
|
|
363
|
+
// Clean up whitespace
|
|
364
|
+
content = content
|
|
365
|
+
.replace(/\n{3,}/g, '\n\n') // Max 2 consecutive newlines
|
|
366
|
+
.replace(/[ \t]+/g, ' ') // Collapse horizontal whitespace
|
|
367
|
+
.replace(/^ +/gm, '') // Remove leading spaces per line
|
|
368
|
+
.trim();
|
|
369
|
+
return content;
|
|
370
|
+
}
|
|
371
|
+
/** Decode common HTML entities. */
|
|
372
|
+
function decodeHtmlEntities(text) {
|
|
373
|
+
const entities = {
|
|
374
|
+
'&': '&',
|
|
375
|
+
'<': '<',
|
|
376
|
+
'>': '>',
|
|
377
|
+
'"': '"',
|
|
378
|
+
''': "'",
|
|
379
|
+
''': "'",
|
|
380
|
+
' ': ' ',
|
|
381
|
+
'—': '—',
|
|
382
|
+
'–': '–',
|
|
383
|
+
'…': '…',
|
|
384
|
+
'«': '«',
|
|
385
|
+
'»': '»',
|
|
386
|
+
'©': '©',
|
|
387
|
+
'®': '®',
|
|
388
|
+
'™': '™',
|
|
389
|
+
};
|
|
390
|
+
let result = text;
|
|
391
|
+
for (const [entity, char] of Object.entries(entities)) {
|
|
392
|
+
result = result.replaceAll(entity, char);
|
|
393
|
+
}
|
|
394
|
+
// Numeric entities (decimal and hex)
|
|
395
|
+
result = result.replace(/&#(\d+);/g, (_, code) => String.fromCharCode(Number(code)));
|
|
396
|
+
result = result.replace(/&#x([0-9a-fA-F]+);/g, (_, code) => String.fromCharCode(parseInt(code, 16)));
|
|
397
|
+
return result;
|
|
398
|
+
}
|
|
399
|
+
// ---------------------------------------------------------------------------
|
|
400
|
+
// Factory
|
|
401
|
+
// ---------------------------------------------------------------------------
|
|
402
|
+
/** Create web search and fetch tools. */
|
|
403
|
+
function createWebTools(config) {
|
|
404
|
+
return [new WebSearchTool(config), new WebFetchTool(config)];
|
|
405
|
+
}
|
|
406
|
+
function createPlugin(config) {
|
|
407
|
+
return {
|
|
408
|
+
name: '@rivetos/tool-web-search',
|
|
409
|
+
version: '0.1.0',
|
|
410
|
+
description: 'Web search and URL fetch tools',
|
|
411
|
+
async init(_config) { },
|
|
412
|
+
getTools() {
|
|
413
|
+
return [new WebSearchTool(config), new WebFetchTool(config)];
|
|
414
|
+
},
|
|
415
|
+
async shutdown() { },
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rivetos/tool-web-search",
|
|
3
|
+
"version": "0.4.0-beta.1",
|
|
4
|
+
"description": "Web search tool — Google Custom Search for non-xAI providers",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc -p tsconfig.json",
|
|
10
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
11
|
+
"lint": "eslint src/",
|
|
12
|
+
"test": "vitest",
|
|
13
|
+
"clean": "rm -rf dist",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@rivetos/types": "*"
|
|
18
|
+
},
|
|
19
|
+
"rivetos": {
|
|
20
|
+
"type": "tool",
|
|
21
|
+
"name": "web-search"
|
|
22
|
+
},
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"import": "./dist/index.js",
|
|
27
|
+
"require": "./dist/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"README.md",
|
|
33
|
+
"LICENSE"
|
|
34
|
+
],
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/philbert440/rivetOS.git",
|
|
38
|
+
"directory": "plugins/tools/web-search"
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=22.0.0"
|
|
45
|
+
}
|
|
46
|
+
}
|