Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/cli/src/ui/components/ChatHistoryItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type ToolCategory = "file" | "directory" | "search" | "command" | "browser" | "m
function getToolCategory(toolName: string): ToolCategory {
const fileTools = ["readFile", "read_file", "writeToFile", "write_to_file", "applyDiff", "apply_diff"]
const dirTools = ["listFiles", "list_files", "listFilesRecursive", "listFilesTopLevel"]
const searchTools = ["searchFiles", "search_files"]
const searchTools = ["searchFiles", "search_files", "webSearch", "web_search"]
const commandTools = ["executeCommand", "execute_command"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

web_search is treated as a browser tool in filtering (browserToolEnabled) and grouped under browser, but it is categorized as a search tool in the CLI UI. This mismatch is confusing for users and makes browser enable/disable semantics harder to reason about. Consider categorizing webSearch/web_search under the browser tool group in the CLI UI as well.

Fix it with Roo Code or mention @roomote and request a fix.

const browserTools = ["browserAction", "browser_action"]
const modeTools = ["switchMode", "switch_mode", "newTask", "new_task"]
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/src/ui/components/tools/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function getToolCategory(toolName: string): ToolCategory {
"writeToFile",
]

const searchTools = ["searchFiles", "search_files", "codebaseSearch", "codebase_search"]
const searchTools = ["searchFiles", "search_files", "codebaseSearch", "codebase_search", "webSearch", "web_search"]
const commandTools = ["execute_command", "executeCommand"]
const browserTools = ["browser_action", "browserAction"]
const modeTools = ["switchMode", "switch_mode", "newTask", "new_task", "finishTask"]
Expand Down
4 changes: 4 additions & 0 deletions apps/cli/src/ui/components/tools/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ export function getToolDisplayName(toolName: string): string {
search_files: "Search Files",
codebaseSearch: "Codebase Search",
codebase_search: "Codebase Search",
webSearch: "Web Search",
web_search: "Web Search",

// Command operations
execute_command: "Execute Command",
Expand Down Expand Up @@ -126,6 +128,8 @@ export function getToolIconName(toolName: string): IconName {
search_files: "search",
codebaseSearch: "search",
codebase_search: "search",
webSearch: "search",
web_search: "search",

// Command operations
execute_command: "terminal",
Expand Down
1 change: 1 addition & 0 deletions packages/types/src/tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const toolNames = [
"search_files",
"list_files",
"browser_action",
"web_search",
"use_mcp_tool",
"access_mcp_resource",
"ask_followup_question",
Expand Down
1 change: 1 addition & 0 deletions packages/types/src/vscode-extension-host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@ export interface ClineSayTool {
| "listFilesTopLevel"
| "listFilesRecursive"
| "searchFiles"
| "webSearch"
| "switchMode"
| "newTask"
| "finishTask"
Expand Down
10 changes: 10 additions & 0 deletions src/core/assistant-message/presentAssistantMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { generateImageTool } from "../tools/GenerateImageTool"
import { applyDiffTool as applyDiffToolClass } from "../tools/ApplyDiffTool"
import { validateToolUse } from "../tools/validateToolUse"
import { codebaseSearchTool } from "../tools/CodebaseSearchTool"
import { webSearchTool } from "../tools/WebSearchTool"

import { formatResponse } from "../prompts/responses"

Expand Down Expand Up @@ -1016,6 +1017,15 @@ export async function presentAssistantMessage(cline: Task) {
toolProtocol,
})
break
case "web_search":
await webSearchTool.handle(cline, block as ToolUse<"web_search">, {
askApproval,
handleError,
pushToolResult,
removeClosingTag,
toolProtocol,
})
break
case "browser_action":
await browserActionTool(
cline,
Expand Down
1 change: 1 addition & 0 deletions src/core/auto-approval/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export function isReadOnlyToolAction(tool: ClineSayTool): boolean {
"listFilesRecursive",
"searchFiles",
"codebaseSearch",
"webSearch",
"runSlashCommand",
].includes(tool.tool)
}
3 changes: 2 additions & 1 deletion src/core/prompts/tools/filter-tools-for-mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ export function filterNativeToolsForMode(
// Conditionally exclude browser_action if disabled in settings
if (settings?.browserToolEnabled === false) {
allowedToolNames.delete("browser_action")
allowedToolNames.delete("web_search")
}

// Conditionally exclude apply_diff if diffs are disabled
Expand Down Expand Up @@ -383,7 +384,7 @@ export function isToolAllowedInMode(
}

// Check for browser_action being disabled by user settings
if (toolName === "browser_action" && settings?.browserToolEnabled === false) {
if ((toolName === "browser_action" || toolName === "web_search") && settings?.browserToolEnabled === false) {
return false
}

Expand Down
8 changes: 8 additions & 0 deletions src/core/prompts/tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { getAccessMcpResourceDescription } from "./access-mcp-resource"
import { getSwitchModeDescription } from "./switch-mode"
import { getNewTaskDescription } from "./new-task"
import { getCodebaseSearchDescription } from "./codebase-search"
import { getWebSearchDescription } from "./web-search"
import { getUpdateTodoListDescription } from "./update-todo-list"
import { getRunSlashCommandDescription } from "./run-slash-command"
import { getGenerateImageDescription } from "./generate-image"
Expand All @@ -36,6 +37,7 @@ const toolDescriptionMap: Record<string, (args: ToolArgs) => string | undefined>
search_files: (args) => getSearchFilesDescription(args),
list_files: (args) => getListFilesDescription(args),
browser_action: (args) => getBrowserActionDescription(args),
web_search: () => getWebSearchDescription(),
ask_followup_question: () => getAskFollowupQuestionDescription(),
attempt_completion: (args) => getAttemptCompletionDescription(args),
use_mcp_tool: (args) => getUseMcpToolDescription(args),
Expand Down Expand Up @@ -131,6 +133,11 @@ export function getToolDescriptionsForMode(
tools.delete("run_slash_command")
}

// Conditionally exclude web_search if browser tools are disabled in settings
if (settings?.browserToolEnabled === false) {
tools.delete("web_search")
}

// Map tool descriptions for allowed tools
const descriptions = Array.from(tools).map((toolName) => {
const descriptionFn = toolDescriptionMap[toolName]
Expand Down Expand Up @@ -164,6 +171,7 @@ export {
getAccessMcpResourceDescription,
getSwitchModeDescription,
getCodebaseSearchDescription,
getWebSearchDescription,
getRunSlashCommandDescription,
getGenerateImageDescription,
}
Expand Down
2 changes: 2 additions & 0 deletions src/core/prompts/tools/native-tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import edit_file from "./edit_file"
import searchFiles from "./search_files"
import switchMode from "./switch_mode"
import updateTodoList from "./update_todo_list"
import webSearch from "./web_search"
import writeToFile from "./write_to_file"

export { getMcpServerTools } from "./mcp_server"
Expand Down Expand Up @@ -73,6 +74,7 @@ export function getNativeTools(options: NativeToolsOptions = {}): OpenAI.Chat.Ch
searchFiles,
switchMode,
updateTodoList,
webSearch,
writeToFile,
] satisfies OpenAI.Chat.ChatCompletionTool[]
}
Expand Down
38 changes: 38 additions & 0 deletions src/core/prompts/tools/native-tools/web_search.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type OpenAI from "openai"

const WEB_SEARCH_DESCRIPTION = `Search the public web for up-to-date information and return a concise list of results with titles, URLs, and snippets. Use this tool when you need real-time or external context that is not available in the local workspace.
Parameters:
- query: (required) The search query to run.
- max_results: (optional) Maximum number of results to return (default: 5, max: 10).
Example: Searching for release notes
{ "query": "Cline 3.48.0 web search tool", "max_results": 5 }`

const QUERY_PARAMETER_DESCRIPTION = `Search query string`

const MAX_RESULTS_PARAMETER_DESCRIPTION = `Optional cap on number of results (1-10)`

export default {
type: "function",
function: {
name: "web_search",
description: WEB_SEARCH_DESCRIPTION,
strict: true,
parameters: {
type: "object",
properties: {
query: {
type: "string",
description: QUERY_PARAMETER_DESCRIPTION,
},
max_results: {
type: ["integer", "null"],
description: MAX_RESULTS_PARAMETER_DESCRIPTION,
},
},
required: ["query", "max_results"],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

max_results is described as optional, but the native tool schema marks it as required (required: ["query", "max_results"]). With strict: true, this forces the model to always send max_results and can lead to validation failures if it omits it. Consider removing max_results from required and keeping the runtime defaulting in the tool implementation.

Fix it with Roo Code or mention @roomote and request a fix.

additionalProperties: false,
},
},
} satisfies OpenAI.Chat.ChatCompletionTool
20 changes: 20 additions & 0 deletions src/core/prompts/tools/web-search.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export function getWebSearchDescription(): string {
return `## web_search
Description: Search the public web for up-to-date information and return a concise list of results with titles, URLs, and snippets. Use this tool when you need real-time or external context that is not available in the local workspace.

Parameters:
- query: (required) The search query to run.
- max_results: (optional) Maximum number of results to return (default: 5, max: 10).

Usage:
<web_search>
<query>Your search query</query>
<max_results>5</max_results>
</web_search>

Example:
<web_search>
<query>OpenAI Responses API web search tool</query>
<max_results>3</max_results>
</web_search>`
}
Loading
Loading