From 8806beda202c91222453b2ead02331ce03fa0cc0 Mon Sep 17 00:00:00 2001 From: Daniel Steigman <35793213+NightTrek@users.noreply.github.com> Date: Wed, 20 Aug 2025 16:23:36 -0700 Subject: [PATCH] Change default strict plan mode setting to enabled (#5714) * Change default strict plan mode setting to enabled - Updated default from false to true in state-helpers.ts (primary backend default) - Updated fallback default in controller/index.ts (Task initialization) - Updated frontend default in ExtensionStateContext.tsx for consistency - Fixed linting issue with forEach callback return value - New users will now have strict plan mode enabled by default - Prevents file edits in Plan Mode, enforcing cleaner separation of planning vs execution * added changeset --------- Co-authored-by: pashpashpash --- .changeset/twelve-readers-fetch.md | 5 +++++ docs/docs.json | 2 +- src/core/api/index.ts | 2 +- src/core/api/transform/vercel-ai-gateway-stream.ts | 8 ++++---- src/core/controller/index.ts | 2 +- .../controller/models/refreshVercelAiGatewayModels.ts | 10 +++++----- src/core/controller/ui/initializeWebview.ts | 4 ++-- src/core/storage/utils/state-helpers.ts | 2 +- webview-ui/src/components/settings/ApiOptions.tsx | 4 ++-- .../src/components/settings/common/ModelInfoView.tsx | 2 +- webview-ui/src/context/ExtensionStateContext.tsx | 6 ++++-- 11 files changed, 27 insertions(+), 20 deletions(-) create mode 100644 .changeset/twelve-readers-fetch.md diff --git a/.changeset/twelve-readers-fetch.md b/.changeset/twelve-readers-fetch.md new file mode 100644 index 0000000000..5581374a02 --- /dev/null +++ b/.changeset/twelve-readers-fetch.md @@ -0,0 +1,5 @@ +--- +"claude-dev": patch +--- + +Set default plan mode to strict as the default diff --git a/docs/docs.json b/docs/docs.json index 2f3ae0bddd..9d03efed43 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -214,4 +214,4 @@ "copy" ] } -} \ No newline at end of file +} diff --git a/src/core/api/index.ts b/src/core/api/index.ts index 027605b6d1..3252f82124 100644 --- a/src/core/api/index.ts +++ b/src/core/api/index.ts @@ -29,10 +29,10 @@ import { RequestyHandler } from "./providers/requesty" import { SambanovaHandler } from "./providers/sambanova" import { SapAiCoreHandler } from "./providers/sapaicore" import { TogetherHandler } from "./providers/together" +import { VercelAIGatewayHandler } from "./providers/vercel-ai-gateway" import { VertexHandler } from "./providers/vertex" import { VsCodeLmHandler } from "./providers/vscode-lm" import { XAIHandler } from "./providers/xai" -import { VercelAIGatewayHandler } from "./providers/vercel-ai-gateway" import { ZAiHandler } from "./providers/zai" import { ApiStream, ApiStreamUsageChunk } from "./transform/stream" diff --git a/src/core/api/transform/vercel-ai-gateway-stream.ts b/src/core/api/transform/vercel-ai-gateway-stream.ts index 35b1b2010a..fdbf169103 100644 --- a/src/core/api/transform/vercel-ai-gateway-stream.ts +++ b/src/core/api/transform/vercel-ai-gateway-stream.ts @@ -1,7 +1,7 @@ -import { ModelInfo } from "@shared/api" -import { convertToOpenAiMessages } from "../transform/openai-format" import { Anthropic } from "@anthropic-ai/sdk" +import { ModelInfo } from "@shared/api" import OpenAI from "openai" +import { convertToOpenAiMessages } from "../transform/openai-format" export async function createVercelAIGatewayStream( client: OpenAI, @@ -10,7 +10,7 @@ export async function createVercelAIGatewayStream( model: { id: string; info: ModelInfo }, ) { // Convert Anthropic messages to OpenAI format - let openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ + const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ { role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages), ] @@ -33,7 +33,7 @@ export async function createVercelAIGatewayStream( } if (Array.isArray(msg.content)) { // Find the last text part in the message content - let lastTextPart = msg.content.filter((part) => part.type === "text").pop() + const lastTextPart = msg.content.filter((part) => part.type === "text").pop() if (lastTextPart && lastTextPart.text && lastTextPart.text.length > 0) { // @ts-ignore-next-line diff --git a/src/core/controller/index.ts b/src/core/controller/index.ts index 1f9995aa3f..3ba6776422 100644 --- a/src/core/controller/index.ts +++ b/src/core/controller/index.ts @@ -211,7 +211,7 @@ export class Controller { preferredLanguage, openaiReasoningEffort, mode, - strictPlanModeEnabled ?? false, + strictPlanModeEnabled ?? true, useAutoCondense ?? true, shellIntegrationTimeout, terminalReuseEnabled ?? true, diff --git a/src/core/controller/models/refreshVercelAiGatewayModels.ts b/src/core/controller/models/refreshVercelAiGatewayModels.ts index 0dadb309f2..4f49d1e8c1 100644 --- a/src/core/controller/models/refreshVercelAiGatewayModels.ts +++ b/src/core/controller/models/refreshVercelAiGatewayModels.ts @@ -1,11 +1,11 @@ -import { Controller } from ".." +import { GlobalFileNames } from "@core/storage/disk" import { EmptyRequest } from "@shared/proto/cline/common" import { OpenRouterCompatibleModelInfo, OpenRouterModelInfo } from "@shared/proto/cline/models" -import axios from "axios" -import path from "path" -import fs from "fs/promises" import { fileExistsAtPath } from "@utils/fs" -import { GlobalFileNames } from "@core/storage/disk" +import axios from "axios" +import fs from "fs/promises" +import path from "path" +import { Controller } from ".." /** * Refreshes Vercel AI Gateway models and returns updated model list diff --git a/src/core/controller/ui/initializeWebview.ts b/src/core/controller/ui/initializeWebview.ts index 3da9f57c00..2b78fd1c45 100644 --- a/src/core/controller/ui/initializeWebview.ts +++ b/src/core/controller/ui/initializeWebview.ts @@ -7,8 +7,8 @@ import { sendMcpMarketplaceCatalogEvent } from "../mcp/subscribeToMcpMarketplace import { refreshBasetenModels } from "../models/refreshBasetenModels" import { refreshGroqModels } from "../models/refreshGroqModels" import { refreshOpenRouterModels } from "../models/refreshOpenRouterModels" -import { sendOpenRouterModelsEvent } from "../models/subscribeToOpenRouterModels" import { refreshVercelAiGatewayModels } from "../models/refreshVercelAiGatewayModels" +import { sendOpenRouterModelsEvent } from "../models/subscribeToOpenRouterModels" /** * Initialize webview when it launches @@ -187,7 +187,7 @@ export async function initializeWebview(controller: Controller, _request: EmptyR // Shared models: update both plan and act modes const planModelId = apiConfiguration.planModeVercelAiGatewayModelId const actModelId = apiConfiguration.actModeVercelAiGatewayModelId - let updatedConfig = { ...apiConfiguration } + const updatedConfig = { ...apiConfiguration } // Update plan mode model info if we have a model ID if (planModelId && response.models[planModelId]) { diff --git a/src/core/storage/utils/state-helpers.ts b/src/core/storage/utils/state-helpers.ts index 7ccf8cf23b..c8248f4d47 100644 --- a/src/core/storage/utils/state-helpers.ts +++ b/src/core/storage/utils/state-helpers.ts @@ -384,7 +384,7 @@ export async function readStateFromDisk(context: ExtensionContext) { actModeVercelAiGatewayModelId, actModeVercelAiGatewayModelInfo, }, - strictPlanModeEnabled: strictPlanModeEnabled ?? false, + strictPlanModeEnabled: strictPlanModeEnabled ?? true, useAutoCondense: useAutoCondense ?? true, isNewUser: isNewUser ?? true, welcomeViewCompleted, diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 4c548bda82..1107dcfa2f 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -35,8 +35,8 @@ import { QwenProvider } from "./providers/QwenProvider" import { RequestyProvider } from "./providers/RequestyProvider" import { SambanovaProvider } from "./providers/SambanovaProvider" import { SapAiCoreProvider } from "./providers/SapAiCoreProvider" -import { VercelAIGatewayProvider } from "./providers/VercelAIGatewayProvider" import { TogetherProvider } from "./providers/TogetherProvider" +import { VercelAIGatewayProvider } from "./providers/VercelAIGatewayProvider" import { VertexProvider } from "./providers/VertexProvider" import { VSCodeLmProvider } from "./providers/VSCodeLmProvider" import { XaiProvider } from "./providers/XaiProvider" @@ -224,7 +224,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is )} {apiConfiguration && selectedProvider === "vercel-ai-gateway" && ( - + )} {apiConfiguration && selectedProvider === "sambanova" && ( diff --git a/webview-ui/src/components/settings/common/ModelInfoView.tsx b/webview-ui/src/components/settings/common/ModelInfoView.tsx index 5a48a25348..2dd91d8e74 100644 --- a/webview-ui/src/components/settings/common/ModelInfoView.tsx +++ b/webview-ui/src/components/settings/common/ModelInfoView.tsx @@ -1,5 +1,6 @@ import { geminiModels, ModelInfo } from "@shared/api" import { Fragment, useState } from "react" +import { useExtensionState } from "@/context/ExtensionStateContext" import { ModelDescriptionMarkdown } from "../OpenRouterModelPicker" import { formatPrice, @@ -10,7 +11,6 @@ import { supportsImages, supportsPromptCache, } from "../utils/pricingUtils" -import { useExtensionState } from "@/context/ExtensionStateContext" import { normalizeApiConfiguration } from "../utils/providerUtils" /** diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index d5dae1bd7a..3ca3efff69 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -200,7 +200,7 @@ export const ExtensionStateContextProvider: React.FC<{ isNewUser: false, welcomeViewCompleted: false, mcpResponsesCollapsed: false, // Default value (expanded), will be overwritten by extension state - strictPlanModeEnabled: false, + strictPlanModeEnabled: true, useAutoCondense: true, }) const [didHydrateState, setDidHydrateState] = useState(false) @@ -534,7 +534,9 @@ export const ExtensionStateContextProvider: React.FC<{ relinquishControlUnsubscribeRef.current = UiServiceClient.subscribeToRelinquishControl(EmptyRequest.create({}), { onResponse: () => { // Call all registered callbacks - relinquishControlCallbacks.current.forEach((callback) => callback()) + relinquishControlCallbacks.current.forEach((callback) => { + callback() + }) }, onError: (error) => { console.error("Error in relinquishControl subscription:", error)