Skip to content

Instantly share code, notes, and snippets.

@yanosh-k
Created February 6, 2026 16:31
Show Gist options
  • Select an option

  • Save yanosh-k/2aac282fb646fe50fcaddafc853aada0 to your computer and use it in GitHub Desktop.

Select an option

Save yanosh-k/2aac282fb646fe50fcaddafc853aada0 to your computer and use it in GitHub Desktop.
Web search tool for opencode using the python ddgs package
import os from 'os'
const { tool } = await import(os.homedir().replace(/\/$/, '') + '/.config/opencode/node_modules/@opencode-ai/plugin/dist/')
export default tool({
description: "Performs web searches and returns a list of relevant results. Each result includes a title, URL, and snippet/description of the page content. Use this tool when you need current information from the internet, want to find specific websites, research topics, verify facts, or gather multiple perspectives on a subject. The tool returns up to 10 search results ranked by relevance. Note: This tool only provides brief snippets - use a web fetching tool with the returned URLs to access the full page content when needed. Do not make parallel requests with this tool as it will hit the usage limit, instead make single calls to it.",
args: {
query: tool.schema.string().describe("Search query"),
},
async execute(args) {
// Validate query
if (!args.query.trim()) {
return "Error: Search query cannot be empty"
}
// Hardcoded parameters (you can edit these directly in the code)
const REGION = "bg-bg"
const BACKEND = "duckduckgo"
const MAX_RESULTS = 10
const VERIFY_SSL = false
const SEARCH_FILE = `/tmp/opencode_ddgs_search_${Date.now()}.json`
try {
// Build the command with hardcoded parameters
const cmdParts = [
"PATH_TO_DDGS_EXECUTABLE/ddgs",
"text",
"-q", args.query,
"-r", REGION,
"-b", BACKEND,
"-m", MAX_RESULTS.toString(),
"-v", VERIFY_SSL ? "true" : "false",
"-o", SEARCH_FILE
]
// Execute the ddgs command
const proc = await Bun.$`${cmdParts}`.quiet().nothrow()
// Check if the command failed
if (proc.exitCode !== 0) {
const stdout = proc.stdout.toString()
const stderr = proc.stderr.toString()
throw new Error(`Command failed with exit code ${proc.exitCode}. stdout: ${stdout || '(empty)'}. stderr: ${stderr || '(empty)'}`)
}
// Read the results
const file = Bun.file(SEARCH_FILE)
if (!await file.exists()) {
throw new Error(`Search results file was not created at ${SEARCH_FILE}`)
}
const fileContent = await file.text()
if (!fileContent) {
throw new Error(`Search results file is empty`)
}
// Parse the JSON to validate and potentially format it
const results = JSON.parse(fileContent)
// Format the output for better readability
let formattedOutput = `Search results for "${args.query}":\n\n`
if (Array.isArray(results) && results.length > 0) {
results.forEach((result, index) => {
formattedOutput += `${index + 1}. ${result.title || 'No title'}\n`
formattedOutput += ` URL: ${result.href || result.url || 'N/A'}\n`
formattedOutput += ` ${result.body || result.description || ''}\n\n`
})
} else {
formattedOutput += "No results found."
}
// Clean up temporary file
try {
await Bun.$`rm ${SEARCH_FILE}`.quiet()
} catch {
// Ignore cleanup errors
}
return formattedOutput
} catch (error) {
// Clean up on error
try {
await Bun.$`rm ${SEARCH_FILE}`.quiet()
} catch {
// Ignore cleanup errors
}
return `Error performing search: ${error instanceof Error ? error.message : String(error)}`
}
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment