mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 04:11:10 -05:00
feat: implement experimental features system
- Add experiments.ts to manage experimental features - Refactor experimental diff strategy into experiments system - Add UI components for managing experimental features - Add tests for experimental tools - Update system prompts to handle experiments
This commit is contained in:
@@ -61,6 +61,7 @@ import { OpenRouterHandler } from "../api/providers/openrouter"
|
||||
import { McpHub } from "../services/mcp/McpHub"
|
||||
import crypto from "crypto"
|
||||
import { insertGroups } from "./diff/insert-groups"
|
||||
import { EXPERIMENT_IDS } from "../shared/experiments"
|
||||
|
||||
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
|
||||
@@ -151,9 +152,8 @@ export class Cline {
|
||||
async updateDiffStrategy(experimentalDiffStrategy?: boolean) {
|
||||
// If not provided, get from current state
|
||||
if (experimentalDiffStrategy === undefined) {
|
||||
const { experimentalDiffStrategy: stateExperimentalDiffStrategy } =
|
||||
(await this.providerRef.deref()?.getState()) ?? {}
|
||||
experimentalDiffStrategy = stateExperimentalDiffStrategy ?? false
|
||||
const { experiments: stateExperimental } = (await this.providerRef.deref()?.getState()) ?? {}
|
||||
experimentalDiffStrategy = stateExperimental?.[EXPERIMENT_IDS.DIFF_STRATEGY] ?? false
|
||||
}
|
||||
this.diffStrategy = getDiffStrategy(this.api.getModel().id, this.fuzzyMatchThreshold, experimentalDiffStrategy)
|
||||
}
|
||||
@@ -810,7 +810,7 @@ export class Cline {
|
||||
})
|
||||
}
|
||||
|
||||
const { browserViewportSize, mode, customModePrompts, preferredLanguage } =
|
||||
const { browserViewportSize, mode, customModePrompts, preferredLanguage, experiments } =
|
||||
(await this.providerRef.deref()?.getState()) ?? {}
|
||||
const { customModes } = (await this.providerRef.deref()?.getState()) ?? {}
|
||||
const systemPrompt = await (async () => {
|
||||
@@ -831,6 +831,7 @@ export class Cline {
|
||||
this.customInstructions,
|
||||
preferredLanguage,
|
||||
this.diffEnabled,
|
||||
experiments,
|
||||
)
|
||||
})()
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import { defaultModeSlug, modes } from "../../../shared/modes"
|
||||
import "../../../utils/path"
|
||||
import { addCustomInstructions } from "../sections/custom-instructions"
|
||||
import * as modesSection from "../sections/modes"
|
||||
import { EXPERIMENT_IDS } from "../../../shared/experiments"
|
||||
|
||||
// Mock the sections
|
||||
jest.mock("../sections/modes", () => ({
|
||||
@@ -121,6 +122,7 @@ const createMockMcpHub = (): McpHub =>
|
||||
|
||||
describe("SYSTEM_PROMPT", () => {
|
||||
let mockMcpHub: McpHub
|
||||
let experiments: Record<string, boolean>
|
||||
|
||||
beforeAll(() => {
|
||||
// Ensure fs mock is properly initialized
|
||||
@@ -140,6 +142,10 @@ describe("SYSTEM_PROMPT", () => {
|
||||
"/mock/mcp/path",
|
||||
]
|
||||
dirs.forEach((dir) => mockFs._mockDirectories.add(dir))
|
||||
experiments = {
|
||||
[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: false,
|
||||
[EXPERIMENT_IDS.INSERT_BLOCK]: false,
|
||||
}
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -164,6 +170,10 @@ describe("SYSTEM_PROMPT", () => {
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
undefined, // globalCustomInstructions
|
||||
undefined, // preferredLanguage
|
||||
undefined, // diffEnabled
|
||||
experiments,
|
||||
)
|
||||
|
||||
expect(prompt).toMatchSnapshot()
|
||||
@@ -179,7 +189,11 @@ describe("SYSTEM_PROMPT", () => {
|
||||
"1280x800", // browserViewportSize
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
undefined, // customModes,
|
||||
undefined, // globalCustomInstructions
|
||||
undefined, // preferredLanguage
|
||||
undefined, // diffEnabled
|
||||
experiments,
|
||||
)
|
||||
|
||||
expect(prompt).toMatchSnapshot()
|
||||
@@ -197,7 +211,11 @@ describe("SYSTEM_PROMPT", () => {
|
||||
undefined, // browserViewportSize
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
undefined, // customModes,
|
||||
undefined, // globalCustomInstructions
|
||||
undefined, // preferredLanguage
|
||||
undefined, // diffEnabled
|
||||
experiments,
|
||||
)
|
||||
|
||||
expect(prompt).toMatchSnapshot()
|
||||
@@ -213,7 +231,11 @@ describe("SYSTEM_PROMPT", () => {
|
||||
undefined, // browserViewportSize
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
undefined, // customModes,
|
||||
undefined, // globalCustomInstructions
|
||||
undefined, // preferredLanguage
|
||||
undefined, // diffEnabled
|
||||
experiments,
|
||||
)
|
||||
|
||||
expect(prompt).toMatchSnapshot()
|
||||
@@ -229,7 +251,11 @@ describe("SYSTEM_PROMPT", () => {
|
||||
"900x600", // different viewport size
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
undefined, // customModes,
|
||||
undefined, // globalCustomInstructions
|
||||
undefined, // preferredLanguage
|
||||
undefined, // diffEnabled
|
||||
experiments,
|
||||
)
|
||||
|
||||
expect(prompt).toMatchSnapshot()
|
||||
@@ -249,6 +275,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
undefined, // globalCustomInstructions
|
||||
undefined, // preferredLanguage
|
||||
true, // diffEnabled
|
||||
experiments,
|
||||
)
|
||||
|
||||
expect(prompt).toContain("apply_diff")
|
||||
@@ -269,6 +296,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
undefined, // globalCustomInstructions
|
||||
undefined, // preferredLanguage
|
||||
false, // diffEnabled
|
||||
experiments,
|
||||
)
|
||||
|
||||
expect(prompt).not.toContain("apply_diff")
|
||||
@@ -289,6 +317,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
undefined, // globalCustomInstructions
|
||||
undefined, // preferredLanguage
|
||||
undefined, // diffEnabled
|
||||
experiments,
|
||||
)
|
||||
|
||||
expect(prompt).not.toContain("apply_diff")
|
||||
@@ -308,6 +337,8 @@ describe("SYSTEM_PROMPT", () => {
|
||||
undefined, // customModes
|
||||
undefined, // globalCustomInstructions
|
||||
"Spanish", // preferredLanguage
|
||||
undefined, // diffEnabled
|
||||
experiments,
|
||||
)
|
||||
|
||||
expect(prompt).toContain("Language Preference:")
|
||||
@@ -337,6 +368,9 @@ describe("SYSTEM_PROMPT", () => {
|
||||
undefined, // customModePrompts
|
||||
customModes, // customModes
|
||||
"Global instructions", // globalCustomInstructions
|
||||
undefined, // preferredLanguage
|
||||
undefined, // diffEnabled
|
||||
experiments,
|
||||
)
|
||||
|
||||
// Role definition should be at the top
|
||||
@@ -368,6 +402,10 @@ describe("SYSTEM_PROMPT", () => {
|
||||
defaultModeSlug,
|
||||
customModePrompts,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
experiments,
|
||||
)
|
||||
|
||||
// Role definition from promptComponent should be at the top
|
||||
@@ -394,18 +432,101 @@ describe("SYSTEM_PROMPT", () => {
|
||||
defaultModeSlug,
|
||||
customModePrompts,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
experiments,
|
||||
)
|
||||
|
||||
// Should use the default mode's role definition
|
||||
expect(prompt.indexOf(modes[0].roleDefinition)).toBeLessThan(prompt.indexOf("TOOL USE"))
|
||||
})
|
||||
|
||||
describe("experimental tools", () => {
|
||||
it("should disable experimental tools by default", async () => {
|
||||
const prompt = await SYSTEM_PROMPT(
|
||||
mockContext,
|
||||
"/test/path",
|
||||
false, // supportsComputerUse
|
||||
undefined, // mcpHub
|
||||
undefined, // diffStrategy
|
||||
undefined, // browserViewportSize
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
undefined, // globalCustomInstructions
|
||||
undefined, // preferredLanguage
|
||||
undefined, // diffEnabled
|
||||
experiments, // experiments - undefined should disable all experimental tools
|
||||
)
|
||||
|
||||
// Verify experimental tools are not included in the prompt
|
||||
expect(prompt).not.toContain(EXPERIMENT_IDS.SEARCH_AND_REPLACE)
|
||||
expect(prompt).not.toContain(EXPERIMENT_IDS.INSERT_BLOCK)
|
||||
})
|
||||
|
||||
it("should enable experimental tools when explicitly enabled", async () => {
|
||||
const experiments = {
|
||||
[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: true,
|
||||
[EXPERIMENT_IDS.INSERT_BLOCK]: true,
|
||||
}
|
||||
|
||||
const prompt = await SYSTEM_PROMPT(
|
||||
mockContext,
|
||||
"/test/path",
|
||||
false, // supportsComputerUse
|
||||
undefined, // mcpHub
|
||||
undefined, // diffStrategy
|
||||
undefined, // browserViewportSize
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
undefined, // globalCustomInstructions
|
||||
undefined, // preferredLanguage
|
||||
undefined, // diffEnabled
|
||||
experiments,
|
||||
)
|
||||
|
||||
// Verify experimental tools are included in the prompt when enabled
|
||||
expect(prompt).toContain(EXPERIMENT_IDS.SEARCH_AND_REPLACE)
|
||||
expect(prompt).toContain(EXPERIMENT_IDS.INSERT_BLOCK)
|
||||
})
|
||||
|
||||
it("should selectively enable experimental tools", async () => {
|
||||
const experiments = {
|
||||
[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: true,
|
||||
[EXPERIMENT_IDS.INSERT_BLOCK]: false,
|
||||
}
|
||||
|
||||
const prompt = await SYSTEM_PROMPT(
|
||||
mockContext,
|
||||
"/test/path",
|
||||
false, // supportsComputerUse
|
||||
undefined, // mcpHub
|
||||
undefined, // diffStrategy
|
||||
undefined, // browserViewportSize
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
undefined, // globalCustomInstructions
|
||||
undefined, // preferredLanguage
|
||||
undefined, // diffEnabled
|
||||
experiments,
|
||||
)
|
||||
|
||||
// Verify only enabled experimental tools are included
|
||||
expect(prompt).toContain(EXPERIMENT_IDS.SEARCH_AND_REPLACE)
|
||||
expect(prompt).not.toContain(EXPERIMENT_IDS.INSERT_BLOCK)
|
||||
})
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
jest.restoreAllMocks()
|
||||
})
|
||||
})
|
||||
|
||||
describe("addCustomInstructions", () => {
|
||||
let experiments: Record<string, boolean>
|
||||
beforeAll(() => {
|
||||
// Ensure fs mock is properly initialized
|
||||
const mockFs = jest.requireMock("fs/promises")
|
||||
@@ -417,6 +538,11 @@ describe("addCustomInstructions", () => {
|
||||
}
|
||||
throw new Error(`ENOENT: no such file or directory, mkdir '${path}'`)
|
||||
})
|
||||
|
||||
experiments = {
|
||||
[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: false,
|
||||
[EXPERIMENT_IDS.INSERT_BLOCK]: false,
|
||||
}
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -434,6 +560,10 @@ describe("addCustomInstructions", () => {
|
||||
"architect", // mode
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
experiments,
|
||||
)
|
||||
|
||||
expect(prompt).toMatchSnapshot()
|
||||
@@ -450,6 +580,10 @@ describe("addCustomInstructions", () => {
|
||||
"ask", // mode
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
experiments,
|
||||
)
|
||||
|
||||
expect(prompt).toMatchSnapshot()
|
||||
|
||||
@@ -39,6 +39,7 @@ async function generatePrompt(
|
||||
globalCustomInstructions?: string,
|
||||
preferredLanguage?: string,
|
||||
diffEnabled?: boolean,
|
||||
experiments?: Record<string, boolean>,
|
||||
): Promise<string> {
|
||||
if (!context) {
|
||||
throw new Error("Extension context is required for generating system prompt")
|
||||
@@ -68,6 +69,7 @@ ${getToolDescriptionsForMode(
|
||||
browserViewportSize,
|
||||
mcpHub,
|
||||
customModeConfigs,
|
||||
experiments,
|
||||
)}
|
||||
|
||||
${getToolUseGuidelinesSection()}
|
||||
@@ -102,6 +104,7 @@ export const SYSTEM_PROMPT = async (
|
||||
globalCustomInstructions?: string,
|
||||
preferredLanguage?: string,
|
||||
diffEnabled?: boolean,
|
||||
experiments?: Record<string, boolean>,
|
||||
): Promise<string> => {
|
||||
if (!context) {
|
||||
throw new Error("Extension context is required for generating system prompt")
|
||||
@@ -135,5 +138,6 @@ export const SYSTEM_PROMPT = async (
|
||||
globalCustomInstructions,
|
||||
preferredLanguage,
|
||||
diffEnabled,
|
||||
experiments,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ export function getToolDescriptionsForMode(
|
||||
browserViewportSize?: string,
|
||||
mcpHub?: McpHub,
|
||||
customModes?: ModeConfig[],
|
||||
experiments?: Record<string, boolean>,
|
||||
): string {
|
||||
const config = getModeConfig(mode, customModes)
|
||||
const args: ToolArgs = {
|
||||
@@ -64,7 +65,7 @@ export function getToolDescriptionsForMode(
|
||||
const toolGroup = TOOL_GROUPS[groupName]
|
||||
if (toolGroup) {
|
||||
toolGroup.forEach((tool) => {
|
||||
if (isToolAllowedForMode(tool as ToolName, mode, customModes ?? [])) {
|
||||
if (isToolAllowedForMode(tool as ToolName, mode, customModes ?? [], experiments ?? {})) {
|
||||
tools.add(tool)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -40,6 +40,12 @@ import { singleCompletionHandler } from "../../utils/single-completion-handler"
|
||||
import { getCommitInfo, searchCommits, getWorkingState } from "../../utils/git"
|
||||
import { ConfigManager } from "../config/ConfigManager"
|
||||
import { CustomModesManager } from "../config/CustomModesManager"
|
||||
import {
|
||||
EXPERIMENT_IDS,
|
||||
experimentConfigs,
|
||||
experiments as Experiments,
|
||||
experimentDefault,
|
||||
} from "../../shared/experiments"
|
||||
import { CustomSupportPrompts, supportPrompt } from "../../shared/support-prompt"
|
||||
|
||||
import { ACTION_NAMES } from "../CodeActionProvider"
|
||||
@@ -118,7 +124,7 @@ type GlobalStateKey =
|
||||
| "customModePrompts"
|
||||
| "customSupportPrompts"
|
||||
| "enhancementApiConfigId"
|
||||
| "experimentalDiffStrategy"
|
||||
| "experiments" // Map of experiment IDs to their enabled state
|
||||
| "autoApprovalEnabled"
|
||||
| "customModes" // Array of custom modes
|
||||
|
||||
@@ -339,7 +345,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
fuzzyMatchThreshold,
|
||||
mode,
|
||||
customInstructions: globalInstructions,
|
||||
experimentalDiffStrategy,
|
||||
experiments,
|
||||
} = await this.getState()
|
||||
|
||||
const modePrompt = customModePrompts?.[mode] as PromptComponent
|
||||
@@ -354,7 +360,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
task,
|
||||
images,
|
||||
undefined,
|
||||
experimentalDiffStrategy,
|
||||
Experiments.isEnabled(experiments, EXPERIMENT_IDS.DIFF_STRATEGY),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -367,7 +373,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
fuzzyMatchThreshold,
|
||||
mode,
|
||||
customInstructions: globalInstructions,
|
||||
experimentalDiffStrategy,
|
||||
experiments,
|
||||
} = await this.getState()
|
||||
|
||||
const modePrompt = customModePrompts?.[mode] as PromptComponent
|
||||
@@ -382,7 +388,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
undefined,
|
||||
undefined,
|
||||
historyItem,
|
||||
experimentalDiffStrategy,
|
||||
Experiments.isEnabled(experiments, EXPERIMENT_IDS.DIFF_STRATEGY),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1044,14 +1050,14 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
diffEnabled,
|
||||
mcpEnabled,
|
||||
fuzzyMatchThreshold,
|
||||
experimentalDiffStrategy,
|
||||
experiments,
|
||||
} = await this.getState()
|
||||
|
||||
// Create diffStrategy based on current model and settings
|
||||
const diffStrategy = getDiffStrategy(
|
||||
apiConfiguration.apiModelId || apiConfiguration.openRouterModelId || "",
|
||||
fuzzyMatchThreshold,
|
||||
experimentalDiffStrategy,
|
||||
Experiments.isEnabled(experiments, EXPERIMENT_IDS.DIFF_STRATEGY),
|
||||
)
|
||||
const cwd =
|
||||
vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) || ""
|
||||
@@ -1072,6 +1078,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
customInstructions,
|
||||
preferredLanguage,
|
||||
diffEnabled,
|
||||
experiments,
|
||||
)
|
||||
|
||||
await this.postMessageToWebview({
|
||||
@@ -1207,14 +1214,28 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
vscode.window.showErrorMessage("Failed to get list api configuration")
|
||||
}
|
||||
break
|
||||
case "experimentalDiffStrategy":
|
||||
await this.updateGlobalState("experimentalDiffStrategy", message.bool ?? false)
|
||||
// Update diffStrategy in current Cline instance if it exists
|
||||
if (this.cline) {
|
||||
await this.cline.updateDiffStrategy(message.bool ?? false)
|
||||
case "updateExperimental": {
|
||||
if (!message.values) {
|
||||
break
|
||||
}
|
||||
|
||||
const updatedExperiments = {
|
||||
...((await this.getGlobalState("experiments")) ?? experimentDefault),
|
||||
...message.values,
|
||||
}
|
||||
|
||||
await this.updateGlobalState("experiments", updatedExperiments)
|
||||
|
||||
// Update diffStrategy in current Cline instance if it exists
|
||||
if (message.values[EXPERIMENT_IDS.DIFF_STRATEGY] !== undefined && this.cline) {
|
||||
await this.cline.updateDiffStrategy(
|
||||
Experiments.isEnabled(updatedExperiments, EXPERIMENT_IDS.DIFF_STRATEGY),
|
||||
)
|
||||
}
|
||||
|
||||
await this.postStateToWebview()
|
||||
break
|
||||
}
|
||||
case "updateMcpTimeout":
|
||||
if (message.serverName && typeof message.timeout === "number") {
|
||||
try {
|
||||
@@ -1873,8 +1894,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
customModePrompts,
|
||||
customSupportPrompts,
|
||||
enhancementApiConfigId,
|
||||
experimentalDiffStrategy,
|
||||
autoApprovalEnabled,
|
||||
experiments,
|
||||
} = await this.getState()
|
||||
|
||||
const allowedCommands = vscode.workspace.getConfiguration("roo-cline").get<string[]>("allowedCommands") || []
|
||||
@@ -1914,9 +1935,9 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
customModePrompts: customModePrompts ?? {},
|
||||
customSupportPrompts: customSupportPrompts ?? {},
|
||||
enhancementApiConfigId,
|
||||
experimentalDiffStrategy: experimentalDiffStrategy ?? false,
|
||||
autoApprovalEnabled: autoApprovalEnabled ?? false,
|
||||
customModes: await this.customModesManager.getCustomModes(),
|
||||
experiments: experiments ?? experimentDefault,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2039,9 +2060,9 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
customModePrompts,
|
||||
customSupportPrompts,
|
||||
enhancementApiConfigId,
|
||||
experimentalDiffStrategy,
|
||||
autoApprovalEnabled,
|
||||
customModes,
|
||||
experiments,
|
||||
] = await Promise.all([
|
||||
this.getGlobalState("apiProvider") as Promise<ApiProvider | undefined>,
|
||||
this.getGlobalState("apiModelId") as Promise<string | undefined>,
|
||||
@@ -2109,9 +2130,9 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
this.getGlobalState("customModePrompts") as Promise<CustomModePrompts | undefined>,
|
||||
this.getGlobalState("customSupportPrompts") as Promise<CustomSupportPrompts | undefined>,
|
||||
this.getGlobalState("enhancementApiConfigId") as Promise<string | undefined>,
|
||||
this.getGlobalState("experimentalDiffStrategy") as Promise<boolean | undefined>,
|
||||
this.getGlobalState("autoApprovalEnabled") as Promise<boolean | undefined>,
|
||||
this.customModesManager.getCustomModes(),
|
||||
this.getGlobalState("experiments") as Promise<Record<string, boolean> | undefined>,
|
||||
])
|
||||
|
||||
let apiProvider: ApiProvider
|
||||
@@ -2225,7 +2246,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
customModePrompts: customModePrompts ?? {},
|
||||
customSupportPrompts: customSupportPrompts ?? {},
|
||||
enhancementApiConfigId,
|
||||
experimentalDiffStrategy: experimentalDiffStrategy ?? false,
|
||||
experiments: experiments ?? experimentDefault,
|
||||
autoApprovalEnabled: autoApprovalEnabled ?? false,
|
||||
customModes,
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { ExtensionMessage, ExtensionState } from "../../../shared/ExtensionMessa
|
||||
import { setSoundEnabled } from "../../../utils/sound"
|
||||
import { defaultModeSlug, modes } from "../../../shared/modes"
|
||||
import { addCustomInstructions } from "../../prompts/sections/custom-instructions"
|
||||
import { experimentDefault, experiments } from "../../../shared/experiments"
|
||||
|
||||
// Mock custom-instructions module
|
||||
const mockAddCustomInstructions = jest.fn()
|
||||
@@ -320,6 +321,7 @@ describe("ClineProvider", () => {
|
||||
requestDelaySeconds: 5,
|
||||
mode: defaultModeSlug,
|
||||
customModes: [],
|
||||
experiments: experimentDefault,
|
||||
}
|
||||
|
||||
const message: ExtensionMessage = {
|
||||
@@ -617,6 +619,7 @@ describe("ClineProvider", () => {
|
||||
mode: "code",
|
||||
diffEnabled: true,
|
||||
fuzzyMatchThreshold: 1.0,
|
||||
experiments: experimentDefault,
|
||||
} as any)
|
||||
|
||||
// Reset Cline mock
|
||||
@@ -636,7 +639,7 @@ describe("ClineProvider", () => {
|
||||
"Test task",
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
)
|
||||
})
|
||||
test("handles mode-specific custom instructions updates", async () => {
|
||||
@@ -887,6 +890,7 @@ describe("ClineProvider", () => {
|
||||
},
|
||||
mcpEnabled: true,
|
||||
mode: "code" as const,
|
||||
experiments: experimentDefault,
|
||||
} as any)
|
||||
|
||||
const handler1 = getMessageHandler()
|
||||
@@ -918,6 +922,7 @@ describe("ClineProvider", () => {
|
||||
},
|
||||
mcpEnabled: false,
|
||||
mode: "code" as const,
|
||||
experiments: experimentDefault,
|
||||
} as any)
|
||||
|
||||
const handler2 = getMessageHandler()
|
||||
@@ -985,6 +990,7 @@ describe("ClineProvider", () => {
|
||||
experimentalDiffStrategy: true,
|
||||
diffEnabled: true,
|
||||
fuzzyMatchThreshold: 0.8,
|
||||
experiments: experimentDefault,
|
||||
} as any)
|
||||
|
||||
// Mock SYSTEM_PROMPT to verify diffStrategy and diffEnabled are passed
|
||||
@@ -1012,6 +1018,7 @@ describe("ClineProvider", () => {
|
||||
undefined, // effectiveInstructions
|
||||
undefined, // preferredLanguage
|
||||
true, // diffEnabled
|
||||
experimentDefault,
|
||||
)
|
||||
|
||||
// Run the test again to verify it's consistent
|
||||
@@ -1034,6 +1041,7 @@ describe("ClineProvider", () => {
|
||||
experimentalDiffStrategy: true,
|
||||
diffEnabled: false,
|
||||
fuzzyMatchThreshold: 0.8,
|
||||
experiments: experimentDefault,
|
||||
} as any)
|
||||
|
||||
// Mock SYSTEM_PROMPT to verify diffEnabled is passed as false
|
||||
@@ -1061,6 +1069,7 @@ describe("ClineProvider", () => {
|
||||
undefined, // effectiveInstructions
|
||||
undefined, // preferredLanguage
|
||||
false, // diffEnabled
|
||||
experimentDefault,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1077,6 +1086,7 @@ describe("ClineProvider", () => {
|
||||
mode: "architect",
|
||||
mcpEnabled: false,
|
||||
browserViewportSize: "900x600",
|
||||
experiments: experimentDefault,
|
||||
} as any)
|
||||
|
||||
// Mock SYSTEM_PROMPT to call addCustomInstructions
|
||||
|
||||
Reference in New Issue
Block a user