@yourgpt/copilot-sdk 2.0.0 → 2.0.2-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/README.md +68 -27
  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-CJ7UWN2Y.js → chunk-3YKHVLNP.js} +397 -7
  19. package/dist/chunk-3YKHVLNP.js.map +1 -0
  20. package/dist/chunk-4WWWMNUA.js +1142 -0
  21. package/dist/chunk-4WWWMNUA.js.map +1 -0
  22. package/dist/chunk-53UGJNHN.js +92 -0
  23. package/dist/chunk-53UGJNHN.js.map +1 -0
  24. package/dist/chunk-6BXQFCK3.js +79 -0
  25. package/dist/chunk-6BXQFCK3.js.map +1 -0
  26. package/dist/chunk-6T5XXJEP.cjs +80 -0
  27. package/dist/chunk-6T5XXJEP.cjs.map +1 -0
  28. package/dist/chunk-7W7QLZNC.js +72 -0
  29. package/dist/chunk-7W7QLZNC.js.map +1 -0
  30. package/dist/chunk-ASV6JLYG.cjs +99 -0
  31. package/dist/chunk-ASV6JLYG.cjs.map +1 -0
  32. package/dist/chunk-CBAHCI4R.cjs +76 -0
  33. package/dist/chunk-CBAHCI4R.cjs.map +1 -0
  34. package/dist/chunk-CEOMTQTP.js +85 -0
  35. package/dist/chunk-CEOMTQTP.js.map +1 -0
  36. package/dist/chunk-DABZYCVX.js +84 -0
  37. package/dist/chunk-DABZYCVX.js.map +1 -0
  38. package/dist/chunk-DGUM43GV.js +10 -0
  39. package/dist/chunk-DGUM43GV.js.map +1 -0
  40. package/dist/{chunk-4PRWNAXQ.cjs → chunk-DUPNYVBP.cjs} +27 -89
  41. package/dist/chunk-DUPNYVBP.cjs.map +1 -0
  42. package/dist/chunk-DVC63PGD.cjs +1160 -0
  43. package/dist/chunk-DVC63PGD.cjs.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-J4OMGO5O.js +66 -0
  49. package/dist/chunk-J4OMGO5O.js.map +1 -0
  50. package/dist/chunk-JEQ2X3Z6.cjs +12 -0
  51. package/dist/chunk-JEQ2X3Z6.cjs.map +1 -0
  52. package/dist/chunk-JO4BHPAD.cjs +40 -0
  53. package/dist/chunk-JO4BHPAD.cjs.map +1 -0
  54. package/dist/chunk-MEBXW75C.cjs +89 -0
  55. package/dist/chunk-MEBXW75C.cjs.map +1 -0
  56. package/dist/chunk-MNDGIW47.js +76 -0
  57. package/dist/chunk-MNDGIW47.js.map +1 -0
  58. package/dist/chunk-PPFHA6IL.js +83 -0
  59. package/dist/chunk-PPFHA6IL.js.map +1 -0
  60. package/dist/{chunk-BLSI67J6.cjs → chunk-RBZXLBGI.cjs} +425 -30
  61. package/dist/chunk-RBZXLBGI.cjs.map +1 -0
  62. package/dist/chunk-RQ74USYU.js +128 -0
  63. package/dist/chunk-RQ74USYU.js.map +1 -0
  64. package/dist/chunk-TX7CGITI.cjs +82 -0
  65. package/dist/chunk-TX7CGITI.cjs.map +1 -0
  66. package/dist/chunk-TXLIY7GF.cjs +132 -0
  67. package/dist/chunk-TXLIY7GF.cjs.map +1 -0
  68. package/dist/chunk-VD74IPKB.js +106 -0
  69. package/dist/chunk-VD74IPKB.js.map +1 -0
  70. package/dist/chunk-W73FBYIH.cjs +87 -0
  71. package/dist/chunk-W73FBYIH.cjs.map +1 -0
  72. package/dist/chunk-W74OTXXX.cjs +73 -0
  73. package/dist/chunk-W74OTXXX.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-JM7PB2LP.js → chunk-Z7PHGSJT.js} +10 -66
  79. package/dist/chunk-Z7PHGSJT.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-DBNh0jhE.d.ts +206 -0
  97. package/dist/index-DOlhSb79.d.cts +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-EiPWA9Ay.d.cts} +34 -367
  196. package/dist/{types-BtAaOV07.d.ts → tools-EiPWA9Ay.d.ts} +34 -367
  197. package/dist/types-B20VCJXL.d.cts +347 -0
  198. package/dist/types-B20VCJXL.d.ts +347 -0
  199. package/dist/types-CKA6U74u.d.cts +441 -0
  200. package/dist/types-DG2ya08y.d.cts +367 -0
  201. package/dist/types-DG2ya08y.d.ts +367 -0
  202. package/dist/types-ZguuKEs_.d.cts +127 -0
  203. package/dist/types-ZguuKEs_.d.ts +127 -0
  204. package/dist/types-iBkPICvQ.d.ts +441 -0
  205. package/dist/ui/index.cjs +1069 -146
  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 +1001 -94
  210. package/dist/ui/index.js.map +1 -1
  211. package/package.json +53 -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,128 @@
