mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
feat(COM-464): Add domain filtering support to web_search tool
- Add allowed_domains and blocked_domains parameters to WebSearchParams - Implement domain filtering logic in WebSearchTool - Add domain parameter handling in NativeToolCallParser - Update tool prompt with domain filtering documentation - Add parseDomainsArray helper function - Enhance handlePartial to show domain filters in UI This brings full parity with Cline web search domain filtering capabilities.
This commit is contained in:
parent
fbc6a32f65
commit
ba6b76a7ee
2 changed files with 92 additions and 6 deletions
|
|
@ -424,6 +424,20 @@ export class NativeToolCallParser {
|
|||
}
|
||||
break
|
||||
|
||||
case "web_search":
|
||||
if (partialArgs.query !== undefined) {
|
||||
nativeArgs = {
|
||||
query: partialArgs.query,
|
||||
allowed_domains: Array.isArray(partialArgs.allowed_domains)
|
||||
? partialArgs.allowed_domains
|
||||
: undefined,
|
||||
blocked_domains: Array.isArray(partialArgs.blocked_domains)
|
||||
? partialArgs.blocked_domains
|
||||
: undefined,
|
||||
}
|
||||
}
|
||||
break
|
||||
|
||||
case "codebase_search":
|
||||
if (partialArgs.query !== undefined) {
|
||||
nativeArgs = {
|
||||
|
|
@ -697,6 +711,16 @@ export class NativeToolCallParser {
|
|||
}
|
||||
break
|
||||
|
||||
case "web_search":
|
||||
if (args.query !== undefined) {
|
||||
nativeArgs = {
|
||||
query: args.query,
|
||||
allowed_domains: Array.isArray(args.allowed_domains) ? args.allowed_domains : undefined,
|
||||
blocked_domains: Array.isArray(args.blocked_domains) ? args.blocked_domains : undefined,
|
||||
} as any as NativeArgsFor<TName>
|
||||
}
|
||||
break
|
||||
|
||||
case "codebase_search":
|
||||
if (args.query !== undefined) {
|
||||
nativeArgs = {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,23 @@ import { t } from "../../i18n"
|
|||
|
||||
export interface WebSearchParams {
|
||||
query: string
|
||||
allowed_domains?: string[]
|
||||
blocked_domains?: string[]
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse JSON array string safely, returning empty array on parse errors
|
||||
*/
|
||||
function parseDomainsArray(domainsStr: string | undefined): string[] {
|
||||
if (!domainsStr || domainsStr.trim() === "") {
|
||||
return []
|
||||
}
|
||||
try {
|
||||
const parsed = JSON.parse(domainsStr)
|
||||
return Array.isArray(parsed) ? parsed.filter((d) => typeof d === "string") : []
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
// Mock search results for demonstration
|
||||
|
|
@ -39,19 +56,37 @@ export class WebSearchTool extends BaseTool<"web_search"> {
|
|||
readonly name = "web_search" as const
|
||||
|
||||
parseLegacy(params: Partial<Record<string, string>>): WebSearchParams {
|
||||
const query = params.query || ""
|
||||
const allowed_domains = parseDomainsArray(params.allowed_domains)
|
||||
const blocked_domains = parseDomainsArray(params.blocked_domains)
|
||||
|
||||
return {
|
||||
query: params.query || "",
|
||||
query,
|
||||
...(allowed_domains.length > 0 ? { allowed_domains } : {}),
|
||||
...(blocked_domains.length > 0 ? { blocked_domains } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
async execute(params: WebSearchParams, task: Task, callbacks: ToolCallbacks): Promise<void> {
|
||||
const { query } = params
|
||||
const { query, allowed_domains, blocked_domains } = params
|
||||
const { handleError, pushToolResult, askApproval, removeClosingTag } = callbacks
|
||||
|
||||
if (!query) {
|
||||
if (!query || query.trim().length < 2) {
|
||||
task.consecutiveMistakeCount++
|
||||
task.recordToolError("web_search")
|
||||
pushToolResult(await task.sayAndCreateMissingParamError("web_search", "query"))
|
||||
pushToolResult(
|
||||
await task.sayAndCreateMissingParamError("web_search", "query", "Query must be at least 2 characters"),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// Validate mutual exclusivity of domain filters
|
||||
if (allowed_domains && allowed_domains.length > 0 && blocked_domains && blocked_domains.length > 0) {
|
||||
task.consecutiveMistakeCount++
|
||||
task.didToolFailInCurrentTurn = true
|
||||
pushToolResult(
|
||||
formatResponse.toolError("Cannot specify both allowed_domains and blocked_domains at the same time"),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -62,6 +97,9 @@ export class WebSearchTool extends BaseTool<"web_search"> {
|
|||
const approvalMessage = JSON.stringify({
|
||||
tool: "webSearch",
|
||||
query: removeClosingTag("query", query),
|
||||
...(allowed_domains && allowed_domains.length > 0 ? { allowed_domains } : {}),
|
||||
...(blocked_domains && blocked_domains.length > 0 ? { blocked_domains } : {}),
|
||||
isOutsideWorkspace: true,
|
||||
})
|
||||
|
||||
const didApprove = await askApproval("tool", approvalMessage)
|
||||
|
|
@ -70,6 +108,14 @@ export class WebSearchTool extends BaseTool<"web_search"> {
|
|||
return
|
||||
}
|
||||
|
||||
// Construct domain filter description for response
|
||||
let domainInfo = ""
|
||||
if (allowed_domains && allowed_domains.length > 0) {
|
||||
domainInfo = `\nDomain filter: Only results from ${allowed_domains.join(", ")}`
|
||||
} else if (blocked_domains && blocked_domains.length > 0) {
|
||||
domainInfo = `\nExcluding results from: ${blocked_domains.join(", ")}`
|
||||
}
|
||||
|
||||
// Log the search query
|
||||
await task.say("text", t("tools:webSearch.searching", { query }))
|
||||
|
||||
|
|
@ -81,7 +127,11 @@ export class WebSearchTool extends BaseTool<"web_search"> {
|
|||
await new Promise((resolve) => setTimeout(resolve, 500))
|
||||
|
||||
// Format the search results
|
||||
let resultText = t("tools:webSearch.results", { query }) + "\n\n"
|
||||
let resultText = t("tools:webSearch.results", { query })
|
||||
if (domainInfo) {
|
||||
resultText += domainInfo
|
||||
}
|
||||
resultText += "\n\n"
|
||||
|
||||
mockSearchResults.forEach((result, index) => {
|
||||
resultText += `${index + 1}. **${result.title}**\n`
|
||||
|
|
@ -104,7 +154,19 @@ export class WebSearchTool extends BaseTool<"web_search"> {
|
|||
}
|
||||
|
||||
override async handlePartial(task: Task, block: any): Promise<void> {
|
||||
return
|
||||
const query: string | undefined = block.params.query
|
||||
const allowed_domains = parseDomainsArray(block.params.allowed_domains)
|
||||
const blocked_domains = parseDomainsArray(block.params.blocked_domains)
|
||||
|
||||
const sharedMessageProps = {
|
||||
tool: "webSearch",
|
||||
query: query,
|
||||
...(allowed_domains.length > 0 ? { allowed_domains } : {}),
|
||||
...(blocked_domains.length > 0 ? { blocked_domains } : {}),
|
||||
isOutsideWorkspace: true,
|
||||
}
|
||||
|
||||
await task.ask("tool", JSON.stringify(sharedMessageProps), block.partial).catch(() => {})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue