Просмотр исходного кода

fix: adjust websearch tool to emphasize that it ISNT 2024, give more info as to current date

Aiden Cline 1 месяц назад
Родитель
Сommit
1a43e5fe87
2 измененных файлов с 98 добавлено и 89 удалено
  1. 95 89
      packages/opencode/src/tool/websearch.ts
  2. 3 0
      packages/opencode/src/tool/websearch.txt

+ 95 - 89
packages/opencode/src/tool/websearch.ts

@@ -36,109 +36,115 @@ interface McpSearchResponse {
   }
 }
 
-export const WebSearchTool = Tool.define("websearch", {
-  description: DESCRIPTION,
-  parameters: z.object({
-    query: z.string().describe("Websearch query"),
-    numResults: z.number().optional().describe("Number of search results to return (default: 8)"),
-    livecrawl: z
-      .enum(["fallback", "preferred"])
-      .optional()
-      .describe(
-        "Live crawl mode - 'fallback': use live crawling as backup if cached content unavailable, 'preferred': prioritize live crawling (default: 'fallback')",
-      ),
-    type: z
-      .enum(["auto", "fast", "deep"])
-      .optional()
-      .describe("Search type - 'auto': balanced search (default), 'fast': quick results, 'deep': comprehensive search"),
-    contextMaxCharacters: z
-      .number()
-      .optional()
-      .describe("Maximum characters for context string optimized for LLMs (default: 10000)"),
-  }),
-  async execute(params, ctx) {
-    await ctx.ask({
-      permission: "websearch",
-      patterns: [params.query],
-      always: ["*"],
-      metadata: {
-        query: params.query,
-        numResults: params.numResults,
-        livecrawl: params.livecrawl,
-        type: params.type,
-        contextMaxCharacters: params.contextMaxCharacters,
-      },
-    })
-
-    const searchRequest: McpSearchRequest = {
-      jsonrpc: "2.0",
-      id: 1,
-      method: "tools/call",
-      params: {
-        name: "web_search_exa",
-        arguments: {
+export const WebSearchTool = Tool.define("websearch", async () => {
+  return {
+    get description() {
+      return DESCRIPTION.replace("{{date}}", new Date().toISOString().slice(0, 10))
+    },
+    parameters: z.object({
+      query: z.string().describe("Websearch query"),
+      numResults: z.number().optional().describe("Number of search results to return (default: 8)"),
+      livecrawl: z
+        .enum(["fallback", "preferred"])
+        .optional()
+        .describe(
+          "Live crawl mode - 'fallback': use live crawling as backup if cached content unavailable, 'preferred': prioritize live crawling (default: 'fallback')",
+        ),
+      type: z
+        .enum(["auto", "fast", "deep"])
+        .optional()
+        .describe(
+          "Search type - 'auto': balanced search (default), 'fast': quick results, 'deep': comprehensive search",
+        ),
+      contextMaxCharacters: z
+        .number()
+        .optional()
+        .describe("Maximum characters for context string optimized for LLMs (default: 10000)"),
+    }),
+    async execute(params, ctx) {
+      await ctx.ask({
+        permission: "websearch",
+        patterns: [params.query],
+        always: ["*"],
+        metadata: {
           query: params.query,
-          type: params.type || "auto",
-          numResults: params.numResults || API_CONFIG.DEFAULT_NUM_RESULTS,
-          livecrawl: params.livecrawl || "fallback",
+          numResults: params.numResults,
+          livecrawl: params.livecrawl,
+          type: params.type,
           contextMaxCharacters: params.contextMaxCharacters,
         },
-      },
-    }
-
-    const controller = new AbortController()
-    const timeoutId = setTimeout(() => controller.abort(), 25000)
+      })
 
-    try {
-      const headers: Record<string, string> = {
-        accept: "application/json, text/event-stream",
-        "content-type": "application/json",
+      const searchRequest: McpSearchRequest = {
+        jsonrpc: "2.0",
+        id: 1,
+        method: "tools/call",
+        params: {
+          name: "web_search_exa",
+          arguments: {
+            query: params.query,
+            type: params.type || "auto",
+            numResults: params.numResults || API_CONFIG.DEFAULT_NUM_RESULTS,
+            livecrawl: params.livecrawl || "fallback",
+            contextMaxCharacters: params.contextMaxCharacters,
+          },
+        },
       }
 
-      const response = await fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.SEARCH}`, {
-        method: "POST",
-        headers,
-        body: JSON.stringify(searchRequest),
-        signal: AbortSignal.any([controller.signal, ctx.abort]),
-      })
+      const controller = new AbortController()
+      const timeoutId = setTimeout(() => controller.abort(), 25000)
 
-      clearTimeout(timeoutId)
+      try {
+        const headers: Record<string, string> = {
+          accept: "application/json, text/event-stream",
+          "content-type": "application/json",
+        }
 
-      if (!response.ok) {
-        const errorText = await response.text()
-        throw new Error(`Search error (${response.status}): ${errorText}`)
-      }
+        const response = await fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.SEARCH}`, {
+          method: "POST",
+          headers,
+          body: JSON.stringify(searchRequest),
+          signal: AbortSignal.any([controller.signal, ctx.abort]),
+        })
+
+        clearTimeout(timeoutId)
+
+        if (!response.ok) {
+          const errorText = await response.text()
+          throw new Error(`Search error (${response.status}): ${errorText}`)
+        }
 
-      const responseText = await response.text()
+        const responseText = await response.text()
 
-      // Parse SSE response
-      const lines = responseText.split("\n")
-      for (const line of lines) {
-        if (line.startsWith("data: ")) {
-          const data: McpSearchResponse = JSON.parse(line.substring(6))
-          if (data.result && data.result.content && data.result.content.length > 0) {
-            return {
-              output: data.result.content[0].text,
-              title: `Web search: ${params.query}`,
-              metadata: {},
+        // Parse SSE response
+        const lines = responseText.split("\n")
+        for (const line of lines) {
+          if (line.startsWith("data: ")) {
+            const data: McpSearchResponse = JSON.parse(line.substring(6))
+            if (data.result && data.result.content && data.result.content.length > 0) {
+              return {
+                output: data.result.content[0].text,
+                title: `Web search: ${params.query}`,
+                metadata: {},
+              }
             }
           }
         }
-      }
 
-      return {
-        output: "No search results found. Please try a different query.",
-        title: `Web search: ${params.query}`,
-        metadata: {},
-      }
-    } catch (error) {
-      clearTimeout(timeoutId)
+        return {
+          output: "No search results found. Please try a different query.",
+          title: `Web search: ${params.query}`,
+          metadata: {},
+        }
+      } catch (error) {
+        clearTimeout(timeoutId)
 
-      if (error instanceof Error && error.name === "AbortError") {
-        throw new Error("Search request timed out")
-      }
+        if (error instanceof Error && error.name === "AbortError") {
+          throw new Error("Search request timed out")
+        }
 
-      throw error
-    }
-  },
+        throw error
+      }
+    },
+  }
 })

+ 3 - 0
packages/opencode/src/tool/websearch.txt

@@ -9,3 +9,6 @@ Usage notes:
   - Search types: 'auto' (balanced), 'fast' (quick results), 'deep' (comprehensive search)
   - Configurable context length for optimal LLM integration
   - Domain filtering and advanced search options available
+
+Today's date is {{date}}. You MUST use this year when searching for recent information or current events
+- Example: If today is 2025-07-15 and the user asks for "latest AI news", search for "AI news 2025", NOT "AI news 2024"