mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
feat: add overrideSystemPrompt option for custom modes
When overrideSystemPrompt is true on a ModeConfig, the system prompt uses only the roleDefinition as its body, skipping all standard sections (CAPABILITIES, TOOL USE, MODES, SKILLS, RULES, SYSTEM INFO, OBJECTIVE, MARKDOWN RULES). Custom instructions from .roo/rules-* files and global settings are still appended. This gives power users full control over the system prompt for specialized workflows while maintaining backward compatibility -- the flag defaults to false/undefined so existing modes are unaffected. Closes #11793
This commit is contained in:
parent
193053110b
commit
d1f7b65d60
3 changed files with 156 additions and 0 deletions
|
|
@ -102,6 +102,7 @@ export const modeConfigSchema = z.object({
|
|||
customInstructions: z.string().optional(),
|
||||
groups: groupEntryArraySchema,
|
||||
source: z.enum(["global", "project"]).optional(),
|
||||
overrideSystemPrompt: z.boolean().optional(),
|
||||
})
|
||||
|
||||
export type ModeConfig = z.infer<typeof modeConfigSchema>
|
||||
|
|
|
|||
|
|
@ -575,6 +575,144 @@ describe("SYSTEM_PROMPT", () => {
|
|||
expect(prompt).toContain("OBJECTIVE")
|
||||
})
|
||||
|
||||
describe("overrideSystemPrompt", () => {
|
||||
it("should use only roleDefinition + custom instructions when overrideSystemPrompt is true", async () => {
|
||||
const customModes: ModeConfig[] = [
|
||||
{
|
||||
slug: "custom-override",
|
||||
name: "Custom Override",
|
||||
roleDefinition: "You are a fully custom assistant with complete override.",
|
||||
customInstructions: "Follow these custom mode instructions.",
|
||||
groups: ["read", "edit"],
|
||||
overrideSystemPrompt: true,
|
||||
},
|
||||
]
|
||||
|
||||
const prompt = await SYSTEM_PROMPT(
|
||||
mockContext,
|
||||
"/test/path",
|
||||
false,
|
||||
undefined, // mcpHub
|
||||
undefined, // diffStrategy
|
||||
"custom-override" as Mode,
|
||||
undefined, // customModePrompts
|
||||
customModes,
|
||||
"Global instructions here", // globalCustomInstructions
|
||||
experiments,
|
||||
undefined, // language
|
||||
undefined, // rooIgnoreInstructions
|
||||
)
|
||||
|
||||
// Should contain the roleDefinition
|
||||
expect(prompt).toContain("You are a fully custom assistant with complete override.")
|
||||
|
||||
// Should NOT contain standard sections
|
||||
expect(prompt).not.toContain("CAPABILITIES")
|
||||
expect(prompt).not.toContain("TOOL USE")
|
||||
expect(prompt).not.toContain("MODES")
|
||||
expect(prompt).not.toContain("SYSTEM INFORMATION")
|
||||
expect(prompt).not.toContain("OBJECTIVE")
|
||||
expect(prompt).not.toContain("MARKDOWN RULES")
|
||||
})
|
||||
|
||||
it("should still include custom instructions when overrideSystemPrompt is true", async () => {
|
||||
const customModes: ModeConfig[] = [
|
||||
{
|
||||
slug: "custom-override-instructions",
|
||||
name: "Custom Override With Instructions",
|
||||
roleDefinition: "You are a specialized assistant.",
|
||||
customInstructions: "Mode-specific instructions here.",
|
||||
groups: ["read"],
|
||||
overrideSystemPrompt: true,
|
||||
},
|
||||
]
|
||||
|
||||
const prompt = await SYSTEM_PROMPT(
|
||||
mockContext,
|
||||
"/test/path",
|
||||
false,
|
||||
undefined, // mcpHub
|
||||
undefined, // diffStrategy
|
||||
"custom-override-instructions" as Mode,
|
||||
undefined, // customModePrompts
|
||||
customModes,
|
||||
"Global custom instructions.", // globalCustomInstructions
|
||||
experiments,
|
||||
undefined, // language
|
||||
undefined, // rooIgnoreInstructions
|
||||
)
|
||||
|
||||
// Should contain custom instructions section
|
||||
expect(prompt).toContain("USER'S CUSTOM INSTRUCTIONS")
|
||||
expect(prompt).toContain("Mode-specific instructions here.")
|
||||
})
|
||||
|
||||
it("should behave normally when overrideSystemPrompt is false", async () => {
|
||||
const customModes: ModeConfig[] = [
|
||||
{
|
||||
slug: "custom-normal",
|
||||
name: "Custom Normal",
|
||||
roleDefinition: "You are a normal custom assistant.",
|
||||
groups: ["read", "edit"],
|
||||
overrideSystemPrompt: false,
|
||||
},
|
||||
]
|
||||
|
||||
const prompt = await SYSTEM_PROMPT(
|
||||
mockContext,
|
||||
"/test/path",
|
||||
false,
|
||||
undefined, // mcpHub
|
||||
undefined, // diffStrategy
|
||||
"custom-normal" as Mode,
|
||||
undefined, // customModePrompts
|
||||
customModes,
|
||||
undefined, // globalCustomInstructions
|
||||
experiments,
|
||||
undefined, // language
|
||||
undefined, // rooIgnoreInstructions
|
||||
)
|
||||
|
||||
// Should contain standard sections
|
||||
expect(prompt).toContain("CAPABILITIES")
|
||||
expect(prompt).toContain("TOOL USE")
|
||||
expect(prompt).toContain("SYSTEM INFORMATION")
|
||||
expect(prompt).toContain("OBJECTIVE")
|
||||
})
|
||||
|
||||
it("should behave normally when overrideSystemPrompt is not set", async () => {
|
||||
const customModes: ModeConfig[] = [
|
||||
{
|
||||
slug: "custom-unset",
|
||||
name: "Custom Unset",
|
||||
roleDefinition: "You are a custom assistant without override flag.",
|
||||
groups: ["read"],
|
||||
},
|
||||
]
|
||||
|
||||
const prompt = await SYSTEM_PROMPT(
|
||||
mockContext,
|
||||
"/test/path",
|
||||
false,
|
||||
undefined, // mcpHub
|
||||
undefined, // diffStrategy
|
||||
"custom-unset" as Mode,
|
||||
undefined, // customModePrompts
|
||||
customModes,
|
||||
undefined, // globalCustomInstructions
|
||||
experiments,
|
||||
undefined, // language
|
||||
undefined, // rooIgnoreInstructions
|
||||
)
|
||||
|
||||
// Should contain standard sections (default behavior)
|
||||
expect(prompt).toContain("CAPABILITIES")
|
||||
expect(prompt).toContain("TOOL USE")
|
||||
expect(prompt).toContain("SYSTEM INFORMATION")
|
||||
expect(prompt).toContain("OBJECTIVE")
|
||||
})
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -64,6 +64,23 @@ async function generatePrompt(
|
|||
const modeConfig = getModeBySlug(mode, customModeConfigs) || modes.find((m) => m.slug === mode) || modes[0]
|
||||
const { roleDefinition, baseInstructions } = getModeSelection(mode, promptComponent, customModeConfigs)
|
||||
|
||||
// When overrideSystemPrompt is true, use roleDefinition as the entire system prompt
|
||||
// body, only appending custom instructions. All standard sections are skipped.
|
||||
if (modeConfig.overrideSystemPrompt) {
|
||||
const customInstructionsSection = await addCustomInstructions(
|
||||
baseInstructions,
|
||||
globalCustomInstructions || "",
|
||||
cwd,
|
||||
mode,
|
||||
{
|
||||
language: language ?? formatLanguage(vscode.env.language),
|
||||
rooIgnoreInstructions,
|
||||
settings,
|
||||
},
|
||||
)
|
||||
return `${roleDefinition}${customInstructionsSection}`
|
||||
}
|
||||
|
||||
// Check if MCP functionality should be included
|
||||
const hasMcpGroup = modeConfig.groups.some((groupEntry) => getGroupName(groupEntry) === "mcp")
|
||||
const hasMcpServers = mcpHub && mcpHub.getServers().length > 0
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue