(params: SwitchModeParams, task: Task, callbacks: ToolCallbacks)
| 15 | readonly name = "switch_mode" as const |
| 16 | |
| 17 | async execute(params: SwitchModeParams, task: Task, callbacks: ToolCallbacks): Promise<void> { |
| 18 | const { mode_slug, reason } = params |
| 19 | const { askApproval, handleError, pushToolResult } = callbacks |
| 20 | |
| 21 | try { |
| 22 | if (!mode_slug) { |
| 23 | task.consecutiveMistakeCount++ |
| 24 | task.recordToolError("switch_mode") |
| 25 | pushToolResult(await task.sayAndCreateMissingParamError("switch_mode", "mode_slug")) |
| 26 | return |
| 27 | } |
| 28 | |
| 29 | task.consecutiveMistakeCount = 0 |
| 30 | |
| 31 | // Verify the mode exists |
| 32 | const targetMode = getModeBySlug(mode_slug, (await task.providerRef.deref()?.getState())?.customModes) |
| 33 | |
| 34 | if (!targetMode) { |
| 35 | task.recordToolError("switch_mode") |
| 36 | task.didToolFailInCurrentTurn = true |
| 37 | pushToolResult(formatResponse.toolError(`Invalid mode: ${mode_slug}`)) |
| 38 | return |
| 39 | } |
| 40 | |
| 41 | // Check if already in requested mode |
| 42 | const currentMode = (await task.providerRef.deref()?.getState())?.mode ?? defaultModeSlug |
| 43 | |
| 44 | if (currentMode === mode_slug) { |
| 45 | task.recordToolError("switch_mode") |
| 46 | task.didToolFailInCurrentTurn = true |
| 47 | pushToolResult(`Already in ${targetMode.name} mode.`) |
| 48 | return |
| 49 | } |
| 50 | |
| 51 | const completeMessage = JSON.stringify({ tool: "switchMode", mode: mode_slug, reason }) |
| 52 | const didApprove = await askApproval("tool", completeMessage) |
| 53 | |
| 54 | if (!didApprove) { |
| 55 | return |
| 56 | } |
| 57 | |
| 58 | // Switch the mode using shared handler |
| 59 | await task.providerRef.deref()?.handleModeSwitch(mode_slug) |
| 60 | |
| 61 | pushToolResult( |
| 62 | `Successfully switched from ${getModeBySlug(currentMode)?.name ?? currentMode} mode to ${ |
| 63 | targetMode.name |
| 64 | } mode${reason ? ` because: ${reason}` : ""}.`, |
| 65 | ) |
| 66 | |
| 67 | await delay(500) // Delay to allow mode change to take effect before next tool is executed |
| 68 | } catch (error) { |
| 69 | await handleError("switching mode", error as Error) |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | override async handlePartial(task: Task, block: ToolUse<"switch_mode">): Promise<void> { |
| 74 | const mode_slug: string | undefined = block.params.mode_slug |
nothing calls this directly
no test coverage detected