@yourgpt/copilot-sdk 2.0.1 → 2.0.2-beta.2
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-53UGJNHN.js +92 -0
- package/dist/chunk-53UGJNHN.js.map +1 -0
- package/dist/chunk-6T5XXJEP.cjs +80 -0
- package/dist/chunk-6T5XXJEP.cjs.map +1 -0
- package/dist/chunk-7K7HZMP4.cjs +1170 -0
- package/dist/chunk-7K7HZMP4.cjs.map +1 -0
- package/dist/chunk-7W7QLZNC.js +72 -0
- package/dist/chunk-7W7QLZNC.js.map +1 -0
- package/dist/{chunk-JM7PB2LP.js → chunk-7XFFRV7D.js} +10 -66
- package/dist/chunk-7XFFRV7D.js.map +1 -0
- package/dist/chunk-ASV6JLYG.cjs +99 -0
- package/dist/chunk-ASV6JLYG.cjs.map +1 -0
- package/dist/chunk-BH7MNDWW.js +1152 -0
- package/dist/chunk-BH7MNDWW.js.map +1 -0
- package/dist/chunk-BKO7DSPU.js +67 -0
- package/dist/chunk-BKO7DSPU.js.map +1 -0
- package/dist/chunk-CBAHCI4R.cjs +76 -0
- package/dist/chunk-CBAHCI4R.cjs.map +1 -0
- package/dist/chunk-CEKAYA2Q.cjs +74 -0
- package/dist/chunk-CEKAYA2Q.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-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-BLSI67J6.cjs → chunk-H5XMKBBA.cjs} +425 -30
- package/dist/chunk-H5XMKBBA.cjs.map +1 -0
- package/dist/{chunk-CJ7UWN2Y.js → chunk-IXFV6AW6.js} +397 -7
- package/dist/chunk-IXFV6AW6.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-RQ74USYU.js +128 -0
- package/dist/chunk-RQ74USYU.js.map +1 -0
- package/dist/chunk-TXLIY7GF.cjs +132 -0
- package/dist/chunk-TXLIY7GF.cjs.map +1 -0
- package/dist/chunk-UIWFYMAO.cjs +82 -0
- package/dist/chunk-UIWFYMAO.cjs.map +1 -0
- package/dist/{chunk-4PRWNAXQ.cjs → chunk-UOWLKFXK.cjs} +27 -89
- package/dist/chunk-UOWLKFXK.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-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-ZPYQDMUX.js +79 -0
- package/dist/chunk-ZPYQDMUX.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-2VtgKM8S.d.cts +206 -0
- package/dist/index-pWEH7pUE.d.ts +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-DDWrco4h.d.cts} +43 -367
- package/dist/{types-BtAaOV07.d.ts → tools-DDWrco4h.d.ts} +43 -367
- package/dist/types-B20VCJXL.d.cts +347 -0
- package/dist/types-B20VCJXL.d.ts +347 -0
- package/dist/types-Cizh9K_f.d.ts +441 -0
- package/dist/types-DG2ya08y.d.cts +367 -0
- package/dist/types-DG2ya08y.d.ts +367 -0
- package/dist/types-DjSfYNKj.d.cts +441 -0
- package/dist/types-ZguuKEs_.d.cts +127 -0
- package/dist/types-ZguuKEs_.d.ts +127 -0
- package/dist/ui/index.cjs +1075 -148
- 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 +1007 -96
- 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
package/README.md
CHANGED
|
@@ -44,6 +44,48 @@ function App() {
|
|
|
44
44
|
| `/ui` | Pre-built UI components |
|
|
45
45
|
| `/core` | Types, utilities, tool helpers |
|
|
46
46
|
|
|
47
|
+
## Built-in Tools
|
|
48
|
+
|
|
49
|
+
### Web Search
|
|
50
|
+
|
|
51
|
+
Add real-time web search capabilities to your AI copilot. **No extra API key needed** - use your existing OpenAI or Google key.
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { createWebSearchTool } from "@yourgpt/copilot-sdk/core";
|
|
55
|
+
|
|
56
|
+
// Use OpenAI's built-in search (recommended)
|
|
57
|
+
const webSearch = createWebSearchTool({
|
|
58
|
+
provider: "openai",
|
|
59
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Or use Google's built-in search
|
|
63
|
+
const webSearch = createWebSearchTool({
|
|
64
|
+
provider: "google",
|
|
65
|
+
apiKey: process.env.GOOGLE_API_KEY,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const runtime = createRuntime({
|
|
69
|
+
provider: openai,
|
|
70
|
+
model: "gpt-4o",
|
|
71
|
+
tools: [webSearch],
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Native Providers (No extra API needed):**
|
|
76
|
+
|
|
77
|
+
- `openai` - OpenAI's built-in web search
|
|
78
|
+
- `google` - Google's grounding with Google Search
|
|
79
|
+
- `anthropic` - Anthropic's built-in web search
|
|
80
|
+
|
|
81
|
+
**Third-Party Providers:**
|
|
82
|
+
|
|
83
|
+
- [Tavily](https://tavily.com/) - AI-native search with answer generation
|
|
84
|
+
- [Serper](https://serper.dev/) - Google Search API
|
|
85
|
+
- [Brave](https://brave.com/search/api/) - Privacy-focused search
|
|
86
|
+
- [Exa](https://exa.ai/) - Semantic AI search
|
|
87
|
+
- [SearXNG](https://docs.searxng.org/) - Self-hosted metasearch
|
|
88
|
+
|
|
47
89
|
## Examples
|
|
48
90
|
|
|
49
91
|
Explore real-world implementations and demo projects.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { T as Thread, a as ThreadData, b as ThreadStorageAdapter, A as AsyncThreadStorageAdapter, M as Message } from './types-DG2ya08y.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Tool types for App Context Awareness
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { T as Thread, a as ThreadData, b as ThreadStorageAdapter, A as AsyncThreadStorageAdapter, M as Message } from './types-DG2ya08y.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Tool types for App Context Awareness
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"anthropic-6F5GRE3B.js"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { W as WebSearchProviderInterface } from './types-ZguuKEs_.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Anthropic Web Search Provider
|
|
5
|
+
*
|
|
6
|
+
* Uses Anthropic's built-in web_search tool via the Messages API.
|
|
7
|
+
* Returns reliable citations with cited_text, url, and title.
|
|
8
|
+
*
|
|
9
|
+
* @see https://docs.anthropic.com/en/docs/build-with-claude/tool-use/web-search-tool
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Anthropic native search provider implementation
|
|
14
|
+
*/
|
|
15
|
+
declare const anthropicProvider: WebSearchProviderInterface;
|
|
16
|
+
|
|
17
|
+
export { anthropicProvider as a };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { W as WebSearchProviderInterface } from './types-ZguuKEs_.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Anthropic Web Search Provider
|
|
5
|
+
*
|
|
6
|
+
* Uses Anthropic's built-in web_search tool via the Messages API.
|
|
7
|
+
* Returns reliable citations with cited_text, url, and title.
|
|
8
|
+
*
|
|
9
|
+
* @see https://docs.anthropic.com/en/docs/build-with-claude/tool-use/web-search-tool
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Anthropic native search provider implementation
|
|
14
|
+
*/
|
|
15
|
+
declare const anthropicProvider: WebSearchProviderInterface;
|
|
16
|
+
|
|
17
|
+
export { anthropicProvider as a };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkTXLIY7GF_cjs = require('./chunk-TXLIY7GF.cjs');
|
|
4
|
+
require('./chunk-JEQ2X3Z6.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(exports, "anthropicProvider", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () { return chunkTXLIY7GF_cjs.anthropicProvider; }
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "searchAnthropic", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return chunkTXLIY7GF_cjs.searchAnthropic; }
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperty(exports, "validateAnthropicConfig", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return chunkTXLIY7GF_cjs.validateAnthropicConfig; }
|
|
19
|
+
});
|
|
20
|
+
//# sourceMappingURL=anthropic-NMTRABEH.cjs.map
|
|
21
|
+
//# sourceMappingURL=anthropic-NMTRABEH.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"anthropic-NMTRABEH.cjs"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { W as WebSearchProviderInterface } from './types-ZguuKEs_.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Brave Search Provider
|
|
5
|
+
*
|
|
6
|
+
* Brave Search is a privacy-focused search engine with its own index.
|
|
7
|
+
* Provides independent search results without tracking.
|
|
8
|
+
*
|
|
9
|
+
* @see https://brave.com/search/api/
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Brave provider implementation
|
|
14
|
+
*/
|
|
15
|
+
declare const braveProvider: WebSearchProviderInterface;
|
|
16
|
+
|
|
17
|
+
export { braveProvider as b };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { W as WebSearchProviderInterface } from './types-ZguuKEs_.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Brave Search Provider
|
|
5
|
+
*
|
|
6
|
+
* Brave Search is a privacy-focused search engine with its own index.
|
|
7
|
+
* Provides independent search results without tracking.
|
|
8
|
+
*
|
|
9
|
+
* @see https://brave.com/search/api/
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Brave provider implementation
|
|
14
|
+
*/
|
|
15
|
+
declare const braveProvider: WebSearchProviderInterface;
|
|
16
|
+
|
|
17
|
+
export { braveProvider as b };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkW73FBYIH_cjs = require('./chunk-W73FBYIH.cjs');
|
|
4
|
+
require('./chunk-JEQ2X3Z6.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(exports, "braveProvider", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () { return chunkW73FBYIH_cjs.braveProvider; }
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "searchBrave", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return chunkW73FBYIH_cjs.searchBrave; }
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperty(exports, "validateBraveConfig", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return chunkW73FBYIH_cjs.validateBraveConfig; }
|
|
19
|
+
});
|
|
20
|
+
//# sourceMappingURL=brave-OYKCOZEM.cjs.map
|
|
21
|
+
//# sourceMappingURL=brave-OYKCOZEM.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"brave-OYKCOZEM.cjs"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"brave-XSASGGH2.js"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/core/tools/webSearch/providers/searxng.ts
|
|
4
|
+
var DEFAULT_SEARXNG_URL = "https://searxng.instance.local";
|
|
5
|
+
function validateSearxngConfig(config) {
|
|
6
|
+
if (!config.baseUrl) {
|
|
7
|
+
throw new Error(
|
|
8
|
+
"SearXNG base URL is required. Self-host SearXNG or use a public instance. See https://docs.searxng.org/ for setup instructions."
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
async function searchSearxng(params, config) {
|
|
13
|
+
validateSearxngConfig(config);
|
|
14
|
+
const startTime = Date.now();
|
|
15
|
+
const baseUrl = config.baseUrl || DEFAULT_SEARXNG_URL;
|
|
16
|
+
const searchParams = new URLSearchParams({
|
|
17
|
+
q: params.query,
|
|
18
|
+
format: "json"
|
|
19
|
+
});
|
|
20
|
+
if (config.language) {
|
|
21
|
+
searchParams.set("language", config.language);
|
|
22
|
+
}
|
|
23
|
+
const url = `${baseUrl.replace(/\/$/, "")}/search?${searchParams.toString()}`;
|
|
24
|
+
const headers = {
|
|
25
|
+
Accept: "application/json"
|
|
26
|
+
};
|
|
27
|
+
if (config.apiKey) {
|
|
28
|
+
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
29
|
+
}
|
|
30
|
+
const response = await fetch(url, {
|
|
31
|
+
method: "GET",
|
|
32
|
+
headers,
|
|
33
|
+
signal: config.timeout ? AbortSignal.timeout(config.timeout) : void 0
|
|
34
|
+
});
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
const errorText = await response.text().catch(() => "Unknown error");
|
|
37
|
+
throw new Error(`SearXNG API error (${response.status}): ${errorText}`);
|
|
38
|
+
}
|
|
39
|
+
const data = await response.json();
|
|
40
|
+
const searchTime = Date.now() - startTime;
|
|
41
|
+
let results = data.results || [];
|
|
42
|
+
if (config.includeDomains?.length) {
|
|
43
|
+
results = results.filter(
|
|
44
|
+
(r) => config.includeDomains.some((domain) => r.url.includes(domain))
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
if (config.excludeDomains?.length) {
|
|
48
|
+
results = results.filter(
|
|
49
|
+
(r) => !config.excludeDomains.some((domain) => r.url.includes(domain))
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
const maxResults = params.maxResults ?? config.maxResults ?? 5;
|
|
53
|
+
results = results.slice(0, maxResults);
|
|
54
|
+
const answer = data.answers?.[0] || data.infoboxes?.[0]?.content;
|
|
55
|
+
return {
|
|
56
|
+
query: params.query,
|
|
57
|
+
answer,
|
|
58
|
+
results: results.map((result) => ({
|
|
59
|
+
title: result.title,
|
|
60
|
+
url: result.url,
|
|
61
|
+
content: result.content,
|
|
62
|
+
score: result.score,
|
|
63
|
+
publishedDate: result.publishedDate,
|
|
64
|
+
image: result.img_src,
|
|
65
|
+
domain: extractDomain(result.url)
|
|
66
|
+
})),
|
|
67
|
+
provider: "searxng",
|
|
68
|
+
totalResults: data.number_of_results,
|
|
69
|
+
searchTime
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function extractDomain(url) {
|
|
73
|
+
try {
|
|
74
|
+
return new URL(url).hostname;
|
|
75
|
+
} catch {
|
|
76
|
+
return url;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
var searxngProvider = {
|
|
80
|
+
search: searchSearxng,
|
|
81
|
+
validateConfig: validateSearxngConfig
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
exports.searchSearxng = searchSearxng;
|
|
85
|
+
exports.searxngProvider = searxngProvider;
|
|
86
|
+
exports.validateSearxngConfig = validateSearxngConfig;
|
|
87
|
+
//# sourceMappingURL=chunk-2FAWEBZS.cjs.map
|
|
88
|
+
//# sourceMappingURL=chunk-2FAWEBZS.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/tools/webSearch/providers/searxng.ts"],"names":[],"mappings":"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","file":"chunk-2FAWEBZS.cjs","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,92 @@
|
|
|
1
|
+
// src/core/tools/webSearch/providers/google.ts
|
|
2
|
+
var GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models";
|
|
3
|
+
function validateGoogleConfig(config) {
|
|
4
|
+
if (!config.apiKey) {
|
|
5
|
+
throw new Error(
|
|
6
|
+
"Google API key is required for native web search. Pass apiKey or set GOOGLE_API_KEY/GEMINI_API_KEY environment variable."
|
|
7
|
+
);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
async function searchGoogle(params, config) {
|
|
11
|
+
validateGoogleConfig(config);
|
|
12
|
+
const startTime = Date.now();
|
|
13
|
+
const apiKey = config.apiKey || process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY;
|
|
14
|
+
const model = "gemini-2.0-flash";
|
|
15
|
+
const url = `${GEMINI_API_URL}/${model}:generateContent?key=${apiKey}`;
|
|
16
|
+
const requestBody = {
|
|
17
|
+
contents: [
|
|
18
|
+
{
|
|
19
|
+
parts: [
|
|
20
|
+
{
|
|
21
|
+
text: params.query
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
tools: [
|
|
27
|
+
{
|
|
28
|
+
google_search: {}
|
|
29
|
+
// Enable Google Search grounding
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
// Generation config
|
|
33
|
+
generationConfig: {
|
|
34
|
+
temperature: 0.7,
|
|
35
|
+
maxOutputTokens: 1024
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const response = await fetch(url, {
|
|
39
|
+
method: "POST",
|
|
40
|
+
headers: {
|
|
41
|
+
"Content-Type": "application/json"
|
|
42
|
+
},
|
|
43
|
+
body: JSON.stringify(requestBody),
|
|
44
|
+
signal: config.timeout ? AbortSignal.timeout(config.timeout) : void 0
|
|
45
|
+
});
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
const errorText = await response.text().catch(() => "Unknown error");
|
|
48
|
+
throw new Error(
|
|
49
|
+
`Google Gemini API error (${response.status}): ${errorText}`
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
const data = await response.json();
|
|
53
|
+
const searchTime = Date.now() - startTime;
|
|
54
|
+
const candidates = data.candidates || [];
|
|
55
|
+
const content = candidates[0]?.content;
|
|
56
|
+
const textParts = content?.parts?.filter((p) => p.text) || [];
|
|
57
|
+
const generatedText = textParts.map((p) => p.text).join("\n");
|
|
58
|
+
const groundingMetadata = candidates[0]?.groundingMetadata;
|
|
59
|
+
const groundingChunks = groundingMetadata?.groundingChunks || [];
|
|
60
|
+
groundingMetadata?.searchEntryPoint;
|
|
61
|
+
const results = groundingChunks.filter((chunk) => chunk.web).slice(0, params.maxResults ?? config.maxResults ?? 5).map((chunk, i) => ({
|
|
62
|
+
title: chunk.web.title || extractDomain(chunk.web.uri),
|
|
63
|
+
url: chunk.web.uri,
|
|
64
|
+
content: "",
|
|
65
|
+
// Google doesn't provide snippets in grounding response
|
|
66
|
+
score: 1 - i * 0.1,
|
|
67
|
+
domain: extractDomain(chunk.web.uri)
|
|
68
|
+
}));
|
|
69
|
+
return {
|
|
70
|
+
query: params.query,
|
|
71
|
+
answer: generatedText,
|
|
72
|
+
results,
|
|
73
|
+
provider: "google",
|
|
74
|
+
totalResults: groundingChunks.length,
|
|
75
|
+
searchTime
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function extractDomain(url) {
|
|
79
|
+
try {
|
|
80
|
+
return new URL(url).hostname.replace("www.", "");
|
|
81
|
+
} catch {
|
|
82
|
+
return url;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
var googleProvider = {
|
|
86
|
+
search: searchGoogle,
|
|
87
|
+
validateConfig: validateGoogleConfig
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export { googleProvider, searchGoogle, validateGoogleConfig };
|
|
91
|
+
//# sourceMappingURL=chunk-53UGJNHN.js.map
|
|
92
|
+
//# sourceMappingURL=chunk-53UGJNHN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/tools/webSearch/providers/google.ts"],"names":[],"mappings":"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","file":"chunk-53UGJNHN.js","sourcesContent":["/**\n * Google Web Search Provider (Grounding with Google Search)\n *\n * Uses Google's built-in grounding feature via the Gemini API.\n * No third-party API key required - uses your Google/Gemini API key.\n *\n * @see https://ai.google.dev/gemini-api/docs/google-search\n */\n\nimport type {\n WebSearchConfig,\n WebSearchParams,\n WebSearchResponse,\n WebSearchProviderInterface,\n} from \"../types\";\n\nconst GEMINI_API_URL =\n \"https://generativelanguage.googleapis.com/v1beta/models\";\n\n/**\n * Validate Google native search configuration\n */\nexport function validateGoogleConfig(config: WebSearchConfig): void {\n if (!config.apiKey) {\n throw new Error(\n \"Google API key is required for native web search. \" +\n \"Pass apiKey or set GOOGLE_API_KEY/GEMINI_API_KEY environment variable.\",\n );\n }\n}\n\n/**\n * Search using Google's native grounding with Google Search\n */\nexport async function searchGoogle(\n params: WebSearchParams,\n config: WebSearchConfig,\n): Promise<WebSearchResponse> {\n validateGoogleConfig(config);\n\n const startTime = Date.now();\n const apiKey =\n config.apiKey || process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY;\n const model = \"gemini-2.0-flash\"; // Use latest model with grounding support\n\n const url = `${GEMINI_API_URL}/${model}:generateContent?key=${apiKey}`;\n\n // Build request with Google Search grounding\n const requestBody = {\n contents: [\n {\n parts: [\n {\n text: params.query,\n },\n ],\n },\n ],\n tools: [\n {\n google_search: {}, // Enable Google Search grounding\n },\n ],\n // Generation config\n generationConfig: {\n temperature: 0.7,\n maxOutputTokens: 1024,\n },\n };\n\n const response = await fetch(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(\n `Google Gemini API error (${response.status}): ${errorText}`,\n );\n }\n\n const data = await response.json();\n const searchTime = Date.now() - startTime;\n\n // Extract the generated text\n const candidates = data.candidates || [];\n const content = candidates[0]?.content;\n const textParts =\n content?.parts?.filter((p: { text?: string }) => p.text) || [];\n const generatedText = textParts\n .map((p: { text: string }) => p.text)\n .join(\"\\n\");\n\n // Extract grounding metadata (sources)\n const groundingMetadata = candidates[0]?.groundingMetadata;\n const groundingChunks = groundingMetadata?.groundingChunks || [];\n const searchEntryPoint = groundingMetadata?.searchEntryPoint;\n\n // Build results from grounding chunks\n const results = groundingChunks\n .filter((chunk: { web?: { uri: string; title?: string } }) => chunk.web)\n .slice(0, params.maxResults ?? config.maxResults ?? 5)\n .map((chunk: { web: { uri: string; title?: string } }, i: number) => ({\n title: chunk.web.title || extractDomain(chunk.web.uri),\n url: chunk.web.uri,\n content: \"\", // Google doesn't provide snippets in grounding response\n score: 1 - i * 0.1,\n domain: extractDomain(chunk.web.uri),\n }));\n\n return {\n query: params.query,\n answer: generatedText,\n results,\n provider: \"google\",\n totalResults: groundingChunks.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.replace(\"www.\", \"\");\n } catch {\n return url;\n }\n}\n\n/**\n * Google native search provider implementation\n */\nexport const googleProvider: WebSearchProviderInterface = {\n search: searchGoogle,\n validateConfig: validateGoogleConfig,\n};\n"]}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/core/tools/webSearch/providers/exa.ts
|
|
4
|
+
var EXA_API_URL = "https://api.exa.ai/search";
|
|
5
|
+
function validateExaConfig(config) {
|
|
6
|
+
if (!config.apiKey) {
|
|
7
|
+
throw new Error("Exa API key is required. Get one at https://exa.ai/");
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
async function searchExa(params, config) {
|
|
11
|
+
validateExaConfig(config);
|
|
12
|
+
const startTime = Date.now();
|
|
13
|
+
const searchType = params.searchDepth === "advanced" || config.searchDepth === "advanced" ? "auto" : "keyword";
|
|
14
|
+
const requestBody = {
|
|
15
|
+
query: params.query,
|
|
16
|
+
numResults: params.maxResults ?? config.maxResults ?? 5,
|
|
17
|
+
type: searchType,
|
|
18
|
+
useAutoprompt: searchType === "auto"
|
|
19
|
+
};
|
|
20
|
+
if (config.includeRawContent) {
|
|
21
|
+
requestBody.contents = {
|
|
22
|
+
text: true,
|
|
23
|
+
highlights: true
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (config.includeDomains?.length) {
|
|
27
|
+
requestBody.includeDomains = config.includeDomains;
|
|
28
|
+
}
|
|
29
|
+
if (config.excludeDomains?.length) {
|
|
30
|
+
requestBody.excludeDomains = config.excludeDomains;
|
|
31
|
+
}
|
|
32
|
+
const response = await fetch(EXA_API_URL, {
|
|
33
|
+
method: "POST",
|
|
34
|
+
headers: {
|
|
35
|
+
"Content-Type": "application/json",
|
|
36
|
+
"x-api-key": config.apiKey
|
|
37
|
+
},
|
|
38
|
+
body: JSON.stringify(requestBody),
|
|
39
|
+
signal: config.timeout ? AbortSignal.timeout(config.timeout) : void 0
|
|
40
|
+
});
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
const errorText = await response.text().catch(() => "Unknown error");
|
|
43
|
+
throw new Error(`Exa API error (${response.status}): ${errorText}`);
|
|
44
|
+
}
|
|
45
|
+
const data = await response.json();
|
|
46
|
+
const searchTime = Date.now() - startTime;
|
|
47
|
+
return {
|
|
48
|
+
query: params.query,
|
|
49
|
+
// Exa uses autoprompt to improve the query, include it as context
|
|
50
|
+
answer: data.autopromptString ? `Enhanced query: ${data.autopromptString}` : void 0,
|
|
51
|
+
results: data.results.map((result) => ({
|
|
52
|
+
title: result.title,
|
|
53
|
+
url: result.url,
|
|
54
|
+
content: result.highlights?.join(" ") || result.text?.slice(0, 300) || "",
|
|
55
|
+
score: result.score,
|
|
56
|
+
publishedDate: result.publishedDate,
|
|
57
|
+
domain: extractDomain(result.url)
|
|
58
|
+
})),
|
|
59
|
+
provider: "exa",
|
|
60
|
+
totalResults: data.results.length,
|
|
61
|
+
searchTime
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function extractDomain(url) {
|
|
65
|
+
try {
|
|
66
|
+
return new URL(url).hostname;
|
|
67
|
+
} catch {
|
|
68
|
+
return url;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
var exaProvider = {
|
|
72
|
+
search: searchExa,
|
|
73
|
+
validateConfig: validateExaConfig
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
exports.exaProvider = exaProvider;
|
|
77
|
+
exports.searchExa = searchExa;
|
|
78
|
+
exports.validateExaConfig = validateExaConfig;
|
|
79
|
+
//# sourceMappingURL=chunk-6T5XXJEP.cjs.map
|
|
80
|
+
//# sourceMappingURL=chunk-6T5XXJEP.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/tools/webSearch/providers/exa.ts"],"names":[],"mappings":"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","file":"chunk-6T5XXJEP.cjs","sourcesContent":["/**\n * Exa Search Provider\n *\n * Exa (formerly Metaphor) is an AI-native search engine\n * that understands queries semantically for better results.\n *\n * @see https://exa.ai/\n */\n\nimport type {\n WebSearchConfig,\n WebSearchParams,\n WebSearchResponse,\n ExaApiResponse,\n WebSearchProviderInterface,\n} from \"../types\";\n\nconst EXA_API_URL = \"https://api.exa.ai/search\";\n\n/**\n * Validate Exa configuration\n */\nexport function validateExaConfig(config: WebSearchConfig): void {\n if (!config.apiKey) {\n throw new Error(\"Exa API key is required. Get one at https://exa.ai/\");\n }\n}\n\n/**\n * Search using Exa API\n */\nexport async function searchExa(\n params: WebSearchParams,\n config: WebSearchConfig,\n): Promise<WebSearchResponse> {\n validateExaConfig(config);\n\n const startTime = Date.now();\n\n // Exa uses \"auto\" for their autoprompt feature which enhances queries\n const searchType =\n params.searchDepth === \"advanced\" || config.searchDepth === \"advanced\"\n ? \"auto\"\n : \"keyword\";\n\n const requestBody: Record<string, unknown> = {\n query: params.query,\n numResults: params.maxResults ?? config.maxResults ?? 5,\n type: searchType,\n useAutoprompt: searchType === \"auto\",\n };\n\n // Add content retrieval if raw content is requested\n if (config.includeRawContent) {\n requestBody.contents = {\n text: true,\n highlights: true,\n };\n }\n\n // Domain filtering\n if (config.includeDomains?.length) {\n requestBody.includeDomains = config.includeDomains;\n }\n if (config.excludeDomains?.length) {\n requestBody.excludeDomains = config.excludeDomains;\n }\n\n const response = await fetch(EXA_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(`Exa API error (${response.status}): ${errorText}`);\n }\n\n const data: ExaApiResponse = await response.json();\n const searchTime = Date.now() - startTime;\n\n return {\n query: params.query,\n // Exa uses autoprompt to improve the query, include it as context\n answer: data.autopromptString\n ? `Enhanced query: ${data.autopromptString}`\n : undefined,\n results: data.results.map((result) => ({\n title: result.title,\n url: result.url,\n content: result.highlights?.join(\" \") || result.text?.slice(0, 300) || \"\",\n score: result.score,\n publishedDate: result.publishedDate,\n domain: extractDomain(result.url),\n })),\n provider: \"exa\",\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 * Exa provider implementation\n */\nexport const exaProvider: WebSearchProviderInterface = {\n search: searchExa,\n validateConfig: validateExaConfig,\n};\n"]}
|