@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.
Files changed (215) hide show
  1. package/README.md +42 -0
  2. package/dist/{ThreadManager-JT0sqSSD.d.ts → ThreadManager-Dkp_eLty.d.ts} +1 -1
  3. package/dist/{ThreadManager-CUq5Ocu2.d.cts → ThreadManager-LfFRhr4e.d.cts} +1 -1
  4. package/dist/anthropic-6F5GRE3B.js +4 -0
  5. package/dist/anthropic-6F5GRE3B.js.map +1 -0
  6. package/dist/anthropic-DGalr_Fw.d.cts +17 -0
  7. package/dist/anthropic-DkCEDYOt.d.ts +17 -0
  8. package/dist/anthropic-NMTRABEH.cjs +21 -0
  9. package/dist/anthropic-NMTRABEH.cjs.map +1 -0
  10. package/dist/brave-DdnWb7Gb.d.cts +17 -0
  11. package/dist/brave-DsI9n7Wr.d.ts +17 -0
  12. package/dist/brave-OYKCOZEM.cjs +21 -0
  13. package/dist/brave-OYKCOZEM.cjs.map +1 -0
  14. package/dist/brave-XSASGGH2.js +4 -0
  15. package/dist/brave-XSASGGH2.js.map +1 -0
  16. package/dist/chunk-2FAWEBZS.cjs +88 -0
  17. package/dist/chunk-2FAWEBZS.cjs.map +1 -0
  18. package/dist/chunk-53UGJNHN.js +92 -0
  19. package/dist/chunk-53UGJNHN.js.map +1 -0
  20. package/dist/chunk-6T5XXJEP.cjs +80 -0
  21. package/dist/chunk-6T5XXJEP.cjs.map +1 -0
  22. package/dist/chunk-7K7HZMP4.cjs +1170 -0
  23. package/dist/chunk-7K7HZMP4.cjs.map +1 -0
  24. package/dist/chunk-7W7QLZNC.js +72 -0
  25. package/dist/chunk-7W7QLZNC.js.map +1 -0
  26. package/dist/{chunk-JM7PB2LP.js → chunk-7XFFRV7D.js} +10 -66
  27. package/dist/chunk-7XFFRV7D.js.map +1 -0
  28. package/dist/chunk-ASV6JLYG.cjs +99 -0
  29. package/dist/chunk-ASV6JLYG.cjs.map +1 -0
  30. package/dist/chunk-BH7MNDWW.js +1152 -0
  31. package/dist/chunk-BH7MNDWW.js.map +1 -0
  32. package/dist/chunk-BKO7DSPU.js +67 -0
  33. package/dist/chunk-BKO7DSPU.js.map +1 -0
  34. package/dist/chunk-CBAHCI4R.cjs +76 -0
  35. package/dist/chunk-CBAHCI4R.cjs.map +1 -0
  36. package/dist/chunk-CEKAYA2Q.cjs +74 -0
  37. package/dist/chunk-CEKAYA2Q.cjs.map +1 -0
  38. package/dist/chunk-CEOMTQTP.js +85 -0
  39. package/dist/chunk-CEOMTQTP.js.map +1 -0
  40. package/dist/chunk-DABZYCVX.js +84 -0
  41. package/dist/chunk-DABZYCVX.js.map +1 -0
  42. package/dist/chunk-DGUM43GV.js +10 -0
  43. package/dist/chunk-DGUM43GV.js.map +1 -0
  44. package/dist/chunk-G4SF2PNQ.js +33 -0
  45. package/dist/chunk-G4SF2PNQ.js.map +1 -0
  46. package/dist/chunk-GANCV72Z.cjs +110 -0
  47. package/dist/chunk-GANCV72Z.cjs.map +1 -0
  48. package/dist/{chunk-BLSI67J6.cjs → chunk-H5XMKBBA.cjs} +425 -30
  49. package/dist/chunk-H5XMKBBA.cjs.map +1 -0
  50. package/dist/{chunk-CJ7UWN2Y.js → chunk-IXFV6AW6.js} +397 -7
  51. package/dist/chunk-IXFV6AW6.js.map +1 -0
  52. package/dist/chunk-JEQ2X3Z6.cjs +12 -0
  53. package/dist/chunk-JEQ2X3Z6.cjs.map +1 -0
  54. package/dist/chunk-JO4BHPAD.cjs +40 -0
  55. package/dist/chunk-JO4BHPAD.cjs.map +1 -0
  56. package/dist/chunk-MEBXW75C.cjs +89 -0
  57. package/dist/chunk-MEBXW75C.cjs.map +1 -0
  58. package/dist/chunk-MNDGIW47.js +76 -0
  59. package/dist/chunk-MNDGIW47.js.map +1 -0
  60. package/dist/chunk-PPFHA6IL.js +83 -0
  61. package/dist/chunk-PPFHA6IL.js.map +1 -0
  62. package/dist/chunk-RQ74USYU.js +128 -0
  63. package/dist/chunk-RQ74USYU.js.map +1 -0
  64. package/dist/chunk-TXLIY7GF.cjs +132 -0
  65. package/dist/chunk-TXLIY7GF.cjs.map +1 -0
  66. package/dist/chunk-UIWFYMAO.cjs +82 -0
  67. package/dist/chunk-UIWFYMAO.cjs.map +1 -0
  68. package/dist/{chunk-4PRWNAXQ.cjs → chunk-UOWLKFXK.cjs} +27 -89
  69. package/dist/chunk-UOWLKFXK.cjs.map +1 -0
  70. package/dist/chunk-VD74IPKB.js +106 -0
  71. package/dist/chunk-VD74IPKB.js.map +1 -0
  72. package/dist/chunk-W73FBYIH.cjs +87 -0
  73. package/dist/chunk-W73FBYIH.cjs.map +1 -0
  74. package/dist/chunk-XGITAEXU.js +93 -0
  75. package/dist/chunk-XGITAEXU.js.map +1 -0
  76. package/dist/chunk-XWOHNY3F.cjs +96 -0
  77. package/dist/chunk-XWOHNY3F.cjs.map +1 -0
  78. package/dist/chunk-ZPYQDMUX.js +79 -0
  79. package/dist/chunk-ZPYQDMUX.js.map +1 -0
  80. package/dist/core/index.cjs +156 -84
  81. package/dist/core/index.d.cts +16 -4
  82. package/dist/core/index.d.ts +16 -4
  83. package/dist/core/index.js +13 -1
  84. package/dist/exa-72KFY5A7.cjs +21 -0
  85. package/dist/exa-72KFY5A7.cjs.map +1 -0
  86. package/dist/exa-Dp9U-WTc.d.ts +17 -0
  87. package/dist/exa-NNVPBC2M.js +4 -0
  88. package/dist/exa-NNVPBC2M.js.map +1 -0
  89. package/dist/exa-jJSPhyUW.d.cts +17 -0
  90. package/dist/google-CHU2yycE.d.cts +17 -0
  91. package/dist/google-CTEK6SV2.js +4 -0
  92. package/dist/google-CTEK6SV2.js.map +1 -0
  93. package/dist/google-Da8IQxaI.d.ts +17 -0
  94. package/dist/google-IIUXFFVF.cjs +21 -0
  95. package/dist/google-IIUXFFVF.cjs.map +1 -0
  96. package/dist/index-2VtgKM8S.d.cts +206 -0
  97. package/dist/index-pWEH7pUE.d.ts +206 -0
  98. package/dist/mcp/index.cjs +670 -0
  99. package/dist/mcp/index.cjs.map +1 -0
  100. package/dist/mcp/index.d.cts +779 -0
  101. package/dist/mcp/index.d.ts +779 -0
  102. package/dist/mcp/index.js +574 -0
  103. package/dist/mcp/index.js.map +1 -0
  104. package/dist/openai-6KTCQ7PZ.cjs +21 -0
  105. package/dist/openai-6KTCQ7PZ.cjs.map +1 -0
  106. package/dist/openai-7W2PCNW5.js +4 -0
  107. package/dist/openai-7W2PCNW5.js.map +1 -0
  108. package/dist/openai-Cam8hF4f.d.ts +17 -0
  109. package/dist/openai-HVSCuXgO.d.cts +17 -0
  110. package/dist/react/index.cjs +75 -42
  111. package/dist/react/index.d.cts +270 -45
  112. package/dist/react/index.d.ts +270 -45
  113. package/dist/react/index.js +15 -2
  114. package/dist/searxng-AXLVGY7Z.js +4 -0
  115. package/dist/searxng-AXLVGY7Z.js.map +1 -0
  116. package/dist/searxng-EJKNY236.cjs +21 -0
  117. package/dist/searxng-EJKNY236.cjs.map +1 -0
  118. package/dist/searxng-K0qtY9vp.d.ts +17 -0
  119. package/dist/searxng-QGOte_Gq.d.cts +17 -0
  120. package/dist/serper-3JYJHJX6.js +4 -0
  121. package/dist/serper-3JYJHJX6.js.map +1 -0
  122. package/dist/serper-63FT4AOL.cjs +21 -0
  123. package/dist/serper-63FT4AOL.cjs.map +1 -0
  124. package/dist/serper-7Czya3PW.d.ts +17 -0
  125. package/dist/serper-JzdaSnS9.d.cts +17 -0
  126. package/dist/styles.css +38 -0
  127. package/dist/tavily-AWFP4RM7.cjs +21 -0
  128. package/dist/tavily-AWFP4RM7.cjs.map +1 -0
  129. package/dist/tavily-C8cXXojE.d.cts +17 -0
  130. package/dist/tavily-CIWAAZPH.js +4 -0
  131. package/dist/tavily-CIWAAZPH.js.map +1 -0
  132. package/dist/tavily-DdSGVgkE.d.ts +17 -0
  133. package/dist/themes/catppuccin.css +2 -0
  134. package/dist/themes/claude.css +2 -0
  135. package/dist/themes/linear.css +2 -0
  136. package/dist/themes/modern-minimal.css +2 -0
  137. package/dist/themes/posthog.css +2 -0
  138. package/dist/themes/supabase.css +2 -0
  139. package/dist/themes/twitter.css +2 -0
  140. package/dist/themes/vercel.css +2 -0
  141. package/dist/tools/anthropic/index.cjs +61 -0
  142. package/dist/tools/anthropic/index.cjs.map +1 -0
  143. package/dist/tools/anthropic/index.d.cts +67 -0
  144. package/dist/tools/anthropic/index.d.ts +67 -0
  145. package/dist/tools/anthropic/index.js +56 -0
  146. package/dist/tools/anthropic/index.js.map +1 -0
  147. package/dist/tools/brave/index.cjs +85 -0
  148. package/dist/tools/brave/index.cjs.map +1 -0
  149. package/dist/tools/brave/index.d.cts +91 -0
  150. package/dist/tools/brave/index.d.ts +91 -0
  151. package/dist/tools/brave/index.js +80 -0
  152. package/dist/tools/brave/index.js.map +1 -0
  153. package/dist/tools/exa/index.cjs +90 -0
  154. package/dist/tools/exa/index.cjs.map +1 -0
  155. package/dist/tools/exa/index.d.cts +92 -0
  156. package/dist/tools/exa/index.d.ts +92 -0
  157. package/dist/tools/exa/index.js +85 -0
  158. package/dist/tools/exa/index.js.map +1 -0
  159. package/dist/tools/google/index.cjs +81 -0
  160. package/dist/tools/google/index.cjs.map +1 -0
  161. package/dist/tools/google/index.d.cts +81 -0
  162. package/dist/tools/google/index.d.ts +81 -0
  163. package/dist/tools/google/index.js +76 -0
  164. package/dist/tools/google/index.js.map +1 -0
  165. package/dist/tools/openai/index.cjs +83 -0
  166. package/dist/tools/openai/index.cjs.map +1 -0
  167. package/dist/tools/openai/index.d.cts +84 -0
  168. package/dist/tools/openai/index.d.ts +84 -0
  169. package/dist/tools/openai/index.js +78 -0
  170. package/dist/tools/openai/index.js.map +1 -0
  171. package/dist/tools/searxng/index.cjs +85 -0
  172. package/dist/tools/searxng/index.cjs.map +1 -0
  173. package/dist/tools/searxng/index.d.cts +91 -0
  174. package/dist/tools/searxng/index.d.ts +91 -0
  175. package/dist/tools/searxng/index.js +80 -0
  176. package/dist/tools/searxng/index.js.map +1 -0
  177. package/dist/tools/serper/index.cjs +85 -0
  178. package/dist/tools/serper/index.cjs.map +1 -0
  179. package/dist/tools/serper/index.d.cts +91 -0
  180. package/dist/tools/serper/index.d.ts +91 -0
  181. package/dist/tools/serper/index.js +80 -0
  182. package/dist/tools/serper/index.js.map +1 -0
  183. package/dist/tools/tavily/index.cjs +91 -0
  184. package/dist/tools/tavily/index.cjs.map +1 -0
  185. package/dist/tools/tavily/index.d.cts +95 -0
  186. package/dist/tools/tavily/index.d.ts +95 -0
  187. package/dist/tools/tavily/index.js +86 -0
  188. package/dist/tools/tavily/index.js.map +1 -0
  189. package/dist/tools/web-search/index.cjs +31 -0
  190. package/dist/tools/web-search/index.cjs.map +1 -0
  191. package/dist/tools/web-search/index.d.cts +3 -0
  192. package/dist/tools/web-search/index.d.ts +3 -0
  193. package/dist/tools/web-search/index.js +14 -0
  194. package/dist/tools/web-search/index.js.map +1 -0
  195. package/dist/{types-BtAaOV07.d.cts → tools-DDWrco4h.d.cts} +43 -367
  196. package/dist/{types-BtAaOV07.d.ts → tools-DDWrco4h.d.ts} +43 -367
  197. package/dist/types-B20VCJXL.d.cts +347 -0
  198. package/dist/types-B20VCJXL.d.ts +347 -0
  199. package/dist/types-Cizh9K_f.d.ts +441 -0
  200. package/dist/types-DG2ya08y.d.cts +367 -0
  201. package/dist/types-DG2ya08y.d.ts +367 -0
  202. package/dist/types-DjSfYNKj.d.cts +441 -0
  203. package/dist/types-ZguuKEs_.d.cts +127 -0
  204. package/dist/types-ZguuKEs_.d.ts +127 -0
  205. package/dist/ui/index.cjs +1075 -148
  206. package/dist/ui/index.cjs.map +1 -1
  207. package/dist/ui/index.d.cts +410 -4
  208. package/dist/ui/index.d.ts +410 -4
  209. package/dist/ui/index.js +1007 -96
  210. package/dist/ui/index.js.map +1 -1
  211. package/package.json +52 -2
  212. package/dist/chunk-4PRWNAXQ.cjs.map +0 -1
  213. package/dist/chunk-BLSI67J6.cjs.map +0 -1
  214. package/dist/chunk-CJ7UWN2Y.js.map +0 -1
  215. package/dist/chunk-JM7PB2LP.js.map +0 -1
