mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 04:11:10 -05:00
refactor: separate mode and support prompts
- Rename customPrompts to customModePrompts for mode-specific prompts - Add new customSupportPrompts type for support action prompts - Update types to be more specific (CustomModePrompts and CustomSupportPrompts) - Fix all related tests and component implementations
This commit is contained in:
@@ -809,7 +809,7 @@ export class Cline {
|
||||
})
|
||||
}
|
||||
|
||||
const { browserViewportSize, mode, customPrompts, preferredLanguage } =
|
||||
const { browserViewportSize, mode, customModePrompts, preferredLanguage } =
|
||||
(await this.providerRef.deref()?.getState()) ?? {}
|
||||
const { customModes } = (await this.providerRef.deref()?.getState()) ?? {}
|
||||
const systemPrompt = await (async () => {
|
||||
@@ -825,7 +825,7 @@ export class Cline {
|
||||
this.diffStrategy,
|
||||
browserViewportSize,
|
||||
mode,
|
||||
customPrompts,
|
||||
customModePrompts,
|
||||
customModes,
|
||||
this.customInstructions,
|
||||
preferredLanguage,
|
||||
|
||||
@@ -162,7 +162,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
undefined, // diffStrategy
|
||||
undefined, // browserViewportSize
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customPrompts
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
)
|
||||
|
||||
@@ -178,7 +178,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
undefined, // diffStrategy
|
||||
"1280x800", // browserViewportSize
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customPrompts
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
)
|
||||
|
||||
@@ -196,7 +196,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
undefined, // diffStrategy
|
||||
undefined, // browserViewportSize
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customPrompts
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
)
|
||||
|
||||
@@ -212,7 +212,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
undefined, // diffStrategy
|
||||
undefined, // browserViewportSize
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customPrompts
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
)
|
||||
|
||||
@@ -228,7 +228,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
undefined, // diffStrategy
|
||||
"900x600", // different viewport size
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customPrompts
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
)
|
||||
|
||||
@@ -244,7 +244,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
new SearchReplaceDiffStrategy(), // Use actual diff strategy from the codebase
|
||||
undefined, // browserViewportSize
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customPrompts
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
undefined, // globalCustomInstructions
|
||||
undefined, // preferredLanguage
|
||||
@@ -264,7 +264,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
new SearchReplaceDiffStrategy(), // Use actual diff strategy from the codebase
|
||||
undefined, // browserViewportSize
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customPrompts
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
undefined, // globalCustomInstructions
|
||||
undefined, // preferredLanguage
|
||||
@@ -284,7 +284,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
new SearchReplaceDiffStrategy(), // Use actual diff strategy from the codebase
|
||||
undefined, // browserViewportSize
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customPrompts
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
undefined, // globalCustomInstructions
|
||||
undefined, // preferredLanguage
|
||||
@@ -304,7 +304,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
undefined, // diffStrategy
|
||||
undefined, // browserViewportSize
|
||||
defaultModeSlug, // mode
|
||||
undefined, // customPrompts
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
undefined, // globalCustomInstructions
|
||||
"Spanish", // preferredLanguage
|
||||
@@ -334,7 +334,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
undefined, // diffStrategy
|
||||
undefined, // browserViewportSize
|
||||
"custom-mode", // mode
|
||||
undefined, // customPrompts
|
||||
undefined, // customModePrompts
|
||||
customModes, // customModes
|
||||
"Global instructions", // globalCustomInstructions
|
||||
)
|
||||
@@ -351,7 +351,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
})
|
||||
|
||||
it("should use promptComponent roleDefinition when available", async () => {
|
||||
const customPrompts = {
|
||||
const customModePrompts = {
|
||||
[defaultModeSlug]: {
|
||||
roleDefinition: "Custom prompt role definition",
|
||||
customInstructions: "Custom prompt instructions",
|
||||
@@ -366,7 +366,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
undefined,
|
||||
undefined,
|
||||
defaultModeSlug,
|
||||
customPrompts,
|
||||
customModePrompts,
|
||||
undefined,
|
||||
)
|
||||
|
||||
@@ -377,7 +377,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
})
|
||||
|
||||
it("should fallback to modeConfig roleDefinition when promptComponent has no roleDefinition", async () => {
|
||||
const customPrompts = {
|
||||
const customModePrompts = {
|
||||
[defaultModeSlug]: {
|
||||
customInstructions: "Custom prompt instructions",
|
||||
// No roleDefinition provided
|
||||
@@ -392,7 +392,7 @@ describe("SYSTEM_PROMPT", () => {
|
||||
undefined,
|
||||
undefined,
|
||||
defaultModeSlug,
|
||||
customPrompts,
|
||||
customModePrompts,
|
||||
undefined,
|
||||
)
|
||||
|
||||
@@ -432,7 +432,7 @@ describe("addCustomInstructions", () => {
|
||||
undefined, // diffStrategy
|
||||
undefined, // browserViewportSize
|
||||
"architect", // mode
|
||||
undefined, // customPrompts
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
)
|
||||
|
||||
@@ -448,7 +448,7 @@ describe("addCustomInstructions", () => {
|
||||
undefined, // diffStrategy
|
||||
undefined, // browserViewportSize
|
||||
"ask", // mode
|
||||
undefined, // customPrompts
|
||||
undefined, // customModePrompts
|
||||
undefined, // customModes
|
||||
)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
Mode,
|
||||
modes,
|
||||
CustomPrompts,
|
||||
CustomModePrompts,
|
||||
PromptComponent,
|
||||
getRoleDefinition,
|
||||
defaultModeSlug,
|
||||
@@ -97,7 +97,7 @@ export const SYSTEM_PROMPT = async (
|
||||
diffStrategy?: DiffStrategy,
|
||||
browserViewportSize?: string,
|
||||
mode: Mode = defaultModeSlug,
|
||||
customPrompts?: CustomPrompts,
|
||||
customModePrompts?: CustomModePrompts,
|
||||
customModes?: ModeConfig[],
|
||||
globalCustomInstructions?: string,
|
||||
preferredLanguage?: string,
|
||||
@@ -115,7 +115,7 @@ export const SYSTEM_PROMPT = async (
|
||||
}
|
||||
|
||||
// Check if it's a custom mode
|
||||
const promptComponent = getPromptComponent(customPrompts?.[mode])
|
||||
const promptComponent = getPromptComponent(customModePrompts?.[mode])
|
||||
// Get full mode config from custom modes or fall back to built-in modes
|
||||
const currentMode = getModeBySlug(mode, customModes) || modes.find((m) => m.slug === mode) || modes[0]
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import { WebviewMessage } from "../../shared/WebviewMessage"
|
||||
import {
|
||||
Mode,
|
||||
modes,
|
||||
CustomPrompts,
|
||||
CustomModePrompts,
|
||||
PromptComponent,
|
||||
ModeConfig,
|
||||
defaultModeSlug,
|
||||
@@ -40,7 +40,7 @@ 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 { supportPrompt } from "../../shared/support-prompt"
|
||||
import { CustomSupportPrompts, supportPrompt } from "../../shared/support-prompt"
|
||||
|
||||
import { ACTION_NAMES } from "../CodeActionProvider"
|
||||
|
||||
@@ -111,7 +111,8 @@ type GlobalStateKey =
|
||||
| "vsCodeLmModelSelector"
|
||||
| "mode"
|
||||
| "modeApiConfigs"
|
||||
| "customPrompts"
|
||||
| "customModePrompts"
|
||||
| "customSupportPrompts"
|
||||
| "enhancementApiConfigId"
|
||||
| "experimentalDiffStrategy"
|
||||
| "autoApprovalEnabled"
|
||||
@@ -203,9 +204,9 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
return
|
||||
}
|
||||
|
||||
const { customPrompts } = await visibleProvider.getState()
|
||||
const { customSupportPrompts } = await visibleProvider.getState()
|
||||
|
||||
const prompt = supportPrompt.create(promptType, params, customPrompts)
|
||||
const prompt = supportPrompt.create(promptType, params, customSupportPrompts)
|
||||
|
||||
await visibleProvider.initClineWithTask(prompt)
|
||||
}
|
||||
@@ -296,7 +297,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
await this.clearTask()
|
||||
const {
|
||||
apiConfiguration,
|
||||
customPrompts,
|
||||
customModePrompts,
|
||||
diffEnabled,
|
||||
fuzzyMatchThreshold,
|
||||
mode,
|
||||
@@ -304,7 +305,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
experimentalDiffStrategy,
|
||||
} = await this.getState()
|
||||
|
||||
const modePrompt = customPrompts?.[mode] as PromptComponent
|
||||
const modePrompt = customModePrompts?.[mode] as PromptComponent
|
||||
const effectiveInstructions = [globalInstructions, modePrompt?.customInstructions].filter(Boolean).join("\n\n")
|
||||
|
||||
this.cline = new Cline(
|
||||
@@ -324,7 +325,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
await this.clearTask()
|
||||
const {
|
||||
apiConfiguration,
|
||||
customPrompts,
|
||||
customModePrompts,
|
||||
diffEnabled,
|
||||
fuzzyMatchThreshold,
|
||||
mode,
|
||||
@@ -332,7 +333,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
experimentalDiffStrategy,
|
||||
} = await this.getState()
|
||||
|
||||
const modePrompt = customPrompts?.[mode] as PromptComponent
|
||||
const modePrompt = customModePrompts?.[mode] as PromptComponent
|
||||
const effectiveInstructions = [globalInstructions, modePrompt?.customInstructions].filter(Boolean).join("\n\n")
|
||||
|
||||
this.cline = new Cline(
|
||||
@@ -817,14 +818,14 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
return
|
||||
}
|
||||
|
||||
const existingPrompts = (await this.getGlobalState("customPrompts")) || {}
|
||||
const existingPrompts = (await this.getGlobalState("customSupportPrompts")) || {}
|
||||
|
||||
const updatedPrompts = {
|
||||
...existingPrompts,
|
||||
...message.values,
|
||||
}
|
||||
|
||||
await this.updateGlobalState("customPrompts", updatedPrompts)
|
||||
await this.updateGlobalState("customSupportPrompts", updatedPrompts)
|
||||
await this.postStateToWebview()
|
||||
} catch (error) {
|
||||
console.error("Error update support prompt:", error)
|
||||
@@ -837,10 +838,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
return
|
||||
}
|
||||
|
||||
const existingPrompts = ((await this.getGlobalState("customPrompts")) || {}) as Record<
|
||||
string,
|
||||
any
|
||||
>
|
||||
const existingPrompts = ((await this.getGlobalState("customSupportPrompts")) ||
|
||||
{}) as Record<string, any>
|
||||
|
||||
const updatedPrompts = {
|
||||
...existingPrompts,
|
||||
@@ -848,7 +847,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
|
||||
updatedPrompts[message.text] = undefined
|
||||
|
||||
await this.updateGlobalState("customPrompts", updatedPrompts)
|
||||
await this.updateGlobalState("customSupportPrompts", updatedPrompts)
|
||||
await this.postStateToWebview()
|
||||
} catch (error) {
|
||||
console.error("Error reset support prompt:", error)
|
||||
@@ -857,21 +856,21 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
break
|
||||
case "updatePrompt":
|
||||
if (message.promptMode && message.customPrompt !== undefined) {
|
||||
const existingPrompts = (await this.getGlobalState("customPrompts")) || {}
|
||||
const existingPrompts = (await this.getGlobalState("customModePrompts")) || {}
|
||||
|
||||
const updatedPrompts = {
|
||||
...existingPrompts,
|
||||
[message.promptMode]: message.customPrompt,
|
||||
}
|
||||
|
||||
await this.updateGlobalState("customPrompts", updatedPrompts)
|
||||
await this.updateGlobalState("customModePrompts", updatedPrompts)
|
||||
|
||||
// Get current state and explicitly include customPrompts
|
||||
// Get current state and explicitly include customModePrompts
|
||||
const currentState = await this.getState()
|
||||
|
||||
const stateWithPrompts = {
|
||||
...currentState,
|
||||
customPrompts: updatedPrompts,
|
||||
customModePrompts: updatedPrompts,
|
||||
}
|
||||
|
||||
// Post state with prompts
|
||||
@@ -981,8 +980,12 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
case "enhancePrompt":
|
||||
if (message.text) {
|
||||
try {
|
||||
const { apiConfiguration, customPrompts, listApiConfigMeta, enhancementApiConfigId } =
|
||||
await this.getState()
|
||||
const {
|
||||
apiConfiguration,
|
||||
customSupportPrompts,
|
||||
listApiConfigMeta,
|
||||
enhancementApiConfigId,
|
||||
} = await this.getState()
|
||||
|
||||
// Try to get enhancement config first, fall back to current config
|
||||
let configToUse: ApiConfiguration = apiConfiguration
|
||||
@@ -1003,7 +1006,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
{
|
||||
userInput: message.text,
|
||||
},
|
||||
customPrompts,
|
||||
customSupportPrompts,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -1024,7 +1027,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
try {
|
||||
const {
|
||||
apiConfiguration,
|
||||
customPrompts,
|
||||
customModePrompts,
|
||||
customInstructions,
|
||||
preferredLanguage,
|
||||
browserViewportSize,
|
||||
@@ -1054,7 +1057,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
diffStrategy,
|
||||
browserViewportSize ?? "900x600",
|
||||
mode,
|
||||
customPrompts,
|
||||
customModePrompts,
|
||||
customModes,
|
||||
customInstructions,
|
||||
preferredLanguage,
|
||||
@@ -1802,7 +1805,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
currentApiConfigName,
|
||||
listApiConfigMeta,
|
||||
mode,
|
||||
customPrompts,
|
||||
customModePrompts,
|
||||
customSupportPrompts,
|
||||
enhancementApiConfigId,
|
||||
experimentalDiffStrategy,
|
||||
autoApprovalEnabled,
|
||||
@@ -1841,7 +1845,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
currentApiConfigName: currentApiConfigName ?? "default",
|
||||
listApiConfigMeta: listApiConfigMeta ?? [],
|
||||
mode: mode ?? defaultModeSlug,
|
||||
customPrompts: customPrompts ?? {},
|
||||
customModePrompts: customModePrompts ?? {},
|
||||
customSupportPrompts: customSupportPrompts ?? {},
|
||||
enhancementApiConfigId,
|
||||
experimentalDiffStrategy: experimentalDiffStrategy ?? false,
|
||||
autoApprovalEnabled: autoApprovalEnabled ?? false,
|
||||
@@ -1961,7 +1966,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
vsCodeLmModelSelector,
|
||||
mode,
|
||||
modeApiConfigs,
|
||||
customPrompts,
|
||||
customModePrompts,
|
||||
customSupportPrompts,
|
||||
enhancementApiConfigId,
|
||||
experimentalDiffStrategy,
|
||||
autoApprovalEnabled,
|
||||
@@ -2026,7 +2032,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
this.getGlobalState("vsCodeLmModelSelector") as Promise<vscode.LanguageModelChatSelector | undefined>,
|
||||
this.getGlobalState("mode") as Promise<Mode | undefined>,
|
||||
this.getGlobalState("modeApiConfigs") as Promise<Record<Mode, string> | undefined>,
|
||||
this.getGlobalState("customPrompts") as Promise<CustomPrompts | undefined>,
|
||||
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>,
|
||||
@@ -2137,7 +2144,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
currentApiConfigName: currentApiConfigName ?? "default",
|
||||
listApiConfigMeta: listApiConfigMeta ?? [],
|
||||
modeApiConfigs: modeApiConfigs ?? ({} as Record<Mode, string>),
|
||||
customPrompts: customPrompts ?? {},
|
||||
customModePrompts: customModePrompts ?? {},
|
||||
customSupportPrompts: customSupportPrompts ?? {},
|
||||
enhancementApiConfigId,
|
||||
experimentalDiffStrategy: experimentalDiffStrategy ?? false,
|
||||
autoApprovalEnabled: autoApprovalEnabled ?? false,
|
||||
|
||||
@@ -555,7 +555,7 @@ describe("ClineProvider", () => {
|
||||
architect: "existing architect prompt",
|
||||
}
|
||||
;(mockContext.globalState.get as jest.Mock).mockImplementation((key: string) => {
|
||||
if (key === "customPrompts") {
|
||||
if (key === "customModePrompts") {
|
||||
return existingPrompts
|
||||
}
|
||||
return undefined
|
||||
@@ -569,7 +569,7 @@ describe("ClineProvider", () => {
|
||||
})
|
||||
|
||||
// Verify state was updated correctly
|
||||
expect(mockContext.globalState.update).toHaveBeenCalledWith("customPrompts", {
|
||||
expect(mockContext.globalState.update).toHaveBeenCalledWith("customModePrompts", {
|
||||
...existingPrompts,
|
||||
code: "new code prompt",
|
||||
})
|
||||
@@ -579,7 +579,7 @@ describe("ClineProvider", () => {
|
||||
expect.objectContaining({
|
||||
type: "state",
|
||||
state: expect.objectContaining({
|
||||
customPrompts: {
|
||||
customModePrompts: {
|
||||
...existingPrompts,
|
||||
code: "new code prompt",
|
||||
},
|
||||
@@ -588,17 +588,17 @@ describe("ClineProvider", () => {
|
||||
)
|
||||
})
|
||||
|
||||
test("customPrompts defaults to empty object", async () => {
|
||||
// Mock globalState.get to return undefined for customPrompts
|
||||
test("customModePrompts defaults to empty object", async () => {
|
||||
// Mock globalState.get to return undefined for customModePrompts
|
||||
;(mockContext.globalState.get as jest.Mock).mockImplementation((key: string) => {
|
||||
if (key === "customPrompts") {
|
||||
if (key === "customModePrompts") {
|
||||
return undefined
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
const state = await provider.getState()
|
||||
expect(state.customPrompts).toEqual({})
|
||||
expect(state.customModePrompts).toEqual({})
|
||||
})
|
||||
|
||||
test("uses mode-specific custom instructions in Cline initialization", async () => {
|
||||
@@ -611,7 +611,7 @@ describe("ClineProvider", () => {
|
||||
|
||||
jest.spyOn(provider, "getState").mockResolvedValue({
|
||||
apiConfiguration: mockApiConfig,
|
||||
customPrompts: {
|
||||
customModePrompts: {
|
||||
code: { customInstructions: modeCustomInstructions },
|
||||
},
|
||||
mode: "code",
|
||||
@@ -651,7 +651,7 @@ describe("ClineProvider", () => {
|
||||
},
|
||||
}
|
||||
mockContext.globalState.get = jest.fn((key: string) => {
|
||||
if (key === "customPrompts") {
|
||||
if (key === "customModePrompts") {
|
||||
return existingPrompts
|
||||
}
|
||||
return undefined
|
||||
@@ -668,7 +668,7 @@ describe("ClineProvider", () => {
|
||||
})
|
||||
|
||||
// Verify state was updated correctly
|
||||
expect(mockContext.globalState.update).toHaveBeenCalledWith("customPrompts", {
|
||||
expect(mockContext.globalState.update).toHaveBeenCalledWith("customModePrompts", {
|
||||
code: {
|
||||
roleDefinition: "Code role",
|
||||
customInstructions: "New instructions",
|
||||
@@ -978,7 +978,7 @@ describe("ClineProvider", () => {
|
||||
apiModelId: "test-model",
|
||||
openRouterModelInfo: { supportsComputerUse: true },
|
||||
},
|
||||
customPrompts: {},
|
||||
customModePrompts: {},
|
||||
mode: "code",
|
||||
mcpEnabled: false,
|
||||
browserViewportSize: "900x600",
|
||||
@@ -1007,7 +1007,7 @@ describe("ClineProvider", () => {
|
||||
}),
|
||||
"900x600", // browserViewportSize
|
||||
"code", // mode
|
||||
{}, // customPrompts
|
||||
{}, // customModePrompts
|
||||
{}, // customModes
|
||||
undefined, // effectiveInstructions
|
||||
undefined, // preferredLanguage
|
||||
@@ -1027,7 +1027,7 @@ describe("ClineProvider", () => {
|
||||
apiModelId: "test-model",
|
||||
openRouterModelInfo: { supportsComputerUse: true },
|
||||
},
|
||||
customPrompts: {},
|
||||
customModePrompts: {},
|
||||
mode: "code",
|
||||
mcpEnabled: false,
|
||||
browserViewportSize: "900x600",
|
||||
@@ -1056,7 +1056,7 @@ describe("ClineProvider", () => {
|
||||
}),
|
||||
"900x600", // browserViewportSize
|
||||
"code", // mode
|
||||
{}, // customPrompts
|
||||
{}, // customModePrompts
|
||||
{}, // customModes
|
||||
undefined, // effectiveInstructions
|
||||
undefined, // preferredLanguage
|
||||
@@ -1071,7 +1071,7 @@ describe("ClineProvider", () => {
|
||||
apiProvider: "openrouter",
|
||||
openRouterModelInfo: { supportsComputerUse: true },
|
||||
},
|
||||
customPrompts: {
|
||||
customModePrompts: {
|
||||
architect: { customInstructions: "Architect mode instructions" },
|
||||
},
|
||||
mode: "architect",
|
||||
|
||||
@@ -4,7 +4,8 @@ import { ApiConfiguration, ApiProvider, ModelInfo } from "./api"
|
||||
import { HistoryItem } from "./HistoryItem"
|
||||
import { McpServer } from "./mcp"
|
||||
import { GitCommit } from "../utils/git"
|
||||
import { Mode, CustomPrompts, ModeConfig } from "./modes"
|
||||
import { Mode, CustomModePrompts, ModeConfig } from "./modes"
|
||||
import { CustomSupportPrompts } from "./support-prompt"
|
||||
|
||||
export interface LanguageModelChatSelector {
|
||||
vendor?: string
|
||||
@@ -82,7 +83,8 @@ export interface ExtensionState {
|
||||
currentApiConfigName?: string
|
||||
listApiConfigMeta?: ApiConfigMeta[]
|
||||
customInstructions?: string
|
||||
customPrompts?: CustomPrompts
|
||||
customModePrompts?: CustomModePrompts
|
||||
customSupportPrompts?: CustomSupportPrompts
|
||||
alwaysAllowReadOnly?: boolean
|
||||
alwaysAllowWrite?: boolean
|
||||
alwaysAllowExecute?: boolean
|
||||
|
||||
@@ -97,18 +97,18 @@ describe("Code Action Prompts", () => {
|
||||
|
||||
it("should return custom template when provided", () => {
|
||||
const customTemplate = "Custom template for explaining code"
|
||||
const customPrompts = {
|
||||
const customSupportPrompts = {
|
||||
EXPLAIN: customTemplate,
|
||||
}
|
||||
const template = supportPrompt.get(customPrompts, "EXPLAIN")
|
||||
const template = supportPrompt.get(customSupportPrompts, "EXPLAIN")
|
||||
expect(template).toBe(customTemplate)
|
||||
})
|
||||
|
||||
it("should return default template when custom prompts does not include type", () => {
|
||||
const customPrompts = {
|
||||
const customSupportPrompts = {
|
||||
SOMETHING_ELSE: "Other template",
|
||||
}
|
||||
const template = supportPrompt.get(customPrompts, "EXPLAIN")
|
||||
const template = supportPrompt.get(customSupportPrompts, "EXPLAIN")
|
||||
expect(template).toBe(supportPrompt.default.EXPLAIN)
|
||||
})
|
||||
})
|
||||
@@ -116,7 +116,7 @@ describe("Code Action Prompts", () => {
|
||||
describe("create with custom prompts", () => {
|
||||
it("should use custom template when provided", () => {
|
||||
const customTemplate = "Custom template for ${filePath}"
|
||||
const customPrompts = {
|
||||
const customSupportPrompts = {
|
||||
EXPLAIN: customTemplate,
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ describe("Code Action Prompts", () => {
|
||||
filePath: testFilePath,
|
||||
selectedText: testCode,
|
||||
},
|
||||
customPrompts,
|
||||
customSupportPrompts,
|
||||
)
|
||||
|
||||
expect(prompt).toContain(`Custom template for ${testFilePath}`)
|
||||
@@ -134,7 +134,7 @@ describe("Code Action Prompts", () => {
|
||||
})
|
||||
|
||||
it("should use default template when custom prompts does not include type", () => {
|
||||
const customPrompts = {
|
||||
const customSupportPrompts = {
|
||||
EXPLAIN: "Other template",
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ describe("Code Action Prompts", () => {
|
||||
filePath: testFilePath,
|
||||
selectedText: testCode,
|
||||
},
|
||||
customPrompts,
|
||||
customSupportPrompts,
|
||||
)
|
||||
|
||||
expect(prompt).toContain("Other template")
|
||||
|
||||
@@ -18,8 +18,8 @@ export type PromptComponent = {
|
||||
customInstructions?: string
|
||||
}
|
||||
|
||||
export type CustomPrompts = {
|
||||
[key: string]: PromptComponent | undefined | string
|
||||
export type CustomModePrompts = {
|
||||
[key: string]: PromptComponent | undefined
|
||||
}
|
||||
|
||||
// Helper to get all tools for a mode
|
||||
@@ -141,7 +141,7 @@ export function isToolAllowedForMode(
|
||||
}
|
||||
|
||||
// Create the mode-specific default prompts
|
||||
export const defaultPrompts: Readonly<CustomPrompts> = Object.freeze(
|
||||
export const defaultPrompts: Readonly<CustomModePrompts> = Object.freeze(
|
||||
Object.fromEntries(modes.map((mode) => [mode.slug, { roleDefinition: mode.roleDefinition }])),
|
||||
)
|
||||
|
||||
|
||||
@@ -84,11 +84,11 @@ type SupportPromptType = keyof typeof defaultTemplates
|
||||
|
||||
export const supportPrompt = {
|
||||
default: defaultTemplates,
|
||||
get: (customPrompts: Record<string, any> | undefined, type: SupportPromptType): string => {
|
||||
return customPrompts?.[type] ?? defaultTemplates[type]
|
||||
get: (customSupportPrompts: Record<string, any> | undefined, type: SupportPromptType): string => {
|
||||
return customSupportPrompts?.[type] ?? defaultTemplates[type]
|
||||
},
|
||||
create: (type: SupportPromptType, params: PromptParams, customPrompts?: Record<string, any>): string => {
|
||||
const template = supportPrompt.get(customPrompts, type)
|
||||
create: (type: SupportPromptType, params: PromptParams, customSupportPrompts?: Record<string, any>): string => {
|
||||
const template = supportPrompt.get(customSupportPrompts, type)
|
||||
return createPrompt(template, params)
|
||||
},
|
||||
} as const
|
||||
@@ -102,3 +102,7 @@ export const supportPromptLabels: Record<SupportPromptType, string> = {
|
||||
IMPROVE: "Improve Code",
|
||||
ENHANCE: "Enhance Prompt",
|
||||
} as const
|
||||
|
||||
export type CustomSupportPrompts = {
|
||||
[key: string]: string | undefined
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { render, fireEvent, screen } from "@testing-library/react"
|
||||
import { useExtensionState } from "../../../context/ExtensionStateContext"
|
||||
import AutoApproveMenu from "../AutoApproveMenu"
|
||||
import { codeMode, defaultPrompts } from "../../../../../src/shared/modes"
|
||||
import { defaultModeSlug, defaultPrompts } from "../../../../../src/shared/modes"
|
||||
|
||||
// Mock the ExtensionStateContext hook
|
||||
jest.mock("../../../context/ExtensionStateContext")
|
||||
@@ -29,8 +29,9 @@ describe("AutoApproveMenu", () => {
|
||||
requestDelaySeconds: 5,
|
||||
currentApiConfigName: "default",
|
||||
listApiConfigMeta: [],
|
||||
mode: codeMode,
|
||||
customPrompts: defaultPrompts,
|
||||
mode: defaultModeSlug,
|
||||
customModePrompts: defaultPrompts,
|
||||
customSupportPrompts: {},
|
||||
enhancementApiConfigId: "",
|
||||
didHydrateState: true,
|
||||
showWelcome: false,
|
||||
|
||||
@@ -23,7 +23,8 @@ type PromptsViewProps = {
|
||||
|
||||
const PromptsView = ({ onDone }: PromptsViewProps) => {
|
||||
const {
|
||||
customPrompts,
|
||||
customModePrompts,
|
||||
customSupportPrompts,
|
||||
listApiConfigMeta,
|
||||
enhancementApiConfigId,
|
||||
setEnhancementApiConfigId,
|
||||
@@ -50,7 +51,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
|
||||
// Direct update functions
|
||||
const updateAgentPrompt = useCallback(
|
||||
(mode: Mode, promptData: PromptComponent) => {
|
||||
const existingPrompt = customPrompts?.[mode] as PromptComponent
|
||||
const existingPrompt = customModePrompts?.[mode] as PromptComponent
|
||||
const updatedPrompt = { ...existingPrompt, ...promptData }
|
||||
|
||||
// Only include properties that differ from defaults
|
||||
@@ -64,7 +65,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
|
||||
customPrompt: updatedPrompt,
|
||||
})
|
||||
},
|
||||
[customPrompts],
|
||||
[customModePrompts],
|
||||
)
|
||||
|
||||
const updateCustomMode = useCallback((slug: string, modeConfig: ModeConfig) => {
|
||||
@@ -261,7 +262,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
|
||||
|
||||
const handleAgentReset = (modeSlug: string) => {
|
||||
// Only reset role definition for built-in modes
|
||||
const existingPrompt = customPrompts?.[modeSlug] as PromptComponent
|
||||
const existingPrompt = customModePrompts?.[modeSlug] as PromptComponent
|
||||
updateAgentPrompt(modeSlug, {
|
||||
...existingPrompt,
|
||||
roleDefinition: undefined,
|
||||
@@ -276,7 +277,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
|
||||
}
|
||||
|
||||
const getSupportPromptValue = (type: SupportPromptType): string => {
|
||||
return supportPrompt.get(customPrompts, type)
|
||||
return supportPrompt.get(customSupportPrompts, type)
|
||||
}
|
||||
|
||||
const handleTestEnhancement = () => {
|
||||
@@ -556,7 +557,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
|
||||
<VSCodeTextArea
|
||||
value={(() => {
|
||||
const customMode = findModeBySlug(mode, customModes)
|
||||
const prompt = customPrompts?.[mode] as PromptComponent
|
||||
const prompt = customModePrompts?.[mode] as PromptComponent
|
||||
return customMode?.roleDefinition ?? prompt?.roleDefinition ?? getRoleDefinition(mode)
|
||||
})()}
|
||||
onChange={(e) => {
|
||||
@@ -673,7 +674,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
|
||||
<VSCodeTextArea
|
||||
value={(() => {
|
||||
const customMode = findModeBySlug(mode, customModes)
|
||||
const prompt = customPrompts?.[mode] as PromptComponent
|
||||
const prompt = customModePrompts?.[mode] as PromptComponent
|
||||
return customMode?.customInstructions ?? prompt?.customInstructions ?? ""
|
||||
})()}
|
||||
onChange={(e) => {
|
||||
@@ -689,7 +690,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
|
||||
})
|
||||
} else {
|
||||
// For built-in modes, update the prompts
|
||||
const existingPrompt = customPrompts?.[mode] as PromptComponent
|
||||
const existingPrompt = customModePrompts?.[mode] as PromptComponent
|
||||
updateAgentPrompt(mode, {
|
||||
...existingPrompt,
|
||||
customInstructions: value.trim() || undefined,
|
||||
|
||||
@@ -12,7 +12,7 @@ jest.mock("../../../utils/vscode", () => ({
|
||||
}))
|
||||
|
||||
const mockExtensionState = {
|
||||
customPrompts: {},
|
||||
customModePrompts: {},
|
||||
listApiConfigMeta: [
|
||||
{ id: "config1", name: "Config 1" },
|
||||
{ id: "config2", name: "Config 2" },
|
||||
|
||||
@@ -14,7 +14,8 @@ import { convertTextMateToHljs } from "../utils/textMateToHljs"
|
||||
import { findLastIndex } from "../../../src/shared/array"
|
||||
import { McpServer } from "../../../src/shared/mcp"
|
||||
import { checkExistKey } from "../../../src/shared/checkExistApiConfig"
|
||||
import { Mode, CustomPrompts, defaultModeSlug, defaultPrompts, ModeConfig } from "../../../src/shared/modes"
|
||||
import { Mode, CustomModePrompts, defaultModeSlug, defaultPrompts, ModeConfig } from "../../../src/shared/modes"
|
||||
import { CustomSupportPrompts } from "../../../src/shared/support-prompt"
|
||||
|
||||
export interface ExtensionStateContextType extends ExtensionState {
|
||||
didHydrateState: boolean
|
||||
@@ -57,7 +58,8 @@ export interface ExtensionStateContextType extends ExtensionState {
|
||||
onUpdateApiConfig: (apiConfig: ApiConfiguration) => void
|
||||
mode: Mode
|
||||
setMode: (value: Mode) => void
|
||||
setCustomPrompts: (value: CustomPrompts) => void
|
||||
setCustomModePrompts: (value: CustomModePrompts) => void
|
||||
setCustomSupportPrompts: (value: CustomSupportPrompts) => void
|
||||
enhancementApiConfigId?: string
|
||||
setEnhancementApiConfigId: (value: string) => void
|
||||
experimentalDiffStrategy: boolean
|
||||
@@ -93,7 +95,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
|
||||
currentApiConfigName: "default",
|
||||
listApiConfigMeta: [],
|
||||
mode: defaultModeSlug,
|
||||
customPrompts: defaultPrompts,
|
||||
customModePrompts: defaultPrompts,
|
||||
customSupportPrompts: {},
|
||||
enhancementApiConfigId: "",
|
||||
experimentalDiffStrategy: false,
|
||||
autoApprovalEnabled: false,
|
||||
@@ -270,7 +273,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
|
||||
setListApiConfigMeta,
|
||||
onUpdateApiConfig,
|
||||
setMode: (value: Mode) => setState((prevState) => ({ ...prevState, mode: value })),
|
||||
setCustomPrompts: (value) => setState((prevState) => ({ ...prevState, customPrompts: value })),
|
||||
setCustomModePrompts: (value) => setState((prevState) => ({ ...prevState, customModePrompts: value })),
|
||||
setCustomSupportPrompts: (value) => setState((prevState) => ({ ...prevState, customSupportPrompts: value })),
|
||||
setEnhancementApiConfigId: (value) =>
|
||||
setState((prevState) => ({ ...prevState, enhancementApiConfigId: value })),
|
||||
setExperimentalDiffStrategy: (value) =>
|
||||
|
||||
Reference in New Issue
Block a user