mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 12:21:13 -05:00
feat: introduce experimental diff strategy toggle and enhance diff handling
- Added support for an experimental diff strategy in the Cline class, allowing users to opt for a new unified diff approach. - Updated the getDiffStrategy function to accommodate the experimental strategy, adjusting the fuzzy match threshold accordingly. - Integrated experimentalDiffStrategy into the global state management, enabling persistence across sessions. - Enhanced the ClineProvider and related components to handle the new experimental strategy, including UI updates for user settings. - Improved task history management to include the experimentalDiffStrategy setting, ensuring consistency in task execution. - Updated relevant interfaces and types to reflect the new experimentalDiffStrategy property.
This commit is contained in:
@@ -51,6 +51,7 @@ import { detectCodeOmission } from "../integrations/editor/detect-omission"
|
||||
import { BrowserSession } from "../services/browser/BrowserSession"
|
||||
import { OpenRouterHandler } from "../api/providers/openrouter"
|
||||
import { McpHub } from "../services/mcp/McpHub"
|
||||
import crypto from "crypto"
|
||||
|
||||
const cwd =
|
||||
vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution
|
||||
@@ -105,26 +106,30 @@ export class Cline {
|
||||
task?: string | undefined,
|
||||
images?: string[] | undefined,
|
||||
historyItem?: HistoryItem | undefined,
|
||||
experimentalDiffStrategy?: boolean,
|
||||
) {
|
||||
this.providerRef = new WeakRef(provider)
|
||||
this.taskId = crypto.randomUUID()
|
||||
this.api = buildApiHandler(apiConfiguration)
|
||||
this.terminalManager = new TerminalManager()
|
||||
this.urlContentFetcher = new UrlContentFetcher(provider.context)
|
||||
this.browserSession = new BrowserSession(provider.context)
|
||||
this.diffViewProvider = new DiffViewProvider(cwd)
|
||||
this.customInstructions = customInstructions
|
||||
this.diffEnabled = enableDiff ?? false
|
||||
if (this.diffEnabled && this.api.getModel().id) {
|
||||
this.diffStrategy = getDiffStrategy(this.api.getModel().id, fuzzyMatchThreshold ?? 1.0)
|
||||
}
|
||||
|
||||
// Prioritize experimentalDiffStrategy from history item if available
|
||||
const effectiveExperimentalDiffStrategy = historyItem?.experimentalDiffStrategy ?? experimentalDiffStrategy
|
||||
this.diffStrategy = getDiffStrategy(this.api.getModel().id, fuzzyMatchThreshold, effectiveExperimentalDiffStrategy)
|
||||
this.diffViewProvider = new DiffViewProvider(cwd)
|
||||
this.providerRef = new WeakRef(provider)
|
||||
|
||||
if (historyItem) {
|
||||
this.taskId = historyItem.id
|
||||
this.resumeTaskFromHistory()
|
||||
} else if (task || images) {
|
||||
this.taskId = Date.now().toString()
|
||||
}
|
||||
|
||||
if (task || images) {
|
||||
this.startTask(task, images)
|
||||
} else {
|
||||
throw new Error("Either historyItem or task/images must be provided")
|
||||
} else if (historyItem) {
|
||||
this.resumeTaskFromHistory()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,10 +7,14 @@ import { NewUnifiedDiffStrategy } from './strategies/new-unified'
|
||||
* @param model The name of the model being used (e.g., 'gpt-4', 'claude-3-opus')
|
||||
* @returns The appropriate diff strategy for the model
|
||||
*/
|
||||
export function getDiffStrategy(model: string, fuzzyMatchThreshold?: number): DiffStrategy {
|
||||
// For now, return SearchReplaceDiffStrategy for all models
|
||||
// This architecture allows for future optimizations based on model capabilities
|
||||
return new NewUnifiedDiffStrategy()
|
||||
export function getDiffStrategy(model: string, fuzzyMatchThreshold?: number, experimentalDiffStrategy?: boolean): DiffStrategy {
|
||||
if (experimentalDiffStrategy) {
|
||||
// Use the fuzzyMatchThreshold with a minimum of 0.8 (80%)
|
||||
const threshold = Math.max(fuzzyMatchThreshold ?? 1.0, 0.8)
|
||||
return new NewUnifiedDiffStrategy(threshold)
|
||||
}
|
||||
// Default to the stable SearchReplaceDiffStrategy
|
||||
return new SearchReplaceDiffStrategy()
|
||||
}
|
||||
|
||||
export type { DiffStrategy }
|
||||
|
||||
@@ -85,6 +85,7 @@ type GlobalStateKey =
|
||||
| "mcpEnabled"
|
||||
| "alwaysApproveResubmit"
|
||||
| "requestDelaySeconds"
|
||||
| "experimentalDiffStrategy"
|
||||
export const GlobalFileNames = {
|
||||
apiConversationHistory: "api_conversation_history.json",
|
||||
uiMessages: "ui_messages.json",
|
||||
@@ -233,7 +234,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
apiConfiguration,
|
||||
customInstructions,
|
||||
diffEnabled,
|
||||
fuzzyMatchThreshold
|
||||
fuzzyMatchThreshold,
|
||||
experimentalDiffStrategy
|
||||
} = await this.getState()
|
||||
|
||||
this.cline = new Cline(
|
||||
@@ -243,7 +245,9 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
diffEnabled,
|
||||
fuzzyMatchThreshold,
|
||||
task,
|
||||
images
|
||||
images,
|
||||
undefined,
|
||||
experimentalDiffStrategy
|
||||
)
|
||||
}
|
||||
|
||||
@@ -253,7 +257,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
apiConfiguration,
|
||||
customInstructions,
|
||||
diffEnabled,
|
||||
fuzzyMatchThreshold
|
||||
fuzzyMatchThreshold,
|
||||
experimentalDiffStrategy
|
||||
} = await this.getState()
|
||||
|
||||
this.cline = new Cline(
|
||||
@@ -264,7 +269,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
fuzzyMatchThreshold,
|
||||
undefined,
|
||||
undefined,
|
||||
historyItem
|
||||
historyItem,
|
||||
experimentalDiffStrategy
|
||||
)
|
||||
}
|
||||
|
||||
@@ -805,6 +811,10 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
}
|
||||
break
|
||||
}
|
||||
case "experimentalDiffStrategy":
|
||||
await this.updateGlobalState("experimentalDiffStrategy", message.bool ?? false)
|
||||
await this.postStateToWebview()
|
||||
break
|
||||
}
|
||||
},
|
||||
null,
|
||||
@@ -1155,7 +1165,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
uiMessagesFilePath: string
|
||||
apiConversationHistory: Anthropic.MessageParam[]
|
||||
}> {
|
||||
const history = ((await this.getGlobalState("taskHistory")) as HistoryItem[] | undefined) || []
|
||||
const history = (await this.getGlobalState("taskHistory") as HistoryItem[] | undefined) || []
|
||||
const historyItem = history.find((item) => item.id === id)
|
||||
if (historyItem) {
|
||||
const taskDirPath = path.join(this.context.globalStorageUri.fsPath, "tasks", id)
|
||||
@@ -1220,7 +1230,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
|
||||
async deleteTaskFromState(id: string) {
|
||||
// Remove the task from history
|
||||
const taskHistory = ((await this.getGlobalState("taskHistory")) as HistoryItem[]) || []
|
||||
const taskHistory = (await this.getGlobalState("taskHistory") as HistoryItem[]) || []
|
||||
const updatedTaskHistory = taskHistory.filter((task) => task.id !== id)
|
||||
await this.updateGlobalState("taskHistory", updatedTaskHistory)
|
||||
|
||||
@@ -1256,6 +1266,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
mcpEnabled,
|
||||
alwaysApproveResubmit,
|
||||
requestDelaySeconds,
|
||||
experimentalDiffStrategy,
|
||||
} = await this.getState()
|
||||
|
||||
const allowedCommands = vscode.workspace
|
||||
@@ -1290,6 +1301,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
mcpEnabled: mcpEnabled ?? true,
|
||||
alwaysApproveResubmit: alwaysApproveResubmit ?? false,
|
||||
requestDelaySeconds: requestDelaySeconds ?? 5,
|
||||
experimentalDiffStrategy: experimentalDiffStrategy ?? false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1397,6 +1409,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
mcpEnabled,
|
||||
alwaysApproveResubmit,
|
||||
requestDelaySeconds,
|
||||
experimentalDiffStrategy,
|
||||
] = await Promise.all([
|
||||
this.getGlobalState("apiProvider") as Promise<ApiProvider | undefined>,
|
||||
this.getGlobalState("apiModelId") as Promise<string | undefined>,
|
||||
@@ -1449,6 +1462,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
this.getGlobalState("mcpEnabled") as Promise<boolean | undefined>,
|
||||
this.getGlobalState("alwaysApproveResubmit") as Promise<boolean | undefined>,
|
||||
this.getGlobalState("requestDelaySeconds") as Promise<number | undefined>,
|
||||
this.getGlobalState("experimentalDiffStrategy") as Promise<boolean | undefined>,
|
||||
])
|
||||
|
||||
let apiProvider: ApiProvider
|
||||
@@ -1545,16 +1559,25 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
mcpEnabled: mcpEnabled ?? true,
|
||||
alwaysApproveResubmit: alwaysApproveResubmit ?? false,
|
||||
requestDelaySeconds: requestDelaySeconds ?? 5,
|
||||
experimentalDiffStrategy: experimentalDiffStrategy ?? false,
|
||||
}
|
||||
}
|
||||
|
||||
async updateTaskHistory(item: HistoryItem): Promise<HistoryItem[]> {
|
||||
const history = ((await this.getGlobalState("taskHistory")) as HistoryItem[]) || []
|
||||
const history = (await this.getGlobalState("taskHistory") as HistoryItem[] | undefined) || []
|
||||
const existingItemIndex = history.findIndex((h) => h.id === item.id)
|
||||
|
||||
// Ensure experimentalDiffStrategy is included from current settings if not already set
|
||||
const { experimentalDiffStrategy } = await this.getState() ?? {}
|
||||
const updatedItem = {
|
||||
...item,
|
||||
experimentalDiffStrategy: item.experimentalDiffStrategy ?? experimentalDiffStrategy
|
||||
}
|
||||
|
||||
if (existingItemIndex !== -1) {
|
||||
history[existingItemIndex] = item
|
||||
history[existingItemIndex] = updatedItem
|
||||
} else {
|
||||
history.push(item)
|
||||
history.push(updatedItem)
|
||||
}
|
||||
await this.updateGlobalState("taskHistory", history)
|
||||
return history
|
||||
|
||||
@@ -70,6 +70,7 @@ export interface ExtensionState {
|
||||
writeDelayMs: number
|
||||
terminalOutputLineLimit?: number
|
||||
mcpEnabled: boolean
|
||||
experimentalDiffStrategy?: boolean
|
||||
}
|
||||
|
||||
export interface ClineMessage {
|
||||
|
||||
@@ -7,4 +7,5 @@ export type HistoryItem = {
|
||||
cacheWrites?: number
|
||||
cacheReads?: number
|
||||
totalCost: number
|
||||
experimentalDiffStrategy?: boolean
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ export interface WebviewMessage {
|
||||
| "searchCommits"
|
||||
| "alwaysApproveResubmit"
|
||||
| "requestDelaySeconds"
|
||||
| "experimentalDiffStrategy"
|
||||
text?: string
|
||||
disabled?: boolean
|
||||
askResponse?: ClineAskResponse
|
||||
|
||||
Reference in New Issue
Block a user