@@ -0,0 +1,106 @@
1
+ // src/core/tools/webSearch/providers/openai.ts
2
+ function validateOpenAIConfig(config) {
3
+ if (!config.apiKey) {
4
+ throw new Error(
5
+ "OpenAI API key is required for native web search. Pass apiKey or set OPENAI_API_KEY environment variable."
6
+ );
7
+ }
8
+ }
9
+ async function searchOpenAI(params, config) {
10
+ validateOpenAIConfig(config);
11
+ const startTime = Date.now();
12
+ const apiKey = config.apiKey || process.env.OPENAI_API_KEY;
13
+ const tools = [
14
+ {
15
+ type: "web_search",
16
+ // Domain filtering if provided
17
+ ...config.includeDomains?.length && {
18
+ filters: {
19
+ domains: config.includeDomains
20
+ }
21
+ }
22
+ }
23
+ ];
24
+ const response = await fetch("https://api.openai.com/v1/responses", {
25
+ method: "POST",
26
+ headers: {
27
+ "Content-Type": "application/json",
28
+ Authorization: `Bearer ${apiKey}`
29
+ },
30
+ body: JSON.stringify({
31
+ model: "gpt-4o",
32
+ // Use GPT-4o for web search
33
+ tools,
34
+ input: params.query
35
+ }),
36
+ signal: config.timeout ? AbortSignal.timeout(config.timeout) : void 0
37
+ });
38
+ if (!response.ok) {
39
+ const errorText = await response.text().catch(() => "Unknown error");
40
+ console.error(
41
+ "[OpenAI Native Search] API error:",
42
+ response.status,
43
+ errorText
44
+ );
45
+ throw new Error(
46
+ `OpenAI Responses API error (${response.status}): ${errorText}`
47
+ );
48
+ }
49
+ const data = await response.json();
50
+ const searchTime = Date.now() - startTime;
51
+ let outputText = "";
52
+ const sources = [];
53
+ if (data.output && Array.isArray(data.output)) {
54
+ for (const item of data.output) {
55
+ if (item.type === "message" && item.content) {
56
+ for (const contentPart of item.content) {
57
+ if (contentPart.type === "output_text" && contentPart.text) {
58
+ outputText = contentPart.text;
59
+ }
60
+ if (contentPart.annotations && Array.isArray(contentPart.annotations)) {
61
+ for (const annotation of contentPart.annotations) {
62
+ if (annotation.type === "url_citation" && annotation.url) {
63
+ if (!sources.find((s) => s.url === annotation.url)) {
64
+ sources.push({
65
+ url: annotation.url,
66
+ title: annotation.title || extractDomain(annotation.url)
67
+ });
68
+ }
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ return {
77
+ query: params.query,
78
+ answer: outputText,
79
+ results: sources.slice(0, params.maxResults ?? config.maxResults ?? 5).map((source, i) => ({
80
+ title: source.title,
81
+ url: source.url,
82
+ content: "",
83
+ // OpenAI returns answer with inline citations, not separate snippets
84
+ score: 1 - i * 0.1,
85
+ domain: extractDomain(source.url)
86
+ })),
87
+ provider: "openai",
88
+ totalResults: sources.length,
89
+ searchTime
90
+ };
91
+ }
92
+ function extractDomain(url) {
93
+ try {
94
+ return new URL(url).hostname.replace("www.", "");
95
+ } catch {
96
+ return url;
97
+ }
98
+ }
99
+ var openaiProvider = {
100
+ search: searchOpenAI,
101
+ validateConfig: validateOpenAIConfig
102
+ };
103
+
104
+ export { openaiProvider, searchOpenAI, validateOpenAIConfig };
105
+ //# sourceMappingURL=chunk-VD74IPKB.js.map
106
+ //# sourceMappingURL=chunk-VD74IPKB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/tools/webSearch/providers/openai.ts"],"names":[],"mappings":"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","file":"chunk-VD74IPKB.js","sourcesContent":["/**\n * OpenAI Web Search Provider\n *\n * Uses OpenAI's built-in web_search tool via the Responses API.\n * No third-party API key required - uses your OpenAI API key.\n *\n * @see https://platform.openai.com/docs/guides/tools-web-search\n */\n\nimport type {\n WebSearchConfig,\n WebSearchParams,\n WebSearchResponse,\n WebSearchProviderInterface,\n} from \"../types\";\n\n/**\n * Validate OpenAI native search configuration\n */\nexport function validateOpenAIConfig(config: WebSearchConfig): void {\n if (!config.apiKey) {\n throw new Error(\n \"OpenAI API key is required for native web search. \" +\n \"Pass apiKey or set OPENAI_API_KEY environment variable.\",\n );\n }\n}\n\n/**\n * Search using OpenAI's native web_search tool (Responses API)\n */\nexport async function searchOpenAI(\n params: WebSearchParams,\n config: WebSearchConfig,\n): Promise<WebSearchResponse> {\n validateOpenAIConfig(config);\n\n const startTime = Date.now();\n const apiKey = config.apiKey || process.env.OPENAI_API_KEY;\n\n // Build tools array with web_search\n const tools: Array<Record<string, unknown>> = [\n {\n type: \"web_search\",\n // Domain filtering if provided\n ...(config.includeDomains?.length && {\n filters: {\n domains: config.includeDomains,\n },\n }),\n },\n ];\n\n // Call OpenAI Responses API\n const response = await fetch(\"https://api.openai.com/v1/responses\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: \"gpt-4o\", // Use GPT-4o for web search\n tools,\n input: params.query,\n }),\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 console.error(\n \"[OpenAI Native Search] API error:\",\n response.status,\n errorText,\n );\n throw new Error(\n `OpenAI Responses API error (${response.status}): ${errorText}`,\n );\n }\n\n const data = await response.json();\n const searchTime = Date.now() - startTime;\n\n // Extract answer text and annotations from the message output\n let outputText = \"\";\n const sources: Array<{ url: string; title: string }> = [];\n\n if (data.output && Array.isArray(data.output)) {\n for (const item of data.output) {\n // Find the message with content\n if (item.type === \"message\" && item.content) {\n for (const contentPart of item.content) {\n // Extract text\n if (contentPart.type === \"output_text\" && contentPart.text) {\n outputText = contentPart.text;\n }\n\n // Extract sources from annotations (url_citation)\n if (\n contentPart.annotations &&\n Array.isArray(contentPart.annotations)\n ) {\n for (const annotation of contentPart.annotations) {\n if (annotation.type === \"url_citation\" && annotation.url) {\n // Avoid duplicates\n if (!sources.find((s) => s.url === annotation.url)) {\n sources.push({\n url: annotation.url,\n title: annotation.title || extractDomain(annotation.url),\n });\n }\n }\n }\n }\n }\n }\n }\n }\n\n return {\n query: params.query,\n answer: outputText,\n results: sources\n .slice(0, params.maxResults ?? config.maxResults ?? 5)\n .map((source, i) => ({\n title: source.title,\n url: source.url,\n content: \"\", // OpenAI returns answer with inline citations, not separate snippets\n score: 1 - i * 0.1,\n domain: extractDomain(source.url),\n })),\n provider: \"openai\",\n totalResults: sources.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 * OpenAI native search provider implementation\n */\nexport const openaiProvider: WebSearchProviderInterface = {\n search: searchOpenAI,\n validateConfig: validateOpenAIConfig,\n};\n"]}
@@ -0,0 +1,87 @@
1
+ 'use strict';
2
+
3
+ // src/core/tools/webSearch/providers/brave.ts
4
+ var BRAVE_API_URL = "https://api.search.brave.com/res/v1/web/search";
5
+ function validateBraveConfig(config) {
6
+ if (!config.apiKey) {
7
+ throw new Error(
8
+ "Brave Search API key is required. Get one at https://brave.com/search/api/"
9
+ );
10
+ }
11
+ }
12
+ async function searchBrave(params, config) {
13
+ validateBraveConfig(config);
14
+ const startTime = Date.now();
15
+ const searchParams = new URLSearchParams({
16
+ q: params.query,
17
+ count: String(params.maxResults ?? config.maxResults ?? 5)
18
+ });
19
+ if (config.country) {
20
+ searchParams.set("country", config.country);
21
+ }
22
+ if (config.language) {
23
+ searchParams.set("search_lang", config.language);
24
+ }
25
+ const url = `${BRAVE_API_URL}?${searchParams.toString()}`;
26
+ const response = await fetch(url, {
27
+ method: "GET",
28
+ headers: {
29
+ Accept: "application/json",
30
+ "Accept-Encoding": "gzip",
31
+ "X-Subscription-Token": config.apiKey
32
+ },
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(
38
+ `Brave Search API error (${response.status}): ${errorText}`
39
+ );
40
+ }
41
+ const data = await response.json();
42
+ const searchTime = Date.now() - startTime;
43
+ let results = data.web?.results || [];
44
+ if (config.includeDomains?.length) {
45
+ results = results.filter(
46
+ (r) => config.includeDomains.some((domain) => r.url.includes(domain))
47
+ );
48
+ }
49
+ if (config.excludeDomains?.length) {
50
+ results = results.filter(
51
+ (r) => !config.excludeDomains.some((domain) => r.url.includes(domain))
52
+ );
53
+ }
54
+ const answer = data.infobox?.description;
55
+ return {
56
+ query: params.query,
57
+ answer,
58
+ results: results.map((result) => ({
59
+ title: result.title,
60
+ url: result.url,
61
+ content: result.description,
62
+ publishedDate: result.page_age,
63
+ image: result.thumbnail?.src,
64
+ domain: extractDomain(result.url)
65
+ })),
66
+ provider: "brave",
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 braveProvider = {
79
+ search: searchBrave,
80
+ validateConfig: validateBraveConfig
81
+ };
82
+
83
+ exports.braveProvider = braveProvider;
84
+ exports.searchBrave = searchBrave;
85
+ exports.validateBraveConfig = validateBraveConfig;
86
+ //# sourceMappingURL=chunk-W73FBYIH.cjs.map
87
+ //# sourceMappingURL=chunk-W73FBYIH.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/tools/webSearch/providers/brave.ts"],"names":[],"mappings":"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","file":"chunk-W73FBYIH.cjs","sourcesContent":["/**\n * Brave Search Provider\n *\n * Brave Search is a privacy-focused search engine with its own index.\n * Provides independent search results without tracking.\n *\n * @see https://brave.com/search/api/\n */\n\nimport type {\n WebSearchConfig,\n WebSearchParams,\n WebSearchResponse,\n BraveApiResponse,\n WebSearchProviderInterface,\n} from \"../types\";\n\nconst BRAVE_API_URL = \"https://api.search.brave.com/res/v1/web/search\";\n\n/**\n * Validate Brave configuration\n */\nexport function validateBraveConfig(config: WebSearchConfig): void {\n if (!config.apiKey) {\n throw new Error(\n \"Brave Search API key is required. Get one at https://brave.com/search/api/\",\n );\n }\n}\n\n/**\n * Search using Brave Search API\n */\nexport async function searchBrave(\n params: WebSearchParams,\n config: WebSearchConfig,\n): Promise<WebSearchResponse> {\n validateBraveConfig(config);\n\n const startTime = Date.now();\n\n const searchParams = new URLSearchParams({\n q: params.query,\n count: String(params.maxResults ?? config.maxResults ?? 5),\n });\n\n // Add locale settings\n if (config.country) {\n searchParams.set(\"country\", config.country);\n }\n if (config.language) {\n searchParams.set(\"search_lang\", config.language);\n }\n\n const url = `${BRAVE_API_URL}?${searchParams.toString()}`;\n\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n Accept: \"application/json\",\n \"Accept-Encoding\": \"gzip\",\n \"X-Subscription-Token\": config.apiKey!,\n },\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 `Brave Search API error (${response.status}): ${errorText}`,\n );\n }\n\n const data: BraveApiResponse = await response.json();\n const searchTime = Date.now() - startTime;\n\n // Filter by domains if specified\n let results = data.web?.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 // Extract answer from infobox if available\n const answer = data.infobox?.description;\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.description,\n publishedDate: result.page_age,\n image: result.thumbnail?.src,\n domain: extractDomain(result.url),\n })),\n provider: \"brave\",\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 * Brave provider implementation\n */\nexport const braveProvider: WebSearchProviderInterface = {\n search: searchBrave,\n validateConfig: validateBraveConfig,\n};\n"]}
@@ -0,0 +1,93 @@
1
+ // src/core/tools/webSearch/index.ts
2
+ var providerLoaders = {
3
+ openai: () => import('./openai-7W2PCNW5.js').then((m) => m.openaiProvider),
4
+ google: () => import('./google-CTEK6SV2.js').then((m) => m.googleProvider),
5
+ anthropic: () => import('./anthropic-6F5GRE3B.js').then((m) => m.anthropicProvider),
6
+ tavily: () => import('./tavily-CIWAAZPH.js').then((m) => m.tavilyProvider),
7
+ serper: () => import('./serper-3JYJHJX6.js').then((m) => m.serperProvider),
8
+ brave: () => import('./brave-XSASGGH2.js').then((m) => m.braveProvider),
9
+ searxng: () => import('./searxng-AXLVGY7Z.js').then((m) => m.searxngProvider),
10
+ exa: () => import('./exa-NNVPBC2M.js').then((m) => m.exaProvider)
11
+ };
12
+ var loadedProviders = /* @__PURE__ */ new Map();
13
+ async function getProvider(name) {
14
+ const cached = loadedProviders.get(name);
15
+ if (cached) {
16
+ return cached;
17
+ }
18
+ const loader = providerLoaders[name];
19
+ if (!loader) {
20
+ throw new Error(
21
+ `Unknown search provider: ${name}. Available providers: ${Object.keys(providerLoaders).join(", ")}`
22
+ );
23
+ }
24
+ const provider = await loader();
25
+ const resolvedProvider = "default" in provider ? provider.default : provider;
26
+ loadedProviders.set(name, resolvedProvider);
27
+ return resolvedProvider;
28
+ }
29
+ function getAvailableProviders() {
30
+ return Object.keys(providerLoaders);
31
+ }
32
+ function isProviderInterface(provider) {
33
+ return typeof provider === "object" && "search" in provider;
34
+ }
35
+ async function executeWebSearch(params, config) {
36
+ const provider = isProviderInterface(config.provider) ? config.provider : await getProvider(config.provider);
37
+ const providerName = isProviderInterface(config.provider) ? "custom" : config.provider;
38
+ const resolvedConfig = {
39
+ ...config,
40
+ provider: providerName
41
+ };
42
+ if (provider.validateConfig) {
43
+ provider.validateConfig(resolvedConfig);
44
+ }
45
+ return provider.search(params, resolvedConfig);
46
+ }
47
+ function formatSearchResultsForAI(response, options) {
48
+ const {
49
+ includeUrls = true,
50
+ includeScores = false,
51
+ maxContentLength = 200
52
+ } = options || {};
53
+ const lines = [];
54
+ if (response.answer) {
55
+ lines.push(`Answer: ${response.answer}`);
56
+ lines.push("");
57
+ }
58
+ lines.push(`Search results for "${response.query}":`);
59
+ lines.push("");
60
+ response.results.forEach((result, index) => {
61
+ const num = index + 1;
62
+ let content = result.content;
63
+ if (maxContentLength && content.length > maxContentLength) {
64
+ content = content.slice(0, maxContentLength) + "...";
65
+ }
66
+ lines.push(`${num}. ${result.title}`);
67
+ if (includeUrls) {
68
+ lines.push(` URL: ${result.url}`);
69
+ }
70
+ lines.push(` ${content}`);
71
+ if (includeScores && result.score !== void 0) {
72
+ lines.push(` Relevance: ${(result.score * 100).toFixed(1)}%`);
73
+ }
74
+ lines.push("");
75
+ });
76
+ return lines.join("\n");
77
+ }
78
+ function summarizeSearchResults(response) {
79
+ const count = response.results.length;
80
+ const sources = response.results.slice(0, 3).map((r) => r.domain || new URL(r.url).hostname).join(", ");
81
+ let summary = `Found ${count} result${count !== 1 ? "s" : ""}`;
82
+ if (sources) {
83
+ summary += ` from ${sources}`;
84
+ }
85
+ if (response.searchTime) {
86
+ summary += ` (${response.searchTime}ms)`;
87
+ }
88
+ return summary;
89
+ }
90
+
91
+ export { executeWebSearch, formatSearchResultsForAI, getAvailableProviders, getProvider, summarizeSearchResults };
92
+ //# sourceMappingURL=chunk-XGITAEXU.js.map
93
+ //# sourceMappingURL=chunk-XGITAEXU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/tools/webSearch/index.ts"],"names":[],"mappings":"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","file":"chunk-XGITAEXU.js","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,96 @@
1
+ 'use strict';
2
+
3
+ // src/core/tools/webSearch/providers/google.ts
4
+ var GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models";
5
+ function validateGoogleConfig(config) {
6
+ if (!config.apiKey) {
7
+ throw new Error(
8
+ "Google API key is required for native web search. Pass apiKey or set GOOGLE_API_KEY/GEMINI_API_KEY environment variable."
9
+ );
10
+ }
11
+ }
12
+ async function searchGoogle(params, config) {
13
+ validateGoogleConfig(config);
14
+ const startTime = Date.now();
15
+ const apiKey = config.apiKey || process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY;
16
+ const model = "gemini-2.0-flash";
17
+ const url = `${GEMINI_API_URL}/${model}:generateContent?key=${apiKey}`;
18
+ const requestBody = {
19
+ contents: [
20
+ {
21
+ parts: [
22
+ {
23
+ text: params.query
24
+ }
25
+ ]
26
+ }
27
+ ],
28
+ tools: [
29
+ {
30
+ google_search: {}
31
+ // Enable Google Search grounding
32
+ }
33
+ ],
34
+ // Generation config
35
+ generationConfig: {
36
+ temperature: 0.7,
37
+ maxOutputTokens: 1024
38
+ }
39
+ };
40
+ const response = await fetch(url, {
41
+ method: "POST",
42
+ headers: {
43
+ "Content-Type": "application/json"
44
+ },
45
+ body: JSON.stringify(requestBody),
46
+ signal: config.timeout ? AbortSignal.timeout(config.timeout) : void 0
47
+ });
48
+ if (!response.ok) {
49
+ const errorText = await response.text().catch(() => "Unknown error");
50
+ throw new Error(
51
+ `Google Gemini API error (${response.status}): ${errorText}`
52
+ );
53
+ }
54
+ const data = await response.json();
55
+ const searchTime = Date.now() - startTime;
56
+ const candidates = data.candidates || [];
57
+ const content = candidates[0]?.content;
58
+ const textParts = content?.parts?.filter((p) => p.text) || [];
59
+ const generatedText = textParts.map((p) => p.text).join("\n");
60
+ const groundingMetadata = candidates[0]?.groundingMetadata;
61
+ const groundingChunks = groundingMetadata?.groundingChunks || [];
62
+ groundingMetadata?.searchEntryPoint;
63
+ const results = groundingChunks.filter((chunk) => chunk.web).slice(0, params.maxResults ?? config.maxResults ?? 5).map((chunk, i) => ({
64
+ title: chunk.web.title || extractDomain(chunk.web.uri),
65
+ url: chunk.web.uri,
66
+ content: "",
67
+ // Google doesn't provide snippets in grounding response
68
+ score: 1 - i * 0.1,
69
+ domain: extractDomain(chunk.web.uri)
70
+ }));
71
+ return {
72
+ query: params.query,
73
+ answer: generatedText,
74
+ results,
75
+ provider: "google",
76
+ totalResults: groundingChunks.length,
77
+ searchTime
78
+ };
79
+ }
80
+ function extractDomain(url) {
81
+ try {
82
+ return new URL(url).hostname.replace("www.", "");
83
+ } catch {
84
+ return url;
85
+ }
86
+ }
87
+ var googleProvider = {
88
+ search: searchGoogle,
89
+ validateConfig: validateGoogleConfig
90
+ };
91
+
92
+ exports.googleProvider = googleProvider;
93
+ exports.searchGoogle = searchGoogle;
94
+ exports.validateGoogleConfig = validateGoogleConfig;
95
+ //# sourceMappingURL=chunk-XWOHNY3F.cjs.map
96
+ //# sourceMappingURL=chunk-XWOHNY3F.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/tools/webSearch/providers/google.ts"],"names":[],"mappings":"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","file":"chunk-XWOHNY3F.cjs","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,79 @@
1
+ import { tool, failure } from './chunk-BKO7DSPU.js';
2
+ import { formatSearchResultsForAI, executeWebSearch, summarizeSearchResults } from './chunk-XGITAEXU.js';
3
+
4
+ // src/core/tools/builtin/webSearch.ts
5
+ var webSearchTool = tool({
6
+ description: `Search the web for current information. Use this when the user asks about:
7
+ - Recent events, news, or current affairs
8
+ - Real-time data (prices, weather, stocks, sports scores)
9
+ - Information that might have changed after your training cutoff
10
+ - Facts that need verification with current sources
11
+ - Research topics that require up-to-date information`,
12
+ location: "server",
13
+ // Runs on server to protect API keys
14
+ title: (args) => `Searching for "${args.query}"`,
15
+ executingTitle: (args) => `Searching the web for "${args.query}"...`,
16
+ completedTitle: (args) => `Found results for "${args.query}"`,
17
+ inputSchema: {
18
+ type: "object",
19
+ properties: {
20
+ query: {
21
+ type: "string",
22
+ description: "The search query to find relevant information"
23
+ },
24
+ maxResults: {
25
+ type: "number",
26
+ description: "Maximum number of results to return (default: 5, max: 10)",
27
+ minimum: 1,
28
+ maximum: 10
29
+ },
30
+ searchDepth: {
31
+ type: "string",
32
+ enum: ["basic", "advanced"],
33
+ description: "Search depth - 'advanced' provides more thorough results but may be slower"
34
+ }
35
+ },
36
+ required: ["query"]
37
+ },
38
+ needsApproval: false,
39
+ // No user data exposed, just searching
40
+ // Control what AI sees from results
41
+ aiResponseMode: "full",
42
+ aiContext: (result, args) => {
43
+ if (!result.success) return `Search failed: ${result.error}`;
44
+ const data = result.data;
45
+ return formatSearchResultsForAI(data);
46
+ }
47
+ });
48
+ function createWebSearchTool(config) {
49
+ return {
50
+ name: "web_search",
51
+ ...webSearchTool,
52
+ handler: async (params) => {
53
+ try {
54
+ const response = await executeWebSearch(
55
+ {
56
+ query: params.query,
57
+ maxResults: params.maxResults ?? config.maxResults ?? 5,
58
+ searchDepth: params.searchDepth ?? config.searchDepth ?? "basic"
59
+ },
60
+ config
61
+ );
62
+ const aiContext = formatSearchResultsForAI(response);
63
+ return {
64
+ success: true,
65
+ message: summarizeSearchResults(response),
66
+ data: response,
67
+ _aiContext: aiContext
68
+ };
69
+ } catch (error) {
70
+ const errorMessage = error instanceof Error ? error.message : "Web search failed";
71
+ return failure(errorMessage);
72
+ }
73
+ }
74
+ };
75
+ }
76
+
77
+ export { createWebSearchTool, webSearchTool };
78
+ //# sourceMappingURL=chunk-ZPYQDMUX.js.map
79
+ //# sourceMappingURL=chunk-ZPYQDMUX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/tools/builtin/webSearch.ts"],"names":[],"mappings":";;;;AAoDO,IAAM,gBAAgB,IAAA,CAAsB;AAAA,EACjD,WAAA,EAAa,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qDAAA,CAAA;AAAA,EAOb,QAAA,EAAU,QAAA;AAAA;AAAA,EAEV,KAAA,EAAO,CAAC,IAAA,KAAS,CAAA,eAAA,EAAkB,KAAK,KAAK,CAAA,CAAA,CAAA;AAAA,EAC7C,cAAA,EAAgB,CAAC,IAAA,KAAS,CAAA,uBAAA,EAA0B,KAAK,KAAK,CAAA,IAAA,CAAA;AAAA,EAC9D,cAAA,EAAgB,CAAC,IAAA,KAAS,CAAA,mBAAA,EAAsB,KAAK,KAAK,CAAA,CAAA,CAAA;AAAA,EAE1D,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,QAAA;AAAA,IACN,UAAA,EAAY;AAAA,MACV,KAAA,EAAO;AAAA,QACL,IAAA,EAAM,QAAA;AAAA,QACN,WAAA,EAAa;AAAA,OACf;AAAA,MACA,UAAA,EAAY;AAAA,QACV,IAAA,EAAM,QAAA;AAAA,QACN,WAAA,EACE,2DAAA;AAAA,QACF,OAAA,EAAS,CAAA;AAAA,QACT,OAAA,EAAS;AAAA,OACX;AAAA,MACA,WAAA,EAAa;AAAA,QACX,IAAA,EAAM,QAAA;AAAA,QACN,IAAA,EAAM,CAAC,OAAA,EAAS,UAAU,CAAA;AAAA,QAC1B,WAAA,EACE;AAAA;AACJ,KACF;AAAA,IACA,QAAA,EAAU,CAAC,OAAO;AAAA,GACpB;AAAA,EAEA,aAAA,EAAe,KAAA;AAAA;AAAA;AAAA,EAGf,cAAA,EAAgB,MAAA;AAAA,EAChB,SAAA,EAAW,CAAC,MAAA,EAAQ,IAAA,KAAS;AAC3B,IAAA,IAAI,CAAC,MAAA,CAAO,OAAA,EAAS,OAAO,CAAA,eAAA,EAAkB,OAAO,KAAK,CAAA,CAAA;AAC1D,IAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AACpB,IAAA,OAAO,yBAAyB,IAAI,CAAA;AAAA,EACtC;AACF,CAAC;AAoEM,SAAS,oBACd,MAAA,EACiC;AACjC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,YAAA;AAAA,IACN,GAAG,aAAA;AAAA,IACH,OAAA,EAAS,OAAO,MAAA,KAA4B;AAC1C,MAAA,IAAI;AACF,QAAA,MAAM,WAAW,MAAM,gBAAA;AAAA,UACrB;AAAA,YACE,OAAO,MAAA,CAAO,KAAA;AAAA,YACd,UAAA,EAAY,MAAA,CAAO,UAAA,IAAc,MAAA,CAAO,UAAA,IAAc,CAAA;AAAA,YACtD,WAAA,EAAa,MAAA,CAAO,WAAA,IAAe,MAAA,CAAO,WAAA,IAAe;AAAA,WAC3D;AAAA,UACA;AAAA,SACF;AAGA,QAAA,MAAM,SAAA,GAAY,yBAAyB,QAAQ,CAAA;AAEnD,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,IAAA;AAAA,UACT,OAAA,EAAS,uBAAuB,QAAQ,CAAA;AAAA,UACxC,IAAA,EAAM,QAAA;AAAA,UACN,UAAA,EAAY;AAAA,SACd;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,MAAM,YAAA,GACJ,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,mBAAA;AAC3C,QAAA,OAAO,QAAQ,YAAY,CAAA;AAAA,MAC7B;AAAA,IACF;AAAA,GACF;AACF","file":"chunk-ZPYQDMUX.js","sourcesContent":["/**\n * Built-in Web Search Tool\n *\n * A pre-configured tool for searching the web with multiple provider support.\n * Runs on the server to protect API keys.\n *\n * Supports tree-shaking - import providers directly for smaller bundles.\n *\n * @example\n * ```typescript\n * // Option 1: String provider (lazy loaded at runtime)\n * import { createWebSearchTool } from '@yourgpt/copilot-sdk';\n * const webSearch = createWebSearchTool({\n * provider: 'tavily',\n * apiKey: process.env.TAVILY_API_KEY,\n * });\n *\n * // Option 2: Direct provider import (best for tree-shaking)\n * import { createWebSearchTool, tavilyProvider } from '@yourgpt/copilot-sdk';\n * const webSearch = createWebSearchTool({\n * provider: tavilyProvider,\n * apiKey: process.env.TAVILY_API_KEY,\n * });\n *\n * // Add to your runtime\n * const runtime = createRuntime({\n * tools: [webSearch],\n * });\n * ```\n */\n\nimport { tool, success, failure } from \"../../types/tools\";\nimport type { ToolDefinition } from \"../../types/tools\";\nimport {\n executeWebSearch,\n formatSearchResultsForAI,\n summarizeSearchResults,\n type WebSearchConfigExtended,\n} from \"../webSearch\";\nimport type {\n WebSearchConfig,\n WebSearchParams,\n WebSearchResponse,\n WebSearchProviderInterface,\n} from \"../webSearch/types\";\n\n/**\n * Base web search tool definition\n *\n * This is the core tool definition. Use `createWebSearchTool()` to create\n * a configured instance with your provider settings.\n */\nexport const webSearchTool = tool<WebSearchParams>({\n description: `Search the web for current information. Use this when the user asks about:\n- Recent events, news, or current affairs\n- Real-time data (prices, weather, stocks, sports scores)\n- Information that might have changed after your training cutoff\n- Facts that need verification with current sources\n- Research topics that require up-to-date information`,\n\n location: \"server\", // Runs on server to protect API keys\n\n title: (args) => `Searching for \"${args.query}\"`,\n executingTitle: (args) => `Searching the web for \"${args.query}\"...`,\n completedTitle: (args) => `Found results for \"${args.query}\"`,\n\n inputSchema: {\n type: \"object\",\n properties: {\n query: {\n type: \"string\",\n description: \"The search query to find relevant information\",\n },\n maxResults: {\n type: \"number\",\n description:\n \"Maximum number of results to return (default: 5, max: 10)\",\n minimum: 1,\n maximum: 10,\n },\n searchDepth: {\n type: \"string\",\n enum: [\"basic\", \"advanced\"],\n description:\n \"Search depth - 'advanced' provides more thorough results but may be slower\",\n },\n },\n required: [\"query\"],\n },\n\n needsApproval: false, // No user data exposed, just searching\n\n // Control what AI sees from results\n aiResponseMode: \"full\",\n aiContext: (result, args) => {\n if (!result.success) return `Search failed: ${result.error}`;\n const data = result.data as WebSearchResponse;\n return formatSearchResultsForAI(data);\n },\n});\n\n/**\n * Create a configured web search tool\n *\n * Supports both string provider names (lazy loaded) and direct provider imports (tree-shakeable).\n *\n * @param config - Web search configuration including provider and API key\n * @returns A configured tool definition ready to use\n *\n * @example\n * ```typescript\n * // ===== BEST FOR TREE-SHAKING: Direct provider import =====\n * import { createWebSearchTool, openaiProvider } from '@yourgpt/copilot-sdk/core';\n *\n * const webSearch = createWebSearchTool({\n * provider: openaiProvider, // Only this provider in bundle\n * apiKey: process.env.OPENAI_API_KEY,\n * });\n *\n * // ===== STRING PROVIDERS (Lazy loaded at runtime) =====\n *\n * // OpenAI (uses your OpenAI API key)\n * const webSearch = createWebSearchTool({\n * provider: 'openai',\n * apiKey: process.env.OPENAI_API_KEY,\n * });\n *\n * // Google (uses your Google/Gemini API key)\n * const webSearch = createWebSearchTool({\n * provider: 'google',\n * apiKey: process.env.GOOGLE_API_KEY,\n * });\n *\n * // Tavily (AI-optimized search with answer generation)\n * const webSearch = createWebSearchTool({\n * provider: 'tavily',\n * apiKey: process.env.TAVILY_API_KEY,\n * includeAnswer: true,\n * maxResults: 5,\n * });\n *\n * // Serper (Google results)\n * const webSearch = createWebSearchTool({\n * provider: 'serper',\n * apiKey: process.env.SERPER_API_KEY,\n * });\n *\n * // Brave Search (privacy-focused)\n * const webSearch = createWebSearchTool({\n * provider: 'brave',\n * apiKey: process.env.BRAVE_API_KEY,\n * });\n *\n * // Self-hosted SearXNG (no API key needed)\n * const webSearch = createWebSearchTool({\n * provider: 'searxng',\n * baseUrl: 'https://your-searxng-instance.com',\n * });\n *\n * // Exa (AI-optimized semantic search)\n * const webSearch = createWebSearchTool({\n * provider: 'exa',\n * apiKey: process.env.EXA_API_KEY,\n * searchDepth: 'advanced',\n * });\n * ```\n */\nexport function createWebSearchTool(\n config: WebSearchConfigExtended,\n): ToolDefinition<WebSearchParams> {\n return {\n name: \"web_search\",\n ...webSearchTool,\n handler: async (params: WebSearchParams) => {\n try {\n const response = await executeWebSearch(\n {\n query: params.query,\n maxResults: params.maxResults ?? config.maxResults ?? 5,\n searchDepth: params.searchDepth ?? config.searchDepth ?? \"basic\",\n },\n config,\n );\n\n // Build the AI context string\n const aiContext = formatSearchResultsForAI(response);\n\n return {\n success: true,\n message: summarizeSearchResults(response),\n data: response,\n _aiContext: aiContext,\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : \"Web search failed\";\n return failure(errorMessage);\n }\n },\n };\n}\n\n/**\n * Utility types for web search tool configuration\n */\nexport type {\n WebSearchConfig,\n WebSearchParams,\n WebSearchResponse,\n WebSearchProviderInterface,\n};\nexport type { WebSearchConfigExtended };\n"]}