Skip to content
Merged
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
4 changes: 0 additions & 4 deletions packages/types/src/global-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,13 @@ export const globalSettingsSchema = z.object({
alwaysAllowWriteProtected: z.boolean().optional(),
writeDelayMs: z.number().min(0).optional(),
alwaysAllowBrowser: z.boolean().optional(),
alwaysApproveResubmit: z.boolean().optional(),
requestDelaySeconds: z.number().optional(),
alwaysAllowMcp: z.boolean().optional(),
alwaysAllowModeSwitch: z.boolean().optional(),
alwaysAllowSubtasks: z.boolean().optional(),
alwaysAllowExecute: z.boolean().optional(),
alwaysAllowFollowupQuestions: z.boolean().optional(),
followupAutoApproveTimeoutMs: z.number().optional(),
alwaysAllowUpdateTodoList: z.boolean().optional(),
allowedCommands: z.array(z.string()).optional(),
deniedCommands: z.array(z.string()).optional(),
commandExecutionTimeout: z.number().optional(),
Expand Down Expand Up @@ -307,14 +305,12 @@ export const EVALS_SETTINGS: RooCodeSettings = {
alwaysAllowWriteProtected: false,
writeDelayMs: 1000,
alwaysAllowBrowser: true,
alwaysApproveResubmit: true,
requestDelaySeconds: 10,
alwaysAllowMcp: true,
alwaysAllowModeSwitch: true,
alwaysAllowSubtasks: true,
alwaysAllowExecute: true,
alwaysAllowFollowupQuestions: true,
alwaysAllowUpdateTodoList: true,
followupAutoApproveTimeoutMs: 0,
allowedCommands: ["*"],
commandExecutionTimeout: 20,
Expand Down
4 changes: 1 addition & 3 deletions src/core/auto-approval/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ export type AutoApprovalState =
| "alwaysAllowReadOnly"
| "alwaysAllowWrite"
| "alwaysAllowBrowser"
| "alwaysApproveResubmit"
| "alwaysAllowMcp"
| "alwaysAllowModeSwitch"
| "alwaysAllowSubtasks"
| "alwaysAllowExecute"
| "alwaysAllowFollowupQuestions"
| "alwaysAllowUpdateTodoList"

// Some of these actions have additional settings associated with them.
export type AutoApprovalStateOptions =
Expand Down Expand Up @@ -144,7 +142,7 @@ export async function checkAutoApproval({
}

if (tool.tool === "updateTodoList") {
return state.alwaysAllowUpdateTodoList === true ? { decision: "approve" } : { decision: "ask" }
return { decision: "approve" }
}

if (tool?.tool === "fetchInstructions") {
Expand Down
7 changes: 3 additions & 4 deletions src/core/task/Task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2959,7 +2959,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {

// Apply exponential backoff similar to first-chunk errors when auto-resubmit is enabled
const stateForBackoff = await this.providerRef.deref()?.getState()
if (stateForBackoff?.autoApprovalEnabled && stateForBackoff?.alwaysApproveResubmit) {
if (stateForBackoff?.autoApprovalEnabled) {
await this.backoffAndAnnounce(
currentItem.retryAttempt ?? 0,
error,
Expand Down Expand Up @@ -3216,7 +3216,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {

// Check if we should auto-retry or prompt the user
// Reuse the state variable from above
if (state?.autoApprovalEnabled && state?.alwaysApproveResubmit) {
if (state?.autoApprovalEnabled) {
// Auto-retry with backoff - don't persist failure message when retrying
const errorMsg =
"Unexpected API Response: The language model did not provide any assistant messages. This may indicate an issue with the API or the model's output."
Expand Down Expand Up @@ -3509,7 +3509,6 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
const {
apiConfiguration,
autoApprovalEnabled,
alwaysApproveResubmit,
requestDelaySeconds,
mode,
autoCondenseContext = true,
Expand Down Expand Up @@ -3811,7 +3810,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
}

// note that this api_req_failed ask is unique in that we only present this option if the api hasn't streamed any content yet (ie it fails on the first chunk due), as it would allow them to hit a retry button. However if the api failed mid-stream, it could be in any arbitrary state where some tools may have executed, so that error is handled differently and requires cancelling the task entirely.
if (autoApprovalEnabled && alwaysApproveResubmit) {
if (autoApprovalEnabled) {
let errorMsg

if (error.error?.metadata?.raw) {
Expand Down
18 changes: 6 additions & 12 deletions src/core/task/__tests__/Task.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -697,11 +697,8 @@ describe("Cline", () => {
return mockSuccessStream
})

// Set alwaysApproveResubmit and requestDelaySeconds
mockProvider.getState = vi.fn().mockResolvedValue({
alwaysApproveResubmit: true,
requestDelaySeconds: 3,
})
// Set up mock state
mockProvider.getState = vi.fn().mockResolvedValue({})

// Mock previous API request message
cline.clineMessages = [
Expand All @@ -723,7 +720,7 @@ describe("Cline", () => {
await iterator.next()

// Calculate expected delay for first retry
const baseDelay = 3 // from requestDelaySeconds
const baseDelay = 3 // test retry delay

// Verify countdown messages
for (let i = baseDelay; i > 0; i--) {
Expand Down Expand Up @@ -821,11 +818,8 @@ describe("Cline", () => {
return mockSuccessStream
})

// Set alwaysApproveResubmit and requestDelaySeconds
mockProvider.getState = vi.fn().mockResolvedValue({
alwaysApproveResubmit: true,
requestDelaySeconds: 3,
})
// Set up mock state
mockProvider.getState = vi.fn().mockResolvedValue({})

// Mock previous API request message
cline.clineMessages = [
Expand All @@ -847,7 +841,7 @@ describe("Cline", () => {
await iterator.next()

// Verify delay is only applied for the countdown
const baseDelay = 3 // from requestDelaySeconds
const baseDelay = 3 // test retry delay
const expectedDelayCount = baseDelay // One delay per second for countdown
expect(mockDelay).toHaveBeenCalledTimes(expectedDelayCount)
expect(mockDelay).toHaveBeenCalledWith(1000) // Each delay should be 1 second
Expand Down
9 changes: 0 additions & 9 deletions src/core/webview/ClineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1816,7 +1816,6 @@ export class ClineProvider
alwaysAllowMcp,
alwaysAllowModeSwitch,
alwaysAllowSubtasks,
alwaysAllowUpdateTodoList,
allowedMaxRequests,
allowedMaxCost,
autoCondenseContext,
Expand Down Expand Up @@ -1848,8 +1847,6 @@ export class ClineProvider
fuzzyMatchThreshold,
mcpEnabled,
enableMcpServerCreation,
alwaysApproveResubmit,
requestDelaySeconds,
currentApiConfigName,
listApiConfigMeta,
pinnedApiConfigs,
Expand Down Expand Up @@ -1948,7 +1945,6 @@ export class ClineProvider
alwaysAllowMcp: alwaysAllowMcp ?? false,
alwaysAllowModeSwitch: alwaysAllowModeSwitch ?? false,
alwaysAllowSubtasks: alwaysAllowSubtasks ?? false,
alwaysAllowUpdateTodoList: alwaysAllowUpdateTodoList ?? false,
isBrowserSessionActive,
allowedMaxRequests,
allowedMaxCost,
Expand Down Expand Up @@ -1994,8 +1990,6 @@ export class ClineProvider
fuzzyMatchThreshold: fuzzyMatchThreshold ?? 1.0,
mcpEnabled: mcpEnabled ?? true,
enableMcpServerCreation: enableMcpServerCreation ?? true,
alwaysApproveResubmit: alwaysApproveResubmit ?? false,
requestDelaySeconds: requestDelaySeconds ?? 10,
currentApiConfigName: currentApiConfigName ?? "default",
listApiConfigMeta: listApiConfigMeta ?? [],
pinnedApiConfigs: pinnedApiConfigs ?? {},
Expand Down Expand Up @@ -2189,7 +2183,6 @@ export class ClineProvider
alwaysAllowModeSwitch: stateValues.alwaysAllowModeSwitch ?? false,
alwaysAllowSubtasks: stateValues.alwaysAllowSubtasks ?? false,
alwaysAllowFollowupQuestions: stateValues.alwaysAllowFollowupQuestions ?? false,
alwaysAllowUpdateTodoList: stateValues.alwaysAllowUpdateTodoList ?? false,
isBrowserSessionActive,
followupAutoApproveTimeoutMs: stateValues.followupAutoApproveTimeoutMs ?? 60000,
diagnosticsEnabled: stateValues.diagnosticsEnabled ?? true,
Expand Down Expand Up @@ -2232,8 +2225,6 @@ export class ClineProvider
mcpEnabled: stateValues.mcpEnabled ?? true,
enableMcpServerCreation: stateValues.enableMcpServerCreation ?? true,
mcpServers: this.mcpHub?.getAllServers() ?? [],
alwaysApproveResubmit: stateValues.alwaysApproveResubmit ?? false,
requestDelaySeconds: Math.max(5, stateValues.requestDelaySeconds ?? 10),
currentApiConfigName: stateValues.currentApiConfigName ?? "default",
listApiConfigMeta: stateValues.listApiConfigMeta ?? [],
pinnedApiConfigs: stateValues.pinnedApiConfigs ?? {},
Expand Down
38 changes: 0 additions & 38 deletions src/core/webview/__tests__/ClineProvider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,6 @@ describe("ClineProvider", () => {
fuzzyMatchThreshold: 1.0,
mcpEnabled: true,
enableMcpServerCreation: false,
requestDelaySeconds: 5,
mode: defaultModeSlug,
customModes: [],
experiments: experimentDefault,
Expand Down Expand Up @@ -835,27 +834,6 @@ describe("ClineProvider", () => {
expect(mockPostMessage).toHaveBeenCalled()
})

test("requestDelaySeconds defaults to 10 seconds", async () => {
// Mock globalState.get to return undefined for requestDelaySeconds
;(mockContext.globalState.get as any).mockImplementation((key: string) => {
if (key === "requestDelaySeconds") {
return undefined
}
return null
})

const state = await provider.getState()
expect(state.requestDelaySeconds).toBe(10)
})

test("alwaysApproveResubmit defaults to false", async () => {
// Mock globalState.get to return undefined for alwaysApproveResubmit
;(mockContext.globalState.get as any).mockReturnValue(undefined)

const state = await provider.getState()
expect(state.alwaysApproveResubmit).toBe(false)
})

test("autoCondenseContext defaults to true", async () => {
// Mock globalState.get to return undefined for autoCondenseContext
;(mockContext.globalState.get as any).mockImplementation((key: string) =>
Expand Down Expand Up @@ -1026,22 +1004,6 @@ describe("ClineProvider", () => {
expect((await provider.getState()).showRooIgnoredFiles).toBe(false)
})

test("handles request delay settings messages", async () => {
await provider.resolveWebviewView(mockWebviewView)
const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as any).mock.calls[0][0]

// Test alwaysApproveResubmit
await messageHandler({ type: "updateSettings", updatedSettings: { alwaysApproveResubmit: true } })
expect(updateGlobalStateSpy).toHaveBeenCalledWith("alwaysApproveResubmit", true)
expect(mockContext.globalState.update).toHaveBeenCalledWith("alwaysApproveResubmit", true)
expect(mockPostMessage).toHaveBeenCalled()

// Test requestDelaySeconds
await messageHandler({ type: "updateSettings", updatedSettings: { requestDelaySeconds: 10 } })
expect(mockContext.globalState.update).toHaveBeenCalledWith("requestDelaySeconds", 10)
expect(mockPostMessage).toHaveBeenCalled()
})

test("handles updatePrompt message correctly", async () => {
await provider.resolveWebviewView(mockWebviewView)
const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as any).mock.calls[0][0]
Expand Down
4 changes: 1 addition & 3 deletions src/shared/ExtensionMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,11 @@ export type ExtensionState = Pick<
| "alwaysAllowWriteOutsideWorkspace"
| "alwaysAllowWriteProtected"
| "alwaysAllowBrowser"
| "alwaysApproveResubmit"
| "alwaysAllowMcp"
| "alwaysAllowModeSwitch"
| "alwaysAllowSubtasks"
| "alwaysAllowFollowupQuestions"
| "alwaysAllowExecute"
| "alwaysAllowUpdateTodoList"
| "followupAutoApproveTimeoutMs"
| "allowedCommands"
| "deniedCommands"
Expand Down Expand Up @@ -290,6 +288,7 @@ export type ExtensionState = Pick<
| "includeCurrentTime"
| "includeCurrentCost"
| "maxGitStatusFiles"
| "requestDelaySeconds"
> & {
version: string
clineMessages: ClineMessage[]
Expand All @@ -302,7 +301,6 @@ export type ExtensionState = Pick<
taskHistory: HistoryItem[]

writeDelayMs: number
requestDelaySeconds: number

enableCheckpoints: boolean
checkpointTimeout: number // Timeout for checkpoint initialization in seconds (default: 15)
Expand Down
22 changes: 1 addition & 21 deletions webview-ui/src/components/chat/AutoApproveDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,29 +31,17 @@ export const AutoApproveDropdown = ({ disabled = false, triggerClassName = "" }:
const {
autoApprovalEnabled,
setAutoApprovalEnabled,
alwaysApproveResubmit,
setAlwaysAllowReadOnly,
setAlwaysAllowWrite,
setAlwaysAllowExecute,
setAlwaysAllowBrowser,
setAlwaysAllowMcp,
setAlwaysAllowModeSwitch,
setAlwaysAllowSubtasks,
setAlwaysApproveResubmit,
setAlwaysAllowFollowupQuestions,
setAlwaysAllowUpdateTodoList,
} = useExtensionState()

const baseToggles = useAutoApprovalToggles()

// Include alwaysApproveResubmit in addition to the base toggles.
const toggles = React.useMemo(
() => ({
...baseToggles,
alwaysApproveResubmit: alwaysApproveResubmit,
}),
[baseToggles, alwaysApproveResubmit],
)
const toggles = useAutoApprovalToggles()

const onAutoApproveToggle = React.useCallback(
(key: AutoApproveSetting, value: boolean) => {
Expand Down Expand Up @@ -81,15 +69,9 @@ export const AutoApproveDropdown = ({ disabled = false, triggerClassName = "" }:
case "alwaysAllowSubtasks":
setAlwaysAllowSubtasks(value)
break
case "alwaysApproveResubmit":
setAlwaysApproveResubmit(value)
break
case "alwaysAllowFollowupQuestions":
setAlwaysAllowFollowupQuestions(value)
break
case "alwaysAllowUpdateTodoList":
setAlwaysAllowUpdateTodoList(value)
break
}

// If enabling any option, ensure autoApprovalEnabled is true.
Expand All @@ -107,9 +89,7 @@ export const AutoApproveDropdown = ({ disabled = false, triggerClassName = "" }:
setAlwaysAllowMcp,
setAlwaysAllowModeSwitch,
setAlwaysAllowSubtasks,
setAlwaysApproveResubmit,
setAlwaysAllowFollowupQuestions,
setAlwaysAllowUpdateTodoList,
setAutoApprovalEnabled,
],
)
Expand Down
5 changes: 0 additions & 5 deletions webview-ui/src/components/chat/ChatView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
mode,
setMode,
alwaysAllowModeSwitch,
alwaysAllowUpdateTodoList,
customModes,
telemetrySetting,
hasSystemPromptOverride,
Expand Down Expand Up @@ -1299,9 +1298,6 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
tool = { tool: "updateTodoList" }
}
}
if (tool.tool === "updateTodoList" && alwaysAllowUpdateTodoList) {
return false
}
return tool.tool === "updateTodoList" && enableButtons && !!primaryButtonText
})()
}
Expand All @@ -1320,7 +1316,6 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
handleBatchFileResponse,
currentFollowUpTs,
isFollowUpAutoApprovalPaused,
alwaysAllowUpdateTodoList,
enableButtons,
primaryButtonText,
],
Expand Down
Loading
Loading