1
+ // src/core/tools/webSearch/providers/anthropic.ts
2
+ var ANTHROPIC_API_URL = "https://api.anthropic.com/v1/messages";
3
+ function validateAnthropicConfig(config) {
4
+ if (!config.apiKey) {
5
+ throw new Error(
6
+ "Anthropic API key is required for native web search. Pass apiKey or set ANTHROPIC_API_KEY environment variable."
7
+ );
8
+ }
9
+ }
10
+ async function searchAnthropic(params, config) {
11
+ validateAnthropicConfig(config);
12
+ const startTime = Date.now();
13
+ const apiKey = config.apiKey || process.env.ANTHROPIC_API_KEY;
14
+ const webSearchTool = {
15
+ type: "web_search_20250305",
16
+ // Use stable version
17
+ name: "web_search",
18
+ max_uses: config.maxResults ?? 5
19
+ };
20
+ if (config.includeDomains?.length) {
21
+ webSearchTool.allowed_domains = config.includeDomains;
22
+ }
23
+ if (config.excludeDomains?.length) {
24
+ webSearchTool.blocked_domains = config.excludeDomains;
25
+ }
26
+ if (config.country) {
27
+ webSearchTool.user_location = {
28
+ type: "approximate",
29
+ country: config.country.toUpperCase()
30
+ };
31
+ }
32
+ const response = await fetch(ANTHROPIC_API_URL, {
33
+ method: "POST",
34
+ headers: {
35
+ "Content-Type": "application/json",
36
+ "x-api-key": apiKey,
37
+ "anthropic-version": "2023-06-01"
38
+ },
39
+ body: JSON.stringify({
40
+ model: "claude-sonnet-4-20250514",
41
+ // Use Sonnet 4 for balance of speed/quality
42
+ max_tokens: 2048,
43
+ tools: [webSearchTool],
44
+ messages: [
45
+ {
46
+ role: "user",
47
+ content: params.query
48
+ }
49
+ ]
50
+ }),
51
+ signal: config.timeout ? AbortSignal.timeout(config.timeout) : void 0
52
+ });
53
+ if (!response.ok) {
54
+ const errorText = await response.text().catch(() => "Unknown error");
55
+ console.error(
56
+ "[Anthropic Native Search] API error:",
57
+ response.status,
58
+ errorText
59
+ );
60
+ throw new Error(
61
+ `Anthropic Messages API error (${response.status}): ${errorText}`
62
+ );
63
+ }
64
+ const data = await response.json();
65
+ const searchTime = Date.now() - startTime;
66
+ let outputText = "";
67
+ const sources = [];
68
+ const searchResults = [];
69
+ if (data.content && Array.isArray(data.content)) {
70
+ for (const block of data.content) {
71
+ if (block.type === "text" && block.text) {
72
+ outputText += block.text;
73
+ if (block.citations && Array.isArray(block.citations)) {
74
+ for (const citation of block.citations) {
75
+ if (citation.url && !sources.find((s) => s.url === citation.url)) {
76
+ sources.push({
77
+ url: citation.url,
78
+ title: citation.title || extractDomain(citation.url),
79
+ cited_text: citation.cited_text
80
+ });
81
+ }
82
+ }
83
+ }
84
+ }
85
+ if (block.type === "web_search_tool_result" && block.content) {
86
+ for (const result of block.content) {
87
+ if (result.type === "web_search_result" && result.url) {
88
+ searchResults.push({
89
+ url: result.url,
90
+ title: result.title || extractDomain(result.url),
91
+ page_age: result.page_age
92
+ });
93
+ }
94
+ }
95
+ }
96
+ }
97
+ }
98
+ const finalSources = sources.length > 0 ? sources : searchResults;
99
+ return {
100
+ query: params.query,
101
+ answer: outputText,
102
+ results: finalSources.slice(0, params.maxResults ?? config.maxResults ?? 5).map((source, i) => ({
103
+ title: source.title,
104
+ url: source.url,
105
+ content: "cited_text" in source ? source.cited_text || "" : "",
106
+ score: 1 - i * 0.1,
107
+ domain: extractDomain(source.url)
108
+ })),
109
+ provider: "anthropic",
110
+ totalResults: finalSources.length,
111
+ searchTime
112
+ };
113
+ }
114
+ function extractDomain(url) {
115
+ try {
116
+ return new URL(url).hostname.replace("www.", "");
117
+ } catch {
118
+ return url;
119
+ }
120
+ }
121
+ var anthropicProvider = {
122
+ search: searchAnthropic,
123
+ validateConfig: validateAnthropicConfig
124
+ };
125
+
126
+ export { anthropicProvider, searchAnthropic, validateAnthropicConfig };
127
+ //# sourceMappingURL=chunk-RQ74USYU.js.map
128
+ //# sourceMappingURL=chunk-RQ74USYU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/tools/webSearch/providers/anthropic.ts"],"names":[],"mappings":"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","file":"chunk-RQ74USYU.js","sourcesContent":["/**\n * Anthropic Web Search Provider\n *\n * Uses Anthropic's built-in web_search tool via the Messages API.\n * Returns reliable citations with cited_text, url, and title.\n *\n * @see https://docs.anthropic.com/en/docs/build-with-claude/tool-use/web-search-tool\n */\n\nimport type {\n WebSearchConfig,\n WebSearchParams,\n WebSearchResponse,\n WebSearchProviderInterface,\n} from \"../types\";\n\nconst ANTHROPIC_API_URL = \"https://api.anthropic.com/v1/messages\";\n\n/**\n * Validate Anthropic native search configuration\n */\nexport function validateAnthropicConfig(config: WebSearchConfig): void {\n if (!config.apiKey) {\n throw new Error(\n \"Anthropic API key is required for native web search. \" +\n \"Pass apiKey or set ANTHROPIC_API_KEY environment variable.\",\n );\n }\n}\n\n// Type definitions for Anthropic response\ninterface AnthropicWebSearchResult {\n type: \"web_search_result\";\n url: string;\n title: string;\n encrypted_content?: string;\n page_age?: string;\n}\n\ninterface AnthropicCitation {\n type: \"web_search_result_location\";\n url: string;\n title: string;\n encrypted_index?: string;\n cited_text?: string;\n}\n\ninterface AnthropicContentBlock {\n type: string;\n text?: string;\n tool_use_id?: string;\n content?: AnthropicWebSearchResult[];\n citations?: AnthropicCitation[];\n}\n\ninterface AnthropicMessagesResponse {\n id: string;\n content: AnthropicContentBlock[];\n usage?: {\n input_tokens: number;\n output_tokens: number;\n server_tool_use?: {\n web_search_requests?: number;\n };\n };\n}\n\n/**\n * Search using Anthropic's native web_search tool\n */\nexport async function searchAnthropic(\n params: WebSearchParams,\n config: WebSearchConfig,\n): Promise<WebSearchResponse> {\n validateAnthropicConfig(config);\n\n const startTime = Date.now();\n const apiKey = config.apiKey || process.env.ANTHROPIC_API_KEY;\n\n // Build web search tool configuration\n const webSearchTool: Record<string, unknown> = {\n type: \"web_search_20250305\", // Use stable version\n name: \"web_search\",\n max_uses: config.maxResults ?? 5,\n };\n\n // Add domain filtering if provided\n if (config.includeDomains?.length) {\n webSearchTool.allowed_domains = config.includeDomains;\n }\n if (config.excludeDomains?.length) {\n webSearchTool.blocked_domains = config.excludeDomains;\n }\n\n // Add user location if country is set\n if (config.country) {\n webSearchTool.user_location = {\n type: \"approximate\",\n country: config.country.toUpperCase(),\n };\n }\n\n // Call Anthropic Messages API\n const response = await fetch(ANTHROPIC_API_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": apiKey!,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify({\n model: \"claude-sonnet-4-20250514\", // Use Sonnet 4 for balance of speed/quality\n max_tokens: 2048,\n tools: [webSearchTool],\n messages: [\n {\n role: \"user\",\n content: params.query,\n },\n ],\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 \"[Anthropic Native Search] API error:\",\n response.status,\n errorText,\n );\n throw new Error(\n `Anthropic Messages API error (${response.status}): ${errorText}`,\n );\n }\n\n const data: AnthropicMessagesResponse = await response.json();\n const searchTime = Date.now() - startTime;\n\n // Extract answer text and citations\n let outputText = \"\";\n const sources: Array<{ url: string; title: string; cited_text?: string }> =\n [];\n const searchResults: Array<{\n url: string;\n title: string;\n page_age?: string;\n }> = [];\n\n if (data.content && Array.isArray(data.content)) {\n for (const block of data.content) {\n // Extract text blocks\n if (block.type === \"text\" && block.text) {\n outputText += block.text;\n\n // Extract citations from text blocks\n if (block.citations && Array.isArray(block.citations)) {\n for (const citation of block.citations) {\n if (citation.url && !sources.find((s) => s.url === citation.url)) {\n sources.push({\n url: citation.url,\n title: citation.title || extractDomain(citation.url),\n cited_text: citation.cited_text,\n });\n }\n }\n }\n }\n\n // Extract search results from web_search_tool_result\n if (block.type === \"web_search_tool_result\" && block.content) {\n for (const result of block.content) {\n if (result.type === \"web_search_result\" && result.url) {\n searchResults.push({\n url: result.url,\n title: result.title || extractDomain(result.url),\n page_age: result.page_age,\n });\n }\n }\n }\n }\n }\n\n // Prefer citations (have cited_text) over raw search results\n const finalSources = sources.length > 0 ? sources : searchResults;\n\n return {\n query: params.query,\n answer: outputText,\n results: finalSources\n .slice(0, params.maxResults ?? config.maxResults ?? 5)\n .map((source, i) => ({\n title: source.title,\n url: source.url,\n content: \"cited_text\" in source ? source.cited_text || \"\" : \"\",\n score: 1 - i * 0.1,\n domain: extractDomain(source.url),\n })),\n provider: \"anthropic\",\n totalResults: finalSources.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 * Anthropic native search provider implementation\n */\nexport const anthropicProvider: WebSearchProviderInterface = {\n search: searchAnthropic,\n validateConfig: validateAnthropicConfig,\n};\n"]}
@@ -0,0 +1,82 @@
1
+ 'use strict';
2
+
3
+ var chunkW74OTXXX_cjs = require('./chunk-W74OTXXX.cjs');
4
+ var chunkASV6JLYG_cjs = require('./chunk-ASV6JLYG.cjs');
5
+
6
+ // src/core/tools/builtin/webSearch.ts
7
+ var webSearchTool = chunkW74OTXXX_cjs.tool({
8
+ description: `Search the web for current information. Use this when the user asks about:
9
+ - Recent events, news, or current affairs
10
+ - Real-time data (prices, weather, stocks, sports scores)
11
+ - Information that might have changed after your training cutoff
12
+ - Facts that need verification with current sources
13
+ - Research topics that require up-to-date information`,
14
+ location: "server",
15
+ // Runs on server to protect API keys
16
+ title: (args) => `Searching for "${args.query}"`,
17
+ executingTitle: (args) => `Searching the web for "${args.query}"...`,
18
+ completedTitle: (args) => `Found results for "${args.query}"`,
19
+ inputSchema: {
20
+ type: "object",
21
+ properties: {
22
+ query: {
23
+ type: "string",
24
+ description: "The search query to find relevant information"
25
+ },
26
+ maxResults: {
27
+ type: "number",
28
+ description: "Maximum number of results to return (default: 5, max: 10)",
29
+ minimum: 1,
30
+ maximum: 10
31
+ },
32
+ searchDepth: {
33
+ type: "string",
34
+ enum: ["basic", "advanced"],
35
+ description: "Search depth - 'advanced' provides more thorough results but may be slower"
36
+ }
37
+ },
38
+ required: ["query"]
39
+ },
40
+ needsApproval: false,
41
+ // No user data exposed, just searching
42
+ // Control what AI sees from results
43
+ aiResponseMode: "full",
44
+ aiContext: (result, args) => {
45
+ if (!result.success) return `Search failed: ${result.error}`;
46
+ const data = result.data;
47
+ return chunkASV6JLYG_cjs.formatSearchResultsForAI(data);
48
+ }
49
+ });
50
+ function createWebSearchTool(config) {
51
+ return {
52
+ name: "web_search",
53
+ ...webSearchTool,
54
+ handler: async (params) => {
55
+ try {
56
+ const response = await chunkASV6JLYG_cjs.executeWebSearch(
57
+ {
58
+ query: params.query,
59
+ maxResults: params.maxResults ?? config.maxResults ?? 5,
60
+ searchDepth: params.searchDepth ?? config.searchDepth ?? "basic"
61
+ },
62
+ config
63
+ );
64
+ const aiContext = chunkASV6JLYG_cjs.formatSearchResultsForAI(response);
65
+ return {
66
+ success: true,
67
+ message: chunkASV6JLYG_cjs.summarizeSearchResults(response),
68
+ data: response,
69
+ _aiContext: aiContext
70
+ };
71
+ } catch (error) {
72
+ const errorMessage = error instanceof Error ? error.message : "Web search failed";
73
+ return chunkW74OTXXX_cjs.failure(errorMessage);
74
+ }
75
+ }
76
+ };
77
+ }
78
+
79
+ exports.createWebSearchTool = createWebSearchTool;
80
+ exports.webSearchTool = webSearchTool;
81
+ //# sourceMappingURL=chunk-TX7CGITI.cjs.map
82
+ //# sourceMappingURL=chunk-TX7CGITI.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/tools/builtin/webSearch.ts"],"names":["tool","formatSearchResultsForAI","executeWebSearch","summarizeSearchResults","failure"],"mappings":";;;;;;AAoDO,IAAM,gBAAgBA,sBAAA,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,OAAOC,2CAAyB,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,MAAMC,kCAAA;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,GAAYD,2CAAyB,QAAQ,CAAA;AAEnD,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,IAAA;AAAA,UACT,OAAA,EAASE,yCAAuB,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,OAAOC,0BAAQ,YAAY,CAAA;AAAA,MAC7B;AAAA,IACF;AAAA,GACF;AACF","file":"chunk-TX7CGITI.cjs","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"]}
@@ -0,0 +1,132 @@
1
+ 'use strict';
2
+
3
+ // src/core/tools/webSearch/providers/anthropic.ts
4
+ var ANTHROPIC_API_URL = "https://api.anthropic.com/v1/messages";
5
+ function validateAnthropicConfig(config) {
6
+ if (!config.apiKey) {
7
+ throw new Error(
8
+ "Anthropic API key is required for native web search. Pass apiKey or set ANTHROPIC_API_KEY environment variable."
9
+ );
10
+ }
11
+ }
12
+ async function searchAnthropic(params, config) {
13
+ validateAnthropicConfig(config);
14
+ const startTime = Date.now();
15
+ const apiKey = config.apiKey || process.env.ANTHROPIC_API_KEY;
16
+ const webSearchTool = {
17
+ type: "web_search_20250305",
18
+ // Use stable version
19
+ name: "web_search",
20
+ max_uses: config.maxResults ?? 5
21
+ };
22
+ if (config.includeDomains?.length) {
23
+ webSearchTool.allowed_domains = config.includeDomains;
24
+ }
25
+ if (config.excludeDomains?.length) {
26
+ webSearchTool.blocked_domains = config.excludeDomains;
27
+ }
28
+ if (config.country) {
29
+ webSearchTool.user_location = {
30
+ type: "approximate",
31
+ country: config.country.toUpperCase()
32
+ };
33
+ }
34
+ const response = await fetch(ANTHROPIC_API_URL, {
35
+ method: "POST",
36
+ headers: {
37
+ "Content-Type": "application/json",
38
+ "x-api-key": apiKey,
39
+ "anthropic-version": "2023-06-01"
40
+ },
41
+ body: JSON.stringify({
42
+ model: "claude-sonnet-4-20250514",
43
+ // Use Sonnet 4 for balance of speed/quality
44
+ max_tokens: 2048,
45
+ tools: [webSearchTool],
46
+ messages: [
47
+ {
48
+ role: "user",
49
+ content: params.query
50
+ }
51
+ ]
52
+ }),
53
+ signal: config.timeout ? AbortSignal.timeout(config.timeout) : void 0
54
+ });
55
+ if (!response.ok) {
56
+ const errorText = await response.text().catch(() => "Unknown error");
57
+ console.error(
58
+ "[Anthropic Native Search] API error:",
59
+ response.status,
60
+ errorText
61
+ );
62
+ throw new Error(
63
+ `Anthropic Messages API error (${response.status}): ${errorText}`
64
+ );
65
+ }
66
+ const data = await response.json();
67
+ const searchTime = Date.now() - startTime;
68
+ let outputText = "";
69
+ const sources = [];
70
+ const searchResults = [];
71
+ if (data.content && Array.isArray(data.content)) {
72
+ for (const block of data.content) {
73
+ if (block.type === "text" && block.text) {
74
+ outputText += block.text;
75
+ if (block.citations && Array.isArray(block.citations)) {
76
+ for (const citation of block.citations) {
77
+ if (citation.url && !sources.find((s) => s.url === citation.url)) {
78
+ sources.push({
79
+ url: citation.url,
80
+ title: citation.title || extractDomain(citation.url),
81
+ cited_text: citation.cited_text
82
+ });
83
+ }
84
+ }
85
+ }
86
+ }
87
+ if (block.type === "web_search_tool_result" && block.content) {
88
+ for (const result of block.content) {
89
+ if (result.type === "web_search_result" && result.url) {
90
+ searchResults.push({
91
+ url: result.url,
92
+ title: result.title || extractDomain(result.url),
93
+ page_age: result.page_age
94
+ });
95
+ }
96
+ }
97
+ }
98
+ }
99
+ }
100
+ const finalSources = sources.length > 0 ? sources : searchResults;
101
+ return {
102
+ query: params.query,
103
+ answer: outputText,
104
+ results: finalSources.slice(0, params.maxResults ?? config.maxResults ?? 5).map((source, i) => ({
105
+ title: source.title,
106
+ url: source.url,
107
+ content: "cited_text" in source ? source.cited_text || "" : "",
108
+ score: 1 - i * 0.1,
109
+ domain: extractDomain(source.url)
110
+ })),
111
+ provider: "anthropic",
112
+ totalResults: finalSources.length,
113
+ searchTime
114
+ };
115
+ }
116
+ function extractDomain(url) {
117
+ try {
118
+ return new URL(url).hostname.replace("www.", "");
119
+ } catch {
120
+ return url;
121
+ }
122
+ }
123
+ var anthropicProvider = {
124
+ search: searchAnthropic,
125
+ validateConfig: validateAnthropicConfig
126
+ };
127
+
128
+ exports.anthropicProvider = anthropicProvider;
129
+ exports.searchAnthropic = searchAnthropic;
130
+ exports.validateAnthropicConfig = validateAnthropicConfig;
131
+ //# sourceMappingURL=chunk-TXLIY7GF.cjs.map
132
+ //# sourceMappingURL=chunk-TXLIY7GF.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/tools/webSearch/providers/anthropic.ts"],"names":[],"mappings":"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","file":"chunk-TXLIY7GF.cjs","sourcesContent":["/**\n * Anthropic Web Search Provider\n *\n * Uses Anthropic's built-in web_search tool via the Messages API.\n * Returns reliable citations with cited_text, url, and title.\n *\n * @see https://docs.anthropic.com/en/docs/build-with-claude/tool-use/web-search-tool\n */\n\nimport type {\n WebSearchConfig,\n WebSearchParams,\n WebSearchResponse,\n WebSearchProviderInterface,\n} from \"../types\";\n\nconst ANTHROPIC_API_URL = \"https://api.anthropic.com/v1/messages\";\n\n/**\n * Validate Anthropic native search configuration\n */\nexport function validateAnthropicConfig(config: WebSearchConfig): void {\n if (!config.apiKey) {\n throw new Error(\n \"Anthropic API key is required for native web search. \" +\n \"Pass apiKey or set ANTHROPIC_API_KEY environment variable.\",\n );\n }\n}\n\n// Type definitions for Anthropic response\ninterface AnthropicWebSearchResult {\n type: \"web_search_result\";\n url: string;\n title: string;\n encrypted_content?: string;\n page_age?: string;\n}\n\ninterface AnthropicCitation {\n type: \"web_search_result_location\";\n url: string;\n title: string;\n encrypted_index?: string;\n cited_text?: string;\n}\n\ninterface AnthropicContentBlock {\n type: string;\n text?: string;\n tool_use_id?: string;\n content?: AnthropicWebSearchResult[];\n citations?: AnthropicCitation[];\n}\n\ninterface AnthropicMessagesResponse {\n id: string;\n content: AnthropicContentBlock[];\n usage?: {\n input_tokens: number;\n output_tokens: number;\n server_tool_use?: {\n web_search_requests?: number;\n };\n };\n}\n\n/**\n * Search using Anthropic's native web_search tool\n */\nexport async function searchAnthropic(\n params: WebSearchParams,\n config: WebSearchConfig,\n): Promise<WebSearchResponse> {\n validateAnthropicConfig(config);\n\n const startTime = Date.now();\n const apiKey = config.apiKey || process.env.ANTHROPIC_API_KEY;\n\n // Build web search tool configuration\n const webSearchTool: Record<string, unknown> = {\n type: \"web_search_20250305\", // Use stable version\n name: \"web_search\",\n max_uses: config.maxResults ?? 5,\n };\n\n // Add domain filtering if provided\n if (config.includeDomains?.length) {\n webSearchTool.allowed_domains = config.includeDomains;\n }\n if (config.excludeDomains?.length) {\n webSearchTool.blocked_domains = config.excludeDomains;\n }\n\n // Add user location if country is set\n if (config.country) {\n webSearchTool.user_location = {\n type: \"approximate\",\n country: config.country.toUpperCase(),\n };\n }\n\n // Call Anthropic Messages API\n const response = await fetch(ANTHROPIC_API_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": apiKey!,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify({\n model: \"claude-sonnet-4-20250514\", // Use Sonnet 4 for balance of speed/quality\n max_tokens: 2048,\n tools: [webSearchTool],\n messages: [\n {\n role: \"user\",\n content: params.query,\n },\n ],\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 \"[Anthropic Native Search] API error:\",\n response.status,\n errorText,\n );\n throw new Error(\n `Anthropic Messages API error (${response.status}): ${errorText}`,\n );\n }\n\n const data: AnthropicMessagesResponse = await response.json();\n const searchTime = Date.now() - startTime;\n\n // Extract answer text and citations\n let outputText = \"\";\n const sources: Array<{ url: string; title: string; cited_text?: string }> =\n [];\n const searchResults: Array<{\n url: string;\n title: string;\n page_age?: string;\n }> = [];\n\n if (data.content && Array.isArray(data.content)) {\n for (const block of data.content) {\n // Extract text blocks\n if (block.type === \"text\" && block.text) {\n outputText += block.text;\n\n // Extract citations from text blocks\n if (block.citations && Array.isArray(block.citations)) {\n for (const citation of block.citations) {\n if (citation.url && !sources.find((s) => s.url === citation.url)) {\n sources.push({\n url: citation.url,\n title: citation.title || extractDomain(citation.url),\n cited_text: citation.cited_text,\n });\n }\n }\n }\n }\n\n // Extract search results from web_search_tool_result\n if (block.type === \"web_search_tool_result\" && block.content) {\n for (const result of block.content) {\n if (result.type === \"web_search_result\" && result.url) {\n searchResults.push({\n url: result.url,\n title: result.title || extractDomain(result.url),\n page_age: result.page_age,\n });\n }\n }\n }\n }\n }\n\n // Prefer citations (have cited_text) over raw search results\n const finalSources = sources.length > 0 ? sources : searchResults;\n\n return {\n query: params.query,\n answer: outputText,\n results: finalSources\n .slice(0, params.maxResults ?? config.maxResults ?? 5)\n .map((source, i) => ({\n title: source.title,\n url: source.url,\n content: \"cited_text\" in source ? source.cited_text || \"\" : \"\",\n score: 1 - i * 0.1,\n domain: extractDomain(source.url),\n })),\n provider: \"anthropic\",\n totalResults: finalSources.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 * Anthropic native search provider implementation\n */\nexport const anthropicProvider: WebSearchProviderInterface = {\n search: searchAnthropic,\n validateConfig: validateAnthropicConfig,\n};\n"]}
@@ -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"]}