Skip to content
Open
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 src/core/task/Task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2426,7 +2426,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
const modelInfo = this.api.getModel().info
const modelSupportsBrowser = (modelInfo as any)?.supportsImages === true

const canUseBrowserTool = modelSupportsBrowser && modeSupportsBrowser && (browserToolEnabled ?? true)
const canUseBrowserTool = modelSupportsBrowser && modeSupportsBrowser && (browserToolEnabled ?? false)

return SYSTEM_PROMPT(
provider.context,
Expand Down
4 changes: 2 additions & 2 deletions src/core/webview/ClineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1911,7 +1911,7 @@ export class ClineProvider
maxOpenTabsContext: maxOpenTabsContext ?? 20,
maxWorkspaceFiles: maxWorkspaceFiles ?? 200,
cwd,
browserToolEnabled: browserToolEnabled ?? true,
browserToolEnabled: browserToolEnabled ?? false,
telemetrySetting,
telemetryKey,
machineId,
Expand Down Expand Up @@ -2133,7 +2133,7 @@ export class ClineProvider
maxOpenTabsContext: stateValues.maxOpenTabsContext ?? 20,
maxWorkspaceFiles: stateValues.maxWorkspaceFiles ?? 200,
openRouterUseMiddleOutTransform: stateValues.openRouterUseMiddleOutTransform,
browserToolEnabled: stateValues.browserToolEnabled ?? true,
browserToolEnabled: stateValues.browserToolEnabled ?? false,
telemetrySetting: stateValues.telemetrySetting || "unset",
showRooIgnoredFiles: stateValues.showRooIgnoredFiles ?? false,
maxReadFileLine: stateValues.maxReadFileLine ?? -1,
Expand Down
4 changes: 2 additions & 2 deletions src/core/webview/generateSystemPrompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ export const generateSystemPrompt = async (provider: ClineProvider, message: Web
const modelSupportsBrowser = modelInfo && (modelInfo as any)?.supportsImages === true

// Only enable browser tools if the model supports it, the mode includes browser tools,
// and browser tools are enabled in settings
const canUseBrowserTool = modelSupportsBrowser && modeSupportsBrowser && (browserToolEnabled ?? true)
// and browser tools are enabled in settings (default to OFF when unset)
const canUseBrowserTool = modelSupportsBrowser && modeSupportsBrowser && (browserToolEnabled ?? false)

const systemPrompt = await SYSTEM_PROMPT(
provider.context,
Expand Down
2 changes: 1 addition & 1 deletion src/core/webview/webviewMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1562,7 +1562,7 @@ export const webviewMessageHandler = async (
await provider.postStateToWebview()
break
case "browserToolEnabled":
await updateGlobalState("browserToolEnabled", message.bool ?? true)
await updateGlobalState("browserToolEnabled", message.bool ?? false)
await provider.postStateToWebview()
break
case "language":
Expand Down
41 changes: 29 additions & 12 deletions webview-ui/src/components/chat/AutoApproveDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const AutoApproveDropdown = ({ disabled = false, triggerClassName = "" }:

const {
autoApprovalEnabled,
browserToolEnabled,
setAutoApprovalEnabled,
alwaysApproveResubmit,
setAlwaysAllowReadOnly,
Expand Down Expand Up @@ -109,23 +110,31 @@ export const AutoApproveDropdown = ({ disabled = false, triggerClassName = "" }:
)

const handleSelectAll = React.useCallback(() => {
// Enable all options
Object.keys(autoApproveSettingsConfig).forEach((key) => {
// Enable all visible options based on current browser tool setting
const keys = browserToolEnabled
? Object.keys(autoApproveSettingsConfig)
: Object.keys(autoApproveSettingsConfig).filter((k) => k !== "alwaysAllowBrowser")

keys.forEach((key) => {
onAutoApproveToggle(key as AutoApproveSetting, true)
})
// Enable master auto-approval
if (!autoApprovalEnabled) {
setAutoApprovalEnabled(true)
vscode.postMessage({ type: "autoApprovalEnabled", bool: true })
}
}, [onAutoApproveToggle, autoApprovalEnabled, setAutoApprovalEnabled])
}, [onAutoApproveToggle, autoApprovalEnabled, setAutoApprovalEnabled, browserToolEnabled])

const handleSelectNone = React.useCallback(() => {
// Disable all options
Object.keys(autoApproveSettingsConfig).forEach((key) => {
// Disable all visible options based on current browser tool setting
const keys = browserToolEnabled
? Object.keys(autoApproveSettingsConfig)
: Object.keys(autoApproveSettingsConfig).filter((k) => k !== "alwaysAllowBrowser")

keys.forEach((key) => {
onAutoApproveToggle(key as AutoApproveSetting, false)
})
}, [onAutoApproveToggle])
}, [onAutoApproveToggle, browserToolEnabled])

const handleOpenSettings = React.useCallback(
() =>
Expand All @@ -143,21 +152,29 @@ export const AutoApproveDropdown = ({ disabled = false, triggerClassName = "" }:
// Calculate enabled and total counts as separate properties
const settingsArray = Object.values(autoApproveSettingsConfig)

// Filter out Browser toggle when browser tool is disabled
const visibleSettingsArray = React.useMemo(
() => settingsArray.filter((s) => browserToolEnabled || s.key !== "alwaysAllowBrowser"),
[settingsArray, browserToolEnabled],
)

const visibleKeys = React.useMemo(() => visibleSettingsArray.map((s) => s.key), [visibleSettingsArray])

const enabledCount = React.useMemo(() => {
return Object.values(toggles).filter((value) => !!value).length
}, [toggles])
return visibleKeys.filter((key) => !!toggles[key as keyof typeof toggles]).length
}, [visibleKeys, toggles])

const totalCount = React.useMemo(() => {
return Object.keys(toggles).length
}, [toggles])
return visibleKeys.length
}, [visibleKeys])

const { effectiveAutoApprovalEnabled } = useAutoApprovalState(toggles, autoApprovalEnabled)

const tooltipText =
!effectiveAutoApprovalEnabled || enabledCount === 0
? t("chat:autoApprove.tooltipManage")
: t("chat:autoApprove.tooltipStatus", {
toggles: settingsArray
toggles: visibleSettingsArray
.filter((setting) => toggles[setting.key])
.map((setting) => t(setting.labelKey))
.join(", "),
Expand Down Expand Up @@ -216,7 +233,7 @@ export const AutoApproveDropdown = ({ disabled = false, triggerClassName = "" }:
</p>
</div>
<div className="grid grid-cols-1 min-[340px]:grid-cols-2 gap-x-2 gap-y-2 p-3">
{settingsArray.map(({ key, labelKey, descriptionKey, icon }) => {
{visibleSettingsArray.map(({ key, labelKey, descriptionKey, icon }) => {
const isEnabled = toggles[key]
return (
<StandardTooltip key={key} content={t(descriptionKey)}>
Expand Down
8 changes: 7 additions & 1 deletion webview-ui/src/components/settings/AutoApproveToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { GlobalSettings } from "@roo-code/types"
import { useAppTranslation } from "@/i18n/TranslationContext"
import { cn } from "@/lib/utils"
import { Button, StandardTooltip } from "@/components/ui"
import { useExtensionState } from "@/context/ExtensionStateContext"

type AutoApproveToggles = Pick<
GlobalSettings,
Expand Down Expand Up @@ -107,10 +108,15 @@ type AutoApproveToggleProps = AutoApproveToggles & {

export const AutoApproveToggle = ({ onToggle, ...props }: AutoApproveToggleProps) => {
const { t } = useAppTranslation()
const { browserToolEnabled } = useExtensionState()

const visibleConfigs = Object.values(autoApproveSettingsConfig).filter(
(cfg) => browserToolEnabled || cfg.key !== "alwaysAllowBrowser",
)

return (
<div className={cn("flex flex-row flex-wrap gap-2 py-2")}>
{Object.values(autoApproveSettingsConfig).map(({ key, descriptionKey, labelKey, icon, testId }) => (
{visibleConfigs.map(({ key, descriptionKey, labelKey, icon, testId }) => (
<StandardTooltip key={key} content={t(descriptionKey || "")}>
<Button
variant={props[key] ? "default" : "outline"}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ vi.mock("@/i18n/TranslationContext", () => {
}
})

// Ensure components relying on ExtensionStateContext don't crash in tests
vi.mock("@/context/ExtensionStateContext", () => {
return {
useExtensionState: () => ({ browserToolEnabled: true }),
ExtensionStateContextProvider: ({ children }: any) => children,
}
})

describe("AutoApproveToggle", () => {
const mockOnToggle = vi.fn()
const initialProps = {
Expand Down
2 changes: 1 addition & 1 deletion webview-ui/src/context/ExtensionStateContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
maxOpenTabsContext: 20,
maxWorkspaceFiles: 200,
cwd: "",
browserToolEnabled: true,
browserToolEnabled: false,
telemetrySetting: "unset",
showRooIgnoredFiles: true, // Default to showing .rooignore'd files with lock symbol (current behavior).
renderContext: "sidebar",
Expand Down