mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-21 21:01:06 -05:00
Make fuzzy diff matching configurable (and default to off)
This commit is contained in:
@@ -67,6 +67,7 @@ export class Cline {
|
||||
private didEditFile: boolean = false
|
||||
customInstructions?: string
|
||||
diffStrategy?: DiffStrategy
|
||||
diffEnabled: boolean = false
|
||||
|
||||
apiConversationHistory: Anthropic.MessageParam[] = []
|
||||
clineMessages: ClineMessage[] = []
|
||||
@@ -97,10 +98,11 @@ export class Cline {
|
||||
provider: ClineProvider,
|
||||
apiConfiguration: ApiConfiguration,
|
||||
customInstructions?: string,
|
||||
diffEnabled?: boolean,
|
||||
task?: string,
|
||||
images?: string[],
|
||||
historyItem?: HistoryItem,
|
||||
enableDiff?: boolean,
|
||||
fuzzyMatchThreshold?: number,
|
||||
task?: string | undefined,
|
||||
images?: string[] | undefined,
|
||||
historyItem?: HistoryItem | undefined,
|
||||
) {
|
||||
this.providerRef = new WeakRef(provider)
|
||||
this.api = buildApiHandler(apiConfiguration)
|
||||
@@ -109,8 +111,9 @@ export class Cline {
|
||||
this.browserSession = new BrowserSession(provider.context)
|
||||
this.diffViewProvider = new DiffViewProvider(cwd)
|
||||
this.customInstructions = customInstructions
|
||||
if (diffEnabled && this.api.getModel().id) {
|
||||
this.diffStrategy = getDiffStrategy(this.api.getModel().id)
|
||||
this.diffEnabled = enableDiff ?? false
|
||||
if (this.diffEnabled && this.api.getModel().id) {
|
||||
this.diffStrategy = getDiffStrategy(this.api.getModel().id, fuzzyMatchThreshold ?? 1.0)
|
||||
}
|
||||
if (historyItem) {
|
||||
this.taskId = historyItem.id
|
||||
|
||||
@@ -248,7 +248,7 @@ describe('Cline', () => {
|
||||
// Setup mock API configuration
|
||||
mockApiConfig = {
|
||||
apiProvider: 'anthropic',
|
||||
apiModelId: 'claude-3-sonnet'
|
||||
apiModelId: 'claude-3-5-sonnet-20241022'
|
||||
};
|
||||
|
||||
// Mock provider methods
|
||||
@@ -278,20 +278,77 @@ describe('Cline', () => {
|
||||
mockProvider,
|
||||
mockApiConfig,
|
||||
'custom instructions',
|
||||
false, // diffEnabled
|
||||
'test task', // task
|
||||
undefined, // images
|
||||
undefined // historyItem
|
||||
false,
|
||||
0.95, // 95% threshold
|
||||
'test task'
|
||||
);
|
||||
|
||||
expect(cline.customInstructions).toBe('custom instructions');
|
||||
expect(cline.diffEnabled).toBe(false);
|
||||
});
|
||||
|
||||
it('should use default fuzzy match threshold when not provided', () => {
|
||||
const cline = new Cline(
|
||||
mockProvider,
|
||||
mockApiConfig,
|
||||
'custom instructions',
|
||||
true,
|
||||
undefined,
|
||||
'test task'
|
||||
);
|
||||
|
||||
expect(cline.diffEnabled).toBe(true);
|
||||
// The diff strategy should be created with default threshold (1.0)
|
||||
expect(cline.diffStrategy).toBeDefined();
|
||||
});
|
||||
|
||||
it('should use provided fuzzy match threshold', () => {
|
||||
const getDiffStrategySpy = jest.spyOn(require('../diff/DiffStrategy'), 'getDiffStrategy');
|
||||
|
||||
const cline = new Cline(
|
||||
mockProvider,
|
||||
mockApiConfig,
|
||||
'custom instructions',
|
||||
true,
|
||||
0.9, // 90% threshold
|
||||
'test task'
|
||||
);
|
||||
|
||||
expect(cline.diffEnabled).toBe(true);
|
||||
expect(cline.diffStrategy).toBeDefined();
|
||||
expect(getDiffStrategySpy).toHaveBeenCalledWith('claude-3-5-sonnet-20241022', 0.9);
|
||||
|
||||
getDiffStrategySpy.mockRestore();
|
||||
});
|
||||
|
||||
it('should pass default threshold to diff strategy when not provided', () => {
|
||||
const getDiffStrategySpy = jest.spyOn(require('../diff/DiffStrategy'), 'getDiffStrategy');
|
||||
|
||||
const cline = new Cline(
|
||||
mockProvider,
|
||||
mockApiConfig,
|
||||
'custom instructions',
|
||||
true,
|
||||
undefined,
|
||||
'test task'
|
||||
);
|
||||
|
||||
expect(cline.diffEnabled).toBe(true);
|
||||
expect(cline.diffStrategy).toBeDefined();
|
||||
expect(getDiffStrategySpy).toHaveBeenCalledWith('claude-3-5-sonnet-20241022', 1.0);
|
||||
|
||||
getDiffStrategySpy.mockRestore();
|
||||
});
|
||||
|
||||
it('should require either task or historyItem', () => {
|
||||
expect(() => {
|
||||
new Cline(
|
||||
mockProvider,
|
||||
mockApiConfig
|
||||
mockApiConfig,
|
||||
undefined, // customInstructions
|
||||
false, // diffEnabled
|
||||
undefined, // fuzzyMatchThreshold
|
||||
undefined // task
|
||||
);
|
||||
}).toThrow('Either historyItem or task/images must be provided');
|
||||
});
|
||||
|
||||
@@ -6,10 +6,10 @@ import { SearchReplaceDiffStrategy } from './strategies/search-replace'
|
||||
* @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): DiffStrategy {
|
||||
// For now, return SearchReplaceDiffStrategy for all models (with a fuzzy threshold of 0.9)
|
||||
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 SearchReplaceDiffStrategy(0.9)
|
||||
return new SearchReplaceDiffStrategy(fuzzyMatchThreshold ?? 1.0)
|
||||
}
|
||||
|
||||
export type { DiffStrategy }
|
||||
|
||||
@@ -58,7 +58,9 @@ export class SearchReplaceDiffStrategy implements DiffStrategy {
|
||||
private bufferLines: number;
|
||||
|
||||
constructor(fuzzyThreshold?: number, bufferLines?: number) {
|
||||
// Default to exact matching (1.0) unless fuzzy threshold specified
|
||||
// Use provided threshold or default to exact matching (1.0)
|
||||
// Note: fuzzyThreshold is inverted in UI (0% = 1.0, 10% = 0.9)
|
||||
// so we use it directly here
|
||||
this.fuzzyThreshold = fuzzyThreshold ?? 1.0;
|
||||
this.bufferLines = bufferLines ?? BUFFER_LINES;
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ type GlobalStateKey =
|
||||
| "diffEnabled"
|
||||
| "alwaysAllowMcp"
|
||||
| "browserLargeViewport"
|
||||
| "fuzzyMatchThreshold"
|
||||
|
||||
export const GlobalFileNames = {
|
||||
apiConversationHistory: "api_conversation_history.json",
|
||||
@@ -217,7 +218,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
const {
|
||||
apiConfiguration,
|
||||
customInstructions,
|
||||
diffEnabled
|
||||
diffEnabled,
|
||||
fuzzyMatchThreshold
|
||||
} = await this.getState()
|
||||
|
||||
this.cline = new Cline(
|
||||
@@ -225,6 +227,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
apiConfiguration,
|
||||
customInstructions,
|
||||
diffEnabled,
|
||||
fuzzyMatchThreshold,
|
||||
task,
|
||||
images
|
||||
)
|
||||
@@ -235,7 +238,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
const {
|
||||
apiConfiguration,
|
||||
customInstructions,
|
||||
diffEnabled
|
||||
diffEnabled,
|
||||
fuzzyMatchThreshold
|
||||
} = await this.getState()
|
||||
|
||||
this.cline = new Cline(
|
||||
@@ -243,6 +247,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
apiConfiguration,
|
||||
customInstructions,
|
||||
diffEnabled,
|
||||
fuzzyMatchThreshold,
|
||||
undefined,
|
||||
undefined,
|
||||
historyItem
|
||||
@@ -613,6 +618,10 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
await this.updateGlobalState("browserLargeViewport", browserLargeViewport)
|
||||
await this.postStateToWebview()
|
||||
break
|
||||
case "fuzzyMatchThreshold":
|
||||
await this.updateGlobalState("fuzzyMatchThreshold", message.value)
|
||||
await this.postStateToWebview()
|
||||
break
|
||||
}
|
||||
},
|
||||
null,
|
||||
@@ -1062,6 +1071,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
diffEnabled,
|
||||
soundVolume,
|
||||
browserLargeViewport,
|
||||
fuzzyMatchThreshold,
|
||||
] = await Promise.all([
|
||||
this.getGlobalState("apiProvider") as Promise<ApiProvider | undefined>,
|
||||
this.getGlobalState("apiModelId") as Promise<string | undefined>,
|
||||
@@ -1101,6 +1111,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
this.getGlobalState("diffEnabled") as Promise<boolean | undefined>,
|
||||
this.getGlobalState("soundVolume") as Promise<number | undefined>,
|
||||
this.getGlobalState("browserLargeViewport") as Promise<boolean | undefined>,
|
||||
this.getGlobalState("fuzzyMatchThreshold") as Promise<number | undefined>,
|
||||
])
|
||||
|
||||
let apiProvider: ApiProvider
|
||||
@@ -1158,6 +1169,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
diffEnabled: diffEnabled ?? false,
|
||||
soundVolume,
|
||||
browserLargeViewport: browserLargeViewport ?? false,
|
||||
fuzzyMatchThreshold: fuzzyMatchThreshold ?? 1.0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ export interface ExtensionState {
|
||||
soundVolume?: number
|
||||
diffEnabled?: boolean
|
||||
browserLargeViewport?: boolean
|
||||
fuzzyMatchThreshold?: number
|
||||
}
|
||||
|
||||
export interface ClineMessage {
|
||||
|
||||
@@ -39,6 +39,7 @@ export interface WebviewMessage {
|
||||
| "restartMcpServer"
|
||||
| "toggleToolAlwaysAllow"
|
||||
| "toggleMcpServer"
|
||||
| "fuzzyMatchThreshold"
|
||||
text?: string
|
||||
disabled?: boolean
|
||||
askResponse?: ClineAskResponse
|
||||
|
||||
Reference in New Issue
Block a user