@yourgpt/copilot-sdk 2.0.1 → 2.0.2-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/README.md +42 -0
- package/dist/{ThreadManager-JT0sqSSD.d.ts → ThreadManager-Dkp_eLty.d.ts} +1 -1
- package/dist/{ThreadManager-CUq5Ocu2.d.cts → ThreadManager-LfFRhr4e.d.cts} +1 -1
- package/dist/anthropic-6F5GRE3B.js +4 -0
- package/dist/anthropic-6F5GRE3B.js.map +1 -0
- package/dist/anthropic-DGalr_Fw.d.cts +17 -0
- package/dist/anthropic-DkCEDYOt.d.ts +17 -0
- package/dist/anthropic-NMTRABEH.cjs +21 -0
- package/dist/anthropic-NMTRABEH.cjs.map +1 -0
- package/dist/brave-DdnWb7Gb.d.cts +17 -0
- package/dist/brave-DsI9n7Wr.d.ts +17 -0
- package/dist/brave-OYKCOZEM.cjs +21 -0
- package/dist/brave-OYKCOZEM.cjs.map +1 -0
- package/dist/brave-XSASGGH2.js +4 -0
- package/dist/brave-XSASGGH2.js.map +1 -0
- package/dist/chunk-2FAWEBZS.cjs +88 -0
- package/dist/chunk-2FAWEBZS.cjs.map +1 -0
- package/dist/{chunk-CJ7UWN2Y.js → chunk-3YKHVLNP.js} +397 -7
- package/dist/chunk-3YKHVLNP.js.map +1 -0
- package/dist/chunk-4WWWMNUA.js +1142 -0
- package/dist/chunk-4WWWMNUA.js.map +1 -0
- package/dist/chunk-53UGJNHN.js +92 -0
- package/dist/chunk-53UGJNHN.js.map +1 -0
- package/dist/chunk-6BXQFCK3.js +79 -0
- package/dist/chunk-6BXQFCK3.js.map +1 -0
- package/dist/chunk-6T5XXJEP.cjs +80 -0
- package/dist/chunk-6T5XXJEP.cjs.map +1 -0
- package/dist/chunk-7W7QLZNC.js +72 -0
- package/dist/chunk-7W7QLZNC.js.map +1 -0
- package/dist/chunk-ASV6JLYG.cjs +99 -0
- package/dist/chunk-ASV6JLYG.cjs.map +1 -0
- package/dist/chunk-CBAHCI4R.cjs +76 -0
- package/dist/chunk-CBAHCI4R.cjs.map +1 -0
- package/dist/chunk-CEOMTQTP.js +85 -0
- package/dist/chunk-CEOMTQTP.js.map +1 -0
- package/dist/chunk-DABZYCVX.js +84 -0
- package/dist/chunk-DABZYCVX.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +10 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/{chunk-4PRWNAXQ.cjs → chunk-DUPNYVBP.cjs} +27 -89
- package/dist/chunk-DUPNYVBP.cjs.map +1 -0
- package/dist/chunk-DVC63PGD.cjs +1160 -0
- package/dist/chunk-DVC63PGD.cjs.map +1 -0
- package/dist/chunk-G4SF2PNQ.js +33 -0
- package/dist/chunk-G4SF2PNQ.js.map +1 -0
- package/dist/chunk-GANCV72Z.cjs +110 -0
- package/dist/chunk-GANCV72Z.cjs.map +1 -0
- package/dist/chunk-J4OMGO5O.js +66 -0
- package/dist/chunk-J4OMGO5O.js.map +1 -0
- package/dist/chunk-JEQ2X3Z6.cjs +12 -0
- package/dist/chunk-JEQ2X3Z6.cjs.map +1 -0
- package/dist/chunk-JO4BHPAD.cjs +40 -0
- package/dist/chunk-JO4BHPAD.cjs.map +1 -0
- package/dist/chunk-MEBXW75C.cjs +89 -0
- package/dist/chunk-MEBXW75C.cjs.map +1 -0
- package/dist/chunk-MNDGIW47.js +76 -0
- package/dist/chunk-MNDGIW47.js.map +1 -0
- package/dist/chunk-PPFHA6IL.js +83 -0
- package/dist/chunk-PPFHA6IL.js.map +1 -0
- package/dist/{chunk-BLSI67J6.cjs → chunk-RBZXLBGI.cjs} +425 -30
- package/dist/chunk-RBZXLBGI.cjs.map +1 -0
- package/dist/chunk-RQ74USYU.js +128 -0
- package/dist/chunk-RQ74USYU.js.map +1 -0
- package/dist/chunk-TX7CGITI.cjs +82 -0
- package/dist/chunk-TX7CGITI.cjs.map +1 -0
- package/dist/chunk-TXLIY7GF.cjs +132 -0
- package/dist/chunk-TXLIY7GF.cjs.map +1 -0
- package/dist/chunk-VD74IPKB.js +106 -0
- package/dist/chunk-VD74IPKB.js.map +1 -0
- package/dist/chunk-W73FBYIH.cjs +87 -0
- package/dist/chunk-W73FBYIH.cjs.map +1 -0
- package/dist/chunk-W74OTXXX.cjs +73 -0
- package/dist/chunk-W74OTXXX.cjs.map +1 -0
- package/dist/chunk-XGITAEXU.js +93 -0
- package/dist/chunk-XGITAEXU.js.map +1 -0
- package/dist/chunk-XWOHNY3F.cjs +96 -0
- package/dist/chunk-XWOHNY3F.cjs.map +1 -0
- package/dist/{chunk-JM7PB2LP.js → chunk-Z7PHGSJT.js} +10 -66
- package/dist/chunk-Z7PHGSJT.js.map +1 -0
- package/dist/core/index.cjs +156 -84
- package/dist/core/index.d.cts +16 -4
- package/dist/core/index.d.ts +16 -4
- package/dist/core/index.js +13 -1
- package/dist/exa-72KFY5A7.cjs +21 -0
- package/dist/exa-72KFY5A7.cjs.map +1 -0
- package/dist/exa-Dp9U-WTc.d.ts +17 -0
- package/dist/exa-NNVPBC2M.js +4 -0
- package/dist/exa-NNVPBC2M.js.map +1 -0
- package/dist/exa-jJSPhyUW.d.cts +17 -0
- package/dist/google-CHU2yycE.d.cts +17 -0
- package/dist/google-CTEK6SV2.js +4 -0
- package/dist/google-CTEK6SV2.js.map +1 -0
- package/dist/google-Da8IQxaI.d.ts +17 -0
- package/dist/google-IIUXFFVF.cjs +21 -0
- package/dist/google-IIUXFFVF.cjs.map +1 -0
- package/dist/index-DBNh0jhE.d.ts +206 -0
- package/dist/index-DOlhSb79.d.cts +206 -0
- package/dist/mcp/index.cjs +670 -0
- package/dist/mcp/index.cjs.map +1 -0
- package/dist/mcp/index.d.cts +779 -0
- package/dist/mcp/index.d.ts +779 -0
- package/dist/mcp/index.js +574 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/openai-6KTCQ7PZ.cjs +21 -0
- package/dist/openai-6KTCQ7PZ.cjs.map +1 -0
- package/dist/openai-7W2PCNW5.js +4 -0
- package/dist/openai-7W2PCNW5.js.map +1 -0
- package/dist/openai-Cam8hF4f.d.ts +17 -0
- package/dist/openai-HVSCuXgO.d.cts +17 -0
- package/dist/react/index.cjs +75 -42
- package/dist/react/index.d.cts +270 -45
- package/dist/react/index.d.ts +270 -45
- package/dist/react/index.js +15 -2
- package/dist/searxng-AXLVGY7Z.js +4 -0
- package/dist/searxng-AXLVGY7Z.js.map +1 -0
- package/dist/searxng-EJKNY236.cjs +21 -0
- package/dist/searxng-EJKNY236.cjs.map +1 -0
- package/dist/searxng-K0qtY9vp.d.ts +17 -0
- package/dist/searxng-QGOte_Gq.d.cts +17 -0
- package/dist/serper-3JYJHJX6.js +4 -0
- package/dist/serper-3JYJHJX6.js.map +1 -0
- package/dist/serper-63FT4AOL.cjs +21 -0
- package/dist/serper-63FT4AOL.cjs.map +1 -0
- package/dist/serper-7Czya3PW.d.ts +17 -0
- package/dist/serper-JzdaSnS9.d.cts +17 -0
- package/dist/styles.css +38 -0
- package/dist/tavily-AWFP4RM7.cjs +21 -0
- package/dist/tavily-AWFP4RM7.cjs.map +1 -0
- package/dist/tavily-C8cXXojE.d.cts +17 -0
- package/dist/tavily-CIWAAZPH.js +4 -0
- package/dist/tavily-CIWAAZPH.js.map +1 -0
- package/dist/tavily-DdSGVgkE.d.ts +17 -0
- package/dist/themes/catppuccin.css +2 -0
- package/dist/themes/claude.css +2 -0
- package/dist/themes/linear.css +2 -0
- package/dist/themes/modern-minimal.css +2 -0
- package/dist/themes/posthog.css +2 -0
- package/dist/themes/supabase.css +2 -0
- package/dist/themes/twitter.css +2 -0
- package/dist/themes/vercel.css +2 -0
- package/dist/tools/anthropic/index.cjs +61 -0
- package/dist/tools/anthropic/index.cjs.map +1 -0
- package/dist/tools/anthropic/index.d.cts +67 -0
- package/dist/tools/anthropic/index.d.ts +67 -0
- package/dist/tools/anthropic/index.js +56 -0
- package/dist/tools/anthropic/index.js.map +1 -0
- package/dist/tools/brave/index.cjs +85 -0
- package/dist/tools/brave/index.cjs.map +1 -0
- package/dist/tools/brave/index.d.cts +91 -0
- package/dist/tools/brave/index.d.ts +91 -0
- package/dist/tools/brave/index.js +80 -0
- package/dist/tools/brave/index.js.map +1 -0
- package/dist/tools/exa/index.cjs +90 -0
- package/dist/tools/exa/index.cjs.map +1 -0
- package/dist/tools/exa/index.d.cts +92 -0
- package/dist/tools/exa/index.d.ts +92 -0
- package/dist/tools/exa/index.js +85 -0
- package/dist/tools/exa/index.js.map +1 -0
- package/dist/tools/google/index.cjs +81 -0
- package/dist/tools/google/index.cjs.map +1 -0
- package/dist/tools/google/index.d.cts +81 -0
- package/dist/tools/google/index.d.ts +81 -0
- package/dist/tools/google/index.js +76 -0
- package/dist/tools/google/index.js.map +1 -0
- package/dist/tools/openai/index.cjs +83 -0
- package/dist/tools/openai/index.cjs.map +1 -0
- package/dist/tools/openai/index.d.cts +84 -0
- package/dist/tools/openai/index.d.ts +84 -0
- package/dist/tools/openai/index.js +78 -0
- package/dist/tools/openai/index.js.map +1 -0
- package/dist/tools/searxng/index.cjs +85 -0
- package/dist/tools/searxng/index.cjs.map +1 -0
- package/dist/tools/searxng/index.d.cts +91 -0
- package/dist/tools/searxng/index.d.ts +91 -0
- package/dist/tools/searxng/index.js +80 -0
- package/dist/tools/searxng/index.js.map +1 -0
- package/dist/tools/serper/index.cjs +85 -0
- package/dist/tools/serper/index.cjs.map +1 -0
- package/dist/tools/serper/index.d.cts +91 -0
- package/dist/tools/serper/index.d.ts +91 -0
- package/dist/tools/serper/index.js +80 -0
- package/dist/tools/serper/index.js.map +1 -0
- package/dist/tools/tavily/index.cjs +91 -0
- package/dist/tools/tavily/index.cjs.map +1 -0
- package/dist/tools/tavily/index.d.cts +95 -0
- package/dist/tools/tavily/index.d.ts +95 -0
- package/dist/tools/tavily/index.js +86 -0
- package/dist/tools/tavily/index.js.map +1 -0
- package/dist/tools/web-search/index.cjs +31 -0
- package/dist/tools/web-search/index.cjs.map +1 -0
- package/dist/tools/web-search/index.d.cts +3 -0
- package/dist/tools/web-search/index.d.ts +3 -0
- package/dist/tools/web-search/index.js +14 -0
- package/dist/tools/web-search/index.js.map +1 -0
- package/dist/{types-BtAaOV07.d.cts → tools-EiPWA9Ay.d.cts} +34 -367
- package/dist/{types-BtAaOV07.d.ts → tools-EiPWA9Ay.d.ts} +34 -367
- package/dist/types-B20VCJXL.d.cts +347 -0
- package/dist/types-B20VCJXL.d.ts +347 -0
- package/dist/types-CKA6U74u.d.cts +441 -0
- package/dist/types-DG2ya08y.d.cts +367 -0
- package/dist/types-DG2ya08y.d.ts +367 -0
- package/dist/types-ZguuKEs_.d.cts +127 -0
- package/dist/types-ZguuKEs_.d.ts +127 -0
- package/dist/types-iBkPICvQ.d.ts +441 -0
- package/dist/ui/index.cjs +1069 -146
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.d.cts +410 -4
- package/dist/ui/index.d.ts +410 -4
- package/dist/ui/index.js +1001 -94
- package/dist/ui/index.js.map +1 -1
- package/package.json +52 -2
- package/dist/chunk-4PRWNAXQ.cjs.map +0 -1
- package/dist/chunk-BLSI67J6.cjs.map +0 -1
- package/dist/chunk-CJ7UWN2Y.js.map +0 -1
- package/dist/chunk-JM7PB2LP.js.map +0 -1
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/core/tools/webSearch/index.ts
|
|
4
|
+
var providerLoaders = {
|
|
5
|
+
openai: () => import('./openai-6KTCQ7PZ.cjs').then((m) => m.openaiProvider),
|
|
6
|
+
google: () => import('./google-IIUXFFVF.cjs').then((m) => m.googleProvider),
|
|
7
|
+
anthropic: () => import('./anthropic-NMTRABEH.cjs').then((m) => m.anthropicProvider),
|
|
8
|
+
tavily: () => import('./tavily-AWFP4RM7.cjs').then((m) => m.tavilyProvider),
|
|
9
|
+
serper: () => import('./serper-63FT4AOL.cjs').then((m) => m.serperProvider),
|
|
10
|
+
brave: () => import('./brave-OYKCOZEM.cjs').then((m) => m.braveProvider),
|
|
11
|
+
searxng: () => import('./searxng-EJKNY236.cjs').then((m) => m.searxngProvider),
|
|
12
|
+
exa: () => import('./exa-72KFY5A7.cjs').then((m) => m.exaProvider)
|
|
13
|
+
};
|
|
14
|
+
var loadedProviders = /* @__PURE__ */ new Map();
|
|
15
|
+
async function getProvider(name) {
|
|
16
|
+
const cached = loadedProviders.get(name);
|
|
17
|
+
if (cached) {
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
20
|
+
const loader = providerLoaders[name];
|
|
21
|
+
if (!loader) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
`Unknown search provider: ${name}. Available providers: ${Object.keys(providerLoaders).join(", ")}`
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
const provider = await loader();
|
|
27
|
+
const resolvedProvider = "default" in provider ? provider.default : provider;
|
|
28
|
+
loadedProviders.set(name, resolvedProvider);
|
|
29
|
+
return resolvedProvider;
|
|
30
|
+
}
|
|
31
|
+
function getAvailableProviders() {
|
|
32
|
+
return Object.keys(providerLoaders);
|
|
33
|
+
}
|
|
34
|
+
function isProviderInterface(provider) {
|
|
35
|
+
return typeof provider === "object" && "search" in provider;
|
|
36
|
+
}
|
|
37
|
+
async function executeWebSearch(params, config) {
|
|
38
|
+
const provider = isProviderInterface(config.provider) ? config.provider : await getProvider(config.provider);
|
|
39
|
+
const providerName = isProviderInterface(config.provider) ? "custom" : config.provider;
|
|
40
|
+
const resolvedConfig = {
|
|
41
|
+
...config,
|
|
42
|
+
provider: providerName
|
|
43
|
+
};
|
|
44
|
+
if (provider.validateConfig) {
|
|
45
|
+
provider.validateConfig(resolvedConfig);
|
|
46
|
+
}
|
|
47
|
+
return provider.search(params, resolvedConfig);
|
|
48
|
+
}
|
|
49
|
+
function formatSearchResultsForAI(response, options) {
|
|
50
|
+
const {
|
|
51
|
+
includeUrls = true,
|
|
52
|
+
includeScores = false,
|
|
53
|
+
maxContentLength = 200
|
|
54
|
+
} = options || {};
|
|
55
|
+
const lines = [];
|
|
56
|
+
if (response.answer) {
|
|
57
|
+
lines.push(`Answer: ${response.answer}`);
|
|
58
|
+
lines.push("");
|
|
59
|
+
}
|
|
60
|
+
lines.push(`Search results for "${response.query}":`);
|
|
61
|
+
lines.push("");
|
|
62
|
+
response.results.forEach((result, index) => {
|
|
63
|
+
const num = index + 1;
|
|
64
|
+
let content = result.content;
|
|
65
|
+
if (maxContentLength && content.length > maxContentLength) {
|
|
66
|
+
content = content.slice(0, maxContentLength) + "...";
|
|
67
|
+
}
|
|
68
|
+
lines.push(`${num}. ${result.title}`);
|
|
69
|
+
if (includeUrls) {
|
|
70
|
+
lines.push(` URL: ${result.url}`);
|
|
71
|
+
}
|
|
72
|
+
lines.push(` ${content}`);
|
|
73
|
+
if (includeScores && result.score !== void 0) {
|
|
74
|
+
lines.push(` Relevance: ${(result.score * 100).toFixed(1)}%`);
|
|
75
|
+
}
|
|
76
|
+
lines.push("");
|
|
77
|
+
});
|
|
78
|
+
return lines.join("\n");
|
|
79
|
+
}
|
|
80
|
+
function summarizeSearchResults(response) {
|
|
81
|
+
const count = response.results.length;
|
|
82
|
+
const sources = response.results.slice(0, 3).map((r) => r.domain || new URL(r.url).hostname).join(", ");
|
|
83
|
+
let summary = `Found ${count} result${count !== 1 ? "s" : ""}`;
|
|
84
|
+
if (sources) {
|
|
85
|
+
summary += ` from ${sources}`;
|
|
86
|
+
}
|
|
87
|
+
if (response.searchTime) {
|
|
88
|
+
summary += ` (${response.searchTime}ms)`;
|
|
89
|
+
}
|
|
90
|
+
return summary;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
exports.executeWebSearch = executeWebSearch;
|
|
94
|
+
exports.formatSearchResultsForAI = formatSearchResultsForAI;
|
|
95
|
+
exports.getAvailableProviders = getAvailableProviders;
|
|
96
|
+
exports.getProvider = getProvider;
|
|
97
|
+
exports.summarizeSearchResults = summarizeSearchResults;
|
|
98
|
+
//# sourceMappingURL=chunk-ASV6JLYG.cjs.map
|
|
99
|
+
//# sourceMappingURL=chunk-ASV6JLYG.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/tools/webSearch/index.ts"],"names":[],"mappings":"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","file":"chunk-ASV6JLYG.cjs","sourcesContent":["/**\n * Web Search Module\n *\n * Multi-provider web search with unified API.\n * Supports tree-shaking - only the provider you use gets bundled.\n *\n * @example\n * ```typescript\n * // Option 1: Lazy loading (provider loaded on first use)\n * import { executeWebSearch } from './webSearch';\n * const results = await executeWebSearch(\n * { query: 'latest AI news' },\n * { provider: 'tavily', apiKey: 'your-api-key' }\n * );\n *\n * // Option 2: Direct import (best for tree-shaking)\n * import { tavilyProvider, executeWebSearch } from './webSearch';\n * const results = await executeWebSearch(\n * { query: 'latest AI news' },\n * { provider: tavilyProvider, apiKey: 'your-api-key' }\n * );\n * ```\n */\n\nimport type {\n WebSearchConfig,\n WebSearchParams,\n WebSearchResponse,\n WebSearchProvider,\n WebSearchProviderInterface,\n} from \"./types\";\n\n// ============================================\n// Lazy Provider Loading (for tree-shaking)\n// ============================================\n\n/**\n * Provider loaders - dynamically import providers only when needed.\n * This ensures unused providers are NOT included in the bundle.\n */\nconst providerLoaders: Record<\n WebSearchProvider,\n () => Promise<\n { default: WebSearchProviderInterface } | WebSearchProviderInterface\n >\n> = {\n openai: () => import(\"./providers/openai\").then((m) => m.openaiProvider),\n google: () => import(\"./providers/google\").then((m) => m.googleProvider),\n anthropic: () =>\n import(\"./providers/anthropic\").then((m) => m.anthropicProvider),\n tavily: () => import(\"./providers/tavily\").then((m) => m.tavilyProvider),\n serper: () => import(\"./providers/serper\").then((m) => m.serperProvider),\n brave: () => import(\"./providers/brave\").then((m) => m.braveProvider),\n searxng: () => import(\"./providers/searxng\").then((m) => m.searxngProvider),\n exa: () => import(\"./providers/exa\").then((m) => m.exaProvider),\n};\n\n// Cache for loaded providers\nconst loadedProviders: Map<WebSearchProvider, WebSearchProviderInterface> =\n new Map();\n\n/**\n * Get a provider by name (lazy loading)\n *\n * @param name - Provider name string\n * @returns Provider interface (loaded dynamically)\n */\nexport async function getProvider(\n name: WebSearchProvider,\n): Promise<WebSearchProviderInterface> {\n // Check cache first\n const cached = loadedProviders.get(name);\n if (cached) {\n return cached;\n }\n\n // Load provider dynamically\n const loader = providerLoaders[name];\n if (!loader) {\n throw new Error(\n `Unknown search provider: ${name}. ` +\n `Available providers: ${Object.keys(providerLoaders).join(\", \")}`,\n );\n }\n\n const provider = await loader();\n const resolvedProvider = \"default\" in provider ? provider.default : provider;\n\n // Cache for future use\n loadedProviders.set(name, resolvedProvider as WebSearchProviderInterface);\n\n return resolvedProvider as WebSearchProviderInterface;\n}\n\n/**\n * Get all available provider names\n */\nexport function getAvailableProviders(): WebSearchProvider[] {\n return Object.keys(providerLoaders) as WebSearchProvider[];\n}\n\n// ============================================\n// Extended Config with Direct Provider Support\n// ============================================\n\n/**\n * Extended config that allows passing provider directly for tree-shaking\n */\nexport interface WebSearchConfigExtended extends Omit<\n WebSearchConfig,\n \"provider\"\n> {\n /**\n * Provider can be either:\n * - A string name (lazy loaded): \"tavily\", \"openai\", \"anthropic\", \"google\", etc.\n * - A provider instance (best for tree-shaking): import { tavilyProvider } from '...'\n */\n provider: WebSearchProvider | WebSearchProviderInterface;\n}\n\n/**\n * Check if a value is a provider interface (not a string)\n */\nfunction isProviderInterface(\n provider: WebSearchProvider | WebSearchProviderInterface,\n): provider is WebSearchProviderInterface {\n return typeof provider === \"object\" && \"search\" in provider;\n}\n\n// ============================================\n// Execute Search\n// ============================================\n\n/**\n * Execute a web search using the configured provider\n *\n * @param params - Search parameters (query, maxResults, searchDepth)\n * @param config - Provider configuration (provider, apiKey, options)\n * @returns Search results with optional AI-generated answer\n *\n * @example\n * ```typescript\n * // Option 1: String provider name (lazy loaded)\n * const results = await executeWebSearch(\n * { query: 'What is the latest news about SpaceX?' },\n * {\n * provider: 'tavily',\n * apiKey: process.env.TAVILY_API_KEY,\n * }\n * );\n *\n * // Option 2: Direct provider import (best for tree-shaking)\n * import { tavilyProvider } from '@yourgpt/copilot-sdk/core';\n * const results = await executeWebSearch(\n * { query: 'What is the latest news about SpaceX?' },\n * {\n * provider: tavilyProvider,\n * apiKey: process.env.TAVILY_API_KEY,\n * }\n * );\n * ```\n */\nexport async function executeWebSearch(\n params: WebSearchParams,\n config: WebSearchConfigExtended,\n): Promise<WebSearchResponse> {\n // Resolve provider (either from string or direct reference)\n const provider = isProviderInterface(config.provider)\n ? config.provider\n : await getProvider(config.provider);\n\n // Build config with string provider name for validation\n const providerName: WebSearchProvider = isProviderInterface(config.provider)\n ? (\"custom\" as WebSearchProvider) // Direct provider\n : config.provider;\n\n const resolvedConfig: WebSearchConfig = {\n ...config,\n provider: providerName,\n };\n\n // Validate configuration if provider supports it\n if (provider.validateConfig) {\n provider.validateConfig(resolvedConfig);\n }\n\n // Execute search\n return provider.search(params, resolvedConfig);\n}\n\n// ============================================\n// Utility Functions\n// ============================================\n\n/**\n * Format search results for display in AI context\n *\n * @param response - Web search response\n * @param options - Formatting options\n * @returns Formatted string for AI consumption\n */\nexport function formatSearchResultsForAI(\n response: WebSearchResponse,\n options?: {\n includeUrls?: boolean;\n includeScores?: boolean;\n maxContentLength?: number;\n },\n): string {\n const {\n includeUrls = true,\n includeScores = false,\n maxContentLength = 200,\n } = options || {};\n\n const lines: string[] = [];\n\n // Add answer if available\n if (response.answer) {\n lines.push(`Answer: ${response.answer}`);\n lines.push(\"\");\n }\n\n // Add results\n lines.push(`Search results for \"${response.query}\":`);\n lines.push(\"\");\n\n response.results.forEach((result, index) => {\n const num = index + 1;\n let content = result.content;\n\n // Truncate content if needed\n if (maxContentLength && content.length > maxContentLength) {\n content = content.slice(0, maxContentLength) + \"...\";\n }\n\n lines.push(`${num}. ${result.title}`);\n if (includeUrls) {\n lines.push(` URL: ${result.url}`);\n }\n lines.push(` ${content}`);\n if (includeScores && result.score !== undefined) {\n lines.push(` Relevance: ${(result.score * 100).toFixed(1)}%`);\n }\n lines.push(\"\");\n });\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Create a minimal search result summary\n *\n * @param response - Web search response\n * @returns Brief summary string\n */\nexport function summarizeSearchResults(response: WebSearchResponse): string {\n const count = response.results.length;\n const sources = response.results\n .slice(0, 3)\n .map((r) => r.domain || new URL(r.url).hostname)\n .join(\", \");\n\n let summary = `Found ${count} result${count !== 1 ? \"s\" : \"\"}`;\n if (sources) {\n summary += ` from ${sources}`;\n }\n if (response.searchTime) {\n summary += ` (${response.searchTime}ms)`;\n }\n\n return summary;\n}\n\n// ============================================\n// Re-exports\n// ============================================\n\n// Export types\nexport * from \"./types\";\n\n// Export individual providers for direct import (tree-shakeable)\n// Users should import these directly for best bundle size:\n// import { tavilyProvider } from '@yourgpt/copilot-sdk/core';\nexport { openaiProvider } from \"./providers/openai\";\nexport { googleProvider } from \"./providers/google\";\nexport { anthropicProvider } from \"./providers/anthropic\";\nexport { tavilyProvider } from \"./providers/tavily\";\nexport { serperProvider } from \"./providers/serper\";\nexport { braveProvider } from \"./providers/brave\";\nexport { searxngProvider } from \"./providers/searxng\";\nexport { exaProvider } from \"./providers/exa\";\n"]}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/core/tools/webSearch/providers/tavily.ts
|
|
4
|
+
var TAVILY_API_URL = "https://api.tavily.com/search";
|
|
5
|
+
function validateTavilyConfig(config) {
|
|
6
|
+
if (!config.apiKey) {
|
|
7
|
+
throw new Error(
|
|
8
|
+
"Tavily API key is required. Get one at https://tavily.com/"
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
async function searchTavily(params, config) {
|
|
13
|
+
validateTavilyConfig(config);
|
|
14
|
+
const startTime = Date.now();
|
|
15
|
+
const requestBody = {
|
|
16
|
+
api_key: config.apiKey,
|
|
17
|
+
query: params.query,
|
|
18
|
+
search_depth: params.searchDepth || config.searchDepth || "basic",
|
|
19
|
+
max_results: params.maxResults ?? config.maxResults ?? 5,
|
|
20
|
+
include_answer: config.includeAnswer ?? true,
|
|
21
|
+
include_images: config.includeImages ?? false,
|
|
22
|
+
include_raw_content: config.includeRawContent ?? false,
|
|
23
|
+
include_domains: config.includeDomains,
|
|
24
|
+
exclude_domains: config.excludeDomains
|
|
25
|
+
};
|
|
26
|
+
const response = await fetch(TAVILY_API_URL, {
|
|
27
|
+
method: "POST",
|
|
28
|
+
headers: {
|
|
29
|
+
"Content-Type": "application/json"
|
|
30
|
+
},
|
|
31
|
+
body: JSON.stringify(requestBody),
|
|
32
|
+
signal: config.timeout ? AbortSignal.timeout(config.timeout) : void 0
|
|
33
|
+
});
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
const errorText = await response.text().catch(() => "Unknown error");
|
|
36
|
+
throw new Error(`Tavily API error (${response.status}): ${errorText}`);
|
|
37
|
+
}
|
|
38
|
+
const data = await response.json();
|
|
39
|
+
const searchTime = Date.now() - startTime;
|
|
40
|
+
return {
|
|
41
|
+
query: params.query,
|
|
42
|
+
answer: data.answer,
|
|
43
|
+
results: data.results.map((result) => ({
|
|
44
|
+
title: result.title,
|
|
45
|
+
url: result.url,
|
|
46
|
+
content: result.content,
|
|
47
|
+
score: result.score,
|
|
48
|
+
publishedDate: result.published_date,
|
|
49
|
+
domain: extractDomain(result.url)
|
|
50
|
+
})),
|
|
51
|
+
images: data.images?.map((img) => ({
|
|
52
|
+
url: img.url,
|
|
53
|
+
description: img.description
|
|
54
|
+
})),
|
|
55
|
+
provider: "tavily",
|
|
56
|
+
totalResults: data.results.length,
|
|
57
|
+
searchTime
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function extractDomain(url) {
|
|
61
|
+
try {
|
|
62
|
+
return new URL(url).hostname;
|
|
63
|
+
} catch {
|
|
64
|
+
return url;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
var tavilyProvider = {
|
|
68
|
+
search: searchTavily,
|
|
69
|
+
validateConfig: validateTavilyConfig
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
exports.searchTavily = searchTavily;
|
|
73
|
+
exports.tavilyProvider = tavilyProvider;
|
|
74
|
+
exports.validateTavilyConfig = validateTavilyConfig;
|
|
75
|
+
//# sourceMappingURL=chunk-CBAHCI4R.cjs.map
|
|
76
|
+
//# sourceMappingURL=chunk-CBAHCI4R.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/tools/webSearch/providers/tavily.ts"],"names":[],"mappings":"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","file":"chunk-CBAHCI4R.cjs","sourcesContent":["/**\n * Tavily Search Provider\n *\n * Tavily is an AI-native search engine optimized for LLMs.\n * It provides high-quality results with optional AI-generated answers.\n *\n * @see https://tavily.com/\n */\n\nimport type {\n WebSearchConfig,\n WebSearchParams,\n WebSearchResponse,\n TavilyApiResponse,\n WebSearchProviderInterface,\n} from \"../types\";\n\nconst TAVILY_API_URL = \"https://api.tavily.com/search\";\n\n/**\n * Validate Tavily configuration\n */\nexport function validateTavilyConfig(config: WebSearchConfig): void {\n if (!config.apiKey) {\n throw new Error(\n \"Tavily API key is required. Get one at https://tavily.com/\",\n );\n }\n}\n\n/**\n * Search using Tavily API\n */\nexport async function searchTavily(\n params: WebSearchParams,\n config: WebSearchConfig,\n): Promise<WebSearchResponse> {\n validateTavilyConfig(config);\n\n const startTime = Date.now();\n\n const requestBody = {\n api_key: config.apiKey,\n query: params.query,\n search_depth: params.searchDepth || config.searchDepth || \"basic\",\n max_results: params.maxResults ?? config.maxResults ?? 5,\n include_answer: config.includeAnswer ?? true,\n include_images: config.includeImages ?? false,\n include_raw_content: config.includeRawContent ?? false,\n include_domains: config.includeDomains,\n exclude_domains: config.excludeDomains,\n };\n\n const response = await fetch(TAVILY_API_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(requestBody),\n signal: config.timeout ? AbortSignal.timeout(config.timeout) : undefined,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n throw new Error(`Tavily API error (${response.status}): ${errorText}`);\n }\n\n const data: TavilyApiResponse = await response.json();\n const searchTime = Date.now() - startTime;\n\n return {\n query: params.query,\n answer: data.answer,\n results: data.results.map((result) => ({\n title: result.title,\n url: result.url,\n content: result.content,\n score: result.score,\n publishedDate: result.published_date,\n domain: extractDomain(result.url),\n })),\n images: data.images?.map((img) => ({\n url: img.url,\n description: img.description,\n })),\n provider: \"tavily\",\n totalResults: data.results.length,\n searchTime,\n };\n}\n\n/**\n * Extract domain from URL\n */\nfunction extractDomain(url: string): string {\n try {\n return new URL(url).hostname;\n } catch {\n return url;\n }\n}\n\n/**\n * Tavily provider implementation\n */\nexport const tavilyProvider: WebSearchProviderInterface = {\n search: searchTavily,\n validateConfig: validateTavilyConfig,\n};\n"]}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// src/core/tools/webSearch/providers/serper.ts
|
|
2
|
+
var SERPER_API_URL = "https://google.serper.dev/search";
|
|
3
|
+
function validateSerperConfig(config) {
|
|
4
|
+
if (!config.apiKey) {
|
|
5
|
+
throw new Error(
|
|
6
|
+
"Serper API key is required. Get one at https://serper.dev/"
|
|
7
|
+
);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
async function searchSerper(params, config) {
|
|
11
|
+
validateSerperConfig(config);
|
|
12
|
+
const startTime = Date.now();
|
|
13
|
+
const requestBody = {
|
|
14
|
+
q: params.query,
|
|
15
|
+
num: params.maxResults ?? config.maxResults ?? 5
|
|
16
|
+
};
|
|
17
|
+
if (config.country) {
|
|
18
|
+
requestBody.gl = config.country;
|
|
19
|
+
}
|
|
20
|
+
if (config.language) {
|
|
21
|
+
requestBody.hl = config.language;
|
|
22
|
+
}
|
|
23
|
+
const response = await fetch(SERPER_API_URL, {
|
|
24
|
+
method: "POST",
|
|
25
|
+
headers: {
|
|
26
|
+
"Content-Type": "application/json",
|
|
27
|
+
"X-API-KEY": config.apiKey
|
|
28
|
+
},
|
|
29
|
+
body: JSON.stringify(requestBody),
|
|
30
|
+
signal: config.timeout ? AbortSignal.timeout(config.timeout) : void 0
|
|
31
|
+
});
|
|
32
|
+
if (!response.ok) {
|
|
33
|
+
const errorText = await response.text().catch(() => "Unknown error");
|
|
34
|
+
throw new Error(`Serper API error (${response.status}): ${errorText}`);
|
|
35
|
+
}
|
|
36
|
+
const data = await response.json();
|
|
37
|
+
const searchTime = Date.now() - startTime;
|
|
38
|
+
let results = data.organic || [];
|
|
39
|
+
if (config.includeDomains?.length) {
|
|
40
|
+
results = results.filter(
|
|
41
|
+
(r) => config.includeDomains.some((domain) => r.link.includes(domain))
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
if (config.excludeDomains?.length) {
|
|
45
|
+
results = results.filter(
|
|
46
|
+
(r) => !config.excludeDomains.some((domain) => r.link.includes(domain))
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
const answer = data.answerBox?.answer || data.answerBox?.snippet;
|
|
50
|
+
return {
|
|
51
|
+
query: params.query,
|
|
52
|
+
answer,
|
|
53
|
+
results: results.map((result) => ({
|
|
54
|
+
title: result.title,
|
|
55
|
+
url: result.link,
|
|
56
|
+
content: result.snippet,
|
|
57
|
+
publishedDate: result.date,
|
|
58
|
+
image: result.imageUrl,
|
|
59
|
+
domain: extractDomain(result.link)
|
|
60
|
+
})),
|
|
61
|
+
images: data.images?.map((img) => ({
|
|
62
|
+
url: img.imageUrl,
|
|
63
|
+
description: img.title,
|
|
64
|
+
sourceUrl: img.link
|
|
65
|
+
})),
|
|
66
|
+
provider: "serper",
|
|
67
|
+
totalResults: results.length,
|
|
68
|
+
searchTime
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function extractDomain(url) {
|
|
72
|
+
try {
|
|
73
|
+
return new URL(url).hostname;
|
|
74
|
+
} catch {
|
|
75
|
+
return url;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
var serperProvider = {
|
|
79
|
+
search: searchSerper,
|
|
80
|
+
validateConfig: validateSerperConfig
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export { searchSerper, serperProvider, validateSerperConfig };
|
|
84
|
+
//# sourceMappingURL=chunk-CEOMTQTP.js.map
|
|
85
|
+
//# sourceMappingURL=chunk-CEOMTQTP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/tools/webSearch/providers/serper.ts"],"names":[],"mappings":"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","file":"chunk-CEOMTQTP.js","sourcesContent":["/**\n * Serper Search Provider\n *\n * Serper is a Google Search API that provides SERP data.\n * Fast and cost-effective for real-time Google results.\n *\n * @see https://serper.dev/\n */\n\nimport type {\n WebSearchConfig,\n WebSearchParams,\n WebSearchResponse,\n SerperApiResponse,\n WebSearchProviderInterface,\n} from \"../types\";\n\nconst SERPER_API_URL = \"https://google.serper.dev/search\";\n\n/**\n * Validate Serper configuration\n */\nexport function validateSerperConfig(config: WebSearchConfig): void {\n if (!config.apiKey) {\n throw new Error(\n \"Serper API key is required. Get one at https://serper.dev/\",\n );\n }\n}\n\n/**\n * Search using Serper API\n */\nexport async function searchSerper(\n params: WebSearchParams,\n config: WebSearchConfig,\n): Promise<WebSearchResponse> {\n validateSerperConfig(config);\n\n const startTime = Date.now();\n\n const requestBody: Record<string, unknown> = {\n q: params.query,\n num: params.maxResults ?? config.maxResults ?? 5,\n };\n\n // Add locale settings\n if (config.country) {\n requestBody.gl = config.country;\n }\n if (config.language) {\n requestBody.hl = config.language;\n }\n\n const response = await fetch(SERPER_API_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-API-KEY\": config.apiKey!,\n },\n body: JSON.stringify(requestBody),\n signal: config.timeout ? AbortSignal.timeout(config.timeout) : undefined,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n throw new Error(`Serper API error (${response.status}): ${errorText}`);\n }\n\n const data: SerperApiResponse = await response.json();\n const searchTime = Date.now() - startTime;\n\n // Filter by domains if specified\n let results = data.organic || [];\n if (config.includeDomains?.length) {\n results = results.filter((r) =>\n config.includeDomains!.some((domain) => r.link.includes(domain)),\n );\n }\n if (config.excludeDomains?.length) {\n results = results.filter(\n (r) => !config.excludeDomains!.some((domain) => r.link.includes(domain)),\n );\n }\n\n // Extract answer from answer box if available\n const answer = data.answerBox?.answer || data.answerBox?.snippet;\n\n return {\n query: params.query,\n answer,\n results: results.map((result) => ({\n title: result.title,\n url: result.link,\n content: result.snippet,\n publishedDate: result.date,\n image: result.imageUrl,\n domain: extractDomain(result.link),\n })),\n images: data.images?.map((img) => ({\n url: img.imageUrl,\n description: img.title,\n sourceUrl: img.link,\n })),\n provider: \"serper\",\n totalResults: results.length,\n searchTime,\n };\n}\n\n/**\n * Extract domain from URL\n */\nfunction extractDomain(url: string): string {\n try {\n return new URL(url).hostname;\n } catch {\n return url;\n }\n}\n\n/**\n * Serper provider implementation\n */\nexport const serperProvider: WebSearchProviderInterface = {\n search: searchSerper,\n validateConfig: validateSerperConfig,\n};\n"]}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// src/core/tools/webSearch/providers/searxng.ts
|
|
2
|
+
var DEFAULT_SEARXNG_URL = "https://searxng.instance.local";
|
|
3
|
+
function validateSearxngConfig(config) {
|
|
4
|
+
if (!config.baseUrl) {
|
|
5
|
+
throw new Error(
|
|
6
|
+
"SearXNG base URL is required. Self-host SearXNG or use a public instance. See https://docs.searxng.org/ for setup instructions."
|
|
7
|
+
);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
async function searchSearxng(params, config) {
|
|
11
|
+
validateSearxngConfig(config);
|
|
12
|
+
const startTime = Date.now();
|
|
13
|
+
const baseUrl = config.baseUrl || DEFAULT_SEARXNG_URL;
|
|
14
|
+
const searchParams = new URLSearchParams({
|
|
15
|
+
q: params.query,
|
|
16
|
+
format: "json"
|
|
17
|
+
});
|
|
18
|
+
if (config.language) {
|
|
19
|
+
searchParams.set("language", config.language);
|
|
20
|
+
}
|
|
21
|
+
const url = `${baseUrl.replace(/\/$/, "")}/search?${searchParams.toString()}`;
|
|
22
|
+
const headers = {
|
|
23
|
+
Accept: "application/json"
|
|
24
|
+
};
|
|
25
|
+
if (config.apiKey) {
|
|
26
|
+
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
27
|
+
}
|
|
28
|
+
const response = await fetch(url, {
|
|
29
|
+
method: "GET",
|
|
30
|
+
headers,
|
|
31
|
+
signal: config.timeout ? AbortSignal.timeout(config.timeout) : void 0
|
|
32
|
+
});
|
|
33
|
+
if (!response.ok) {
|
|
34
|
+
const errorText = await response.text().catch(() => "Unknown error");
|
|
35
|
+
throw new Error(`SearXNG API error (${response.status}): ${errorText}`);
|
|
36
|
+
}
|
|
37
|
+
const data = await response.json();
|
|
38
|
+
const searchTime = Date.now() - startTime;
|
|
39
|
+
let results = data.results || [];
|
|
40
|
+
if (config.includeDomains?.length) {
|
|
41
|
+
results = results.filter(
|
|
42
|
+
(r) => config.includeDomains.some((domain) => r.url.includes(domain))
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
if (config.excludeDomains?.length) {
|
|
46
|
+
results = results.filter(
|
|
47
|
+
(r) => !config.excludeDomains.some((domain) => r.url.includes(domain))
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
const maxResults = params.maxResults ?? config.maxResults ?? 5;
|
|
51
|
+
results = results.slice(0, maxResults);
|
|
52
|
+
const answer = data.answers?.[0] || data.infoboxes?.[0]?.content;
|
|
53
|
+
return {
|
|
54
|
+
query: params.query,
|
|
55
|
+
answer,
|
|
56
|
+
results: results.map((result) => ({
|
|
57
|
+
title: result.title,
|
|
58
|
+
url: result.url,
|
|
59
|
+
content: result.content,
|
|
60
|
+
score: result.score,
|
|
61
|
+
publishedDate: result.publishedDate,
|
|
62
|
+
image: result.img_src,
|
|
63
|
+
domain: extractDomain(result.url)
|
|
64
|
+
})),
|
|
65
|
+
provider: "searxng",
|
|
66
|
+
totalResults: data.number_of_results,
|
|
67
|
+
searchTime
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function extractDomain(url) {
|
|
71
|
+
try {
|
|
72
|
+
return new URL(url).hostname;
|
|
73
|
+
} catch {
|
|
74
|
+
return url;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
var searxngProvider = {
|
|
78
|
+
search: searchSearxng,
|
|
79
|
+
validateConfig: validateSearxngConfig
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export { searchSearxng, searxngProvider, validateSearxngConfig };
|
|
83
|
+
//# sourceMappingURL=chunk-DABZYCVX.js.map
|
|
84
|
+
//# sourceMappingURL=chunk-DABZYCVX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/tools/webSearch/providers/searxng.ts"],"names":[],"mappings":"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","file":"chunk-DABZYCVX.js","sourcesContent":["/**\n * SearXNG Search Provider\n *\n * SearXNG is a privacy-respecting, self-hostable metasearch engine.\n * It aggregates results from multiple search engines without tracking.\n *\n * @see https://docs.searxng.org/\n */\n\nimport type {\n WebSearchConfig,\n WebSearchParams,\n WebSearchResponse,\n SearxngApiResponse,\n WebSearchProviderInterface,\n} from \"../types\";\n\n// Default public instance (users should self-host for production)\nconst DEFAULT_SEARXNG_URL = \"https://searxng.instance.local\";\n\n/**\n * Validate SearXNG configuration\n */\nexport function validateSearxngConfig(config: WebSearchConfig): void {\n if (!config.baseUrl) {\n throw new Error(\n \"SearXNG base URL is required. Self-host SearXNG or use a public instance. \" +\n \"See https://docs.searxng.org/ for setup instructions.\",\n );\n }\n}\n\n/**\n * Search using SearXNG API\n */\nexport async function searchSearxng(\n params: WebSearchParams,\n config: WebSearchConfig,\n): Promise<WebSearchResponse> {\n validateSearxngConfig(config);\n\n const startTime = Date.now();\n\n const baseUrl = config.baseUrl || DEFAULT_SEARXNG_URL;\n const searchParams = new URLSearchParams({\n q: params.query,\n format: \"json\",\n });\n\n // SearXNG doesn't have a direct max_results param, but we can limit after\n if (config.language) {\n searchParams.set(\"language\", config.language);\n }\n\n // Add specific engines if needed\n // searchParams.set('engines', 'google,duckduckgo,bing');\n\n const url = `${baseUrl.replace(/\\/$/, \"\")}/search?${searchParams.toString()}`;\n\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n };\n\n // Add API key if provided (some instances require it)\n if (config.apiKey) {\n headers[\"Authorization\"] = `Bearer ${config.apiKey}`;\n }\n\n const response = await fetch(url, {\n method: \"GET\",\n headers,\n signal: config.timeout ? AbortSignal.timeout(config.timeout) : undefined,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n throw new Error(`SearXNG API error (${response.status}): ${errorText}`);\n }\n\n const data: SearxngApiResponse = await response.json();\n const searchTime = Date.now() - startTime;\n\n // Filter by domains if specified\n let results = data.results || [];\n if (config.includeDomains?.length) {\n results = results.filter((r) =>\n config.includeDomains!.some((domain) => r.url.includes(domain)),\n );\n }\n if (config.excludeDomains?.length) {\n results = results.filter(\n (r) => !config.excludeDomains!.some((domain) => r.url.includes(domain)),\n );\n }\n\n // Limit results\n const maxResults = params.maxResults ?? config.maxResults ?? 5;\n results = results.slice(0, maxResults);\n\n // Extract answer from infoboxes or answers if available\n const answer = data.answers?.[0] || data.infoboxes?.[0]?.content;\n\n return {\n query: params.query,\n answer,\n results: results.map((result) => ({\n title: result.title,\n url: result.url,\n content: result.content,\n score: result.score,\n publishedDate: result.publishedDate,\n image: result.img_src,\n domain: extractDomain(result.url),\n })),\n provider: \"searxng\",\n totalResults: data.number_of_results,\n searchTime,\n };\n}\n\n/**\n * Extract domain from URL\n */\nfunction extractDomain(url: string): string {\n try {\n return new URL(url).hostname;\n } catch {\n return url;\n }\n}\n\n/**\n * SearXNG provider implementation\n */\nexport const searxngProvider: WebSearchProviderInterface = {\n search: searchSearxng,\n validateConfig: validateSearxngConfig,\n};\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export { __require };
|
|
9
|
+
//# sourceMappingURL=chunk-DGUM43GV.js.map
|
|
10
|
+
//# sourceMappingURL=chunk-DGUM43GV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-DGUM43GV.js"}
|