diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap index 31b49ec682..ea5f8b7338 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap @@ -549,13 +549,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap index b2b0abfad4..84fc71ee25 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap @@ -611,13 +611,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap index 0eecf0482e..43126e40c1 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap @@ -617,13 +617,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap index 731f4b29a7..5da7e33bdb 100644 --- a/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap +++ b/src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap @@ -554,13 +554,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap index 31b49ec682..ea5f8b7338 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap @@ -549,13 +549,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap index fda93c1c77..29afbda0ad 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap @@ -605,13 +605,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap index 31b49ec682..ea5f8b7338 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap @@ -549,13 +549,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap index 8db4d0b377..36af7d8687 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap @@ -637,13 +637,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap index 31b49ec682..ea5f8b7338 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap @@ -549,13 +549,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap index 44d5b58327..68a333d092 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap @@ -605,13 +605,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap index 0eecf0482e..43126e40c1 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap @@ -617,13 +617,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap index 31b49ec682..ea5f8b7338 100644 --- a/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap +++ b/src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap @@ -549,13 +549,19 @@ Mode-specific Instructions: 2. You should also ask the user clarifying questions to get a better understanding of the task. -3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer. +3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be: + - Specific and actionable + - Listed in logical execution order + - Focused on a single, well-defined outcome + - Clear enough that another mode could execute it independently -4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. +4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished. -5. Use the switch_mode tool to request that the user switch to another mode to implement the solution. +5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture. -**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.** +6. Use the switch_mode tool to request that the user switch to another mode to implement the solution. + +**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.** Rules: # Rules from .clinerules-architect: diff --git a/src/core/prompts/__tests__/get-prompt-component.spec.ts b/src/core/prompts/__tests__/get-prompt-component.spec.ts new file mode 100644 index 0000000000..7c4229b9c6 --- /dev/null +++ b/src/core/prompts/__tests__/get-prompt-component.spec.ts @@ -0,0 +1,88 @@ +import { describe, it, expect } from "vitest" +import { getPromptComponent } from "../system" +import type { CustomModePrompts } from "@roo-code/types" + +describe("getPromptComponent", () => { + it("should return undefined for empty objects", () => { + const customModePrompts: CustomModePrompts = { + architect: {}, + } + + const result = getPromptComponent(customModePrompts, "architect") + expect(result).toBeUndefined() + }) + + it("should return the component for objects with any properties", () => { + const customModePrompts: CustomModePrompts = { + architect: { + foo: "bar", + baz: 123, + } as any, + } + + const result = getPromptComponent(customModePrompts, "architect") + expect(result).toEqual({ foo: "bar", baz: 123 }) + }) + + it("should return undefined for missing mode", () => { + const customModePrompts: CustomModePrompts = {} + + const result = getPromptComponent(customModePrompts, "architect") + expect(result).toBeUndefined() + }) + + it("should return undefined when customModePrompts is undefined", () => { + const result = getPromptComponent(undefined, "architect") + expect(result).toBeUndefined() + }) + + it.each([ + ["roleDefinition", { roleDefinition: "Test role" }], + ["customInstructions", { customInstructions: "Test instructions" }], + ["whenToUse", { whenToUse: "Test when to use" }], + ["description", { description: "Test description" }], + ])("should return the component when it has %s", (property, component) => { + const customModePrompts: CustomModePrompts = { + architect: component, + } + + const result = getPromptComponent(customModePrompts, "architect") + expect(result).toEqual(component) + }) + + it("should return the component when it has multiple properties", () => { + const customModePrompts: CustomModePrompts = { + architect: { + roleDefinition: "Test role", + customInstructions: "Test instructions", + whenToUse: "Test when to use", + description: "Test description", + }, + } + + const result = getPromptComponent(customModePrompts, "architect") + expect(result).toEqual({ + roleDefinition: "Test role", + customInstructions: "Test instructions", + whenToUse: "Test when to use", + description: "Test description", + }) + }) + + it("should return the component when it has both relevant and irrelevant properties", () => { + const customModePrompts: CustomModePrompts = { + architect: { + roleDefinition: "Test role", + foo: "bar", + baz: 123, + } as any, + } + + const result = getPromptComponent(customModePrompts, "architect") + expect(result).toEqual({ + roleDefinition: "Test role", + foo: "bar", + baz: 123, + }) + }) +}) diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index be3b91f146..bfc12930a0 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -6,6 +6,7 @@ import type { ModeConfig, PromptComponent, CustomModePrompts, TodoItem } from "@ import { Mode, modes, defaultModeSlug, getModeBySlug, getGroupName, getModeSelection } from "../../shared/modes" import { DiffStrategy } from "../../shared/tools" import { formatLanguage } from "../../shared/language" +import { isEmpty } from "../../utils/object" import { McpHub } from "../../services/mcp/McpHub" import { CodeIndexManager } from "../../services/code-index/manager" @@ -26,6 +27,19 @@ import { markdownFormattingSection, } from "./sections" +// Helper function to get prompt component, filtering out empty objects +export function getPromptComponent( + customModePrompts: CustomModePrompts | undefined, + mode: string, +): PromptComponent | undefined { + const component = customModePrompts?.[mode] + // Return undefined if component is empty + if (isEmpty(component)) { + return undefined + } + return component +} + async function generatePrompt( context: vscode.ExtensionContext, cwd: string, @@ -129,13 +143,6 @@ export const SYSTEM_PROMPT = async ( throw new Error("Extension context is required for generating system prompt") } - const getPromptComponent = (value: unknown) => { - if (typeof value === "object" && value !== null) { - return value as PromptComponent - } - return undefined - } - // Try to load custom system prompt from file const variablesForPrompt: PromptVariables = { workspace: cwd, @@ -147,7 +154,7 @@ export const SYSTEM_PROMPT = async ( const fileCustomSystemPrompt = await loadSystemPromptFile(cwd, mode, variablesForPrompt) // Check if it's a custom mode - const promptComponent = getPromptComponent(customModePrompts?.[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] diff --git a/src/shared/__tests__/modes-empty-prompt-component.spec.ts b/src/shared/__tests__/modes-empty-prompt-component.spec.ts new file mode 100644 index 0000000000..5af93cb5d9 --- /dev/null +++ b/src/shared/__tests__/modes-empty-prompt-component.spec.ts @@ -0,0 +1,97 @@ +import { describe, it, expect } from "vitest" +import { getModeSelection, modes } from "../modes" +import type { PromptComponent } from "@roo-code/types" + +describe("getModeSelection with empty promptComponent", () => { + it("should use built-in mode instructions when promptComponent is undefined", () => { + const architectMode = modes.find((m) => m.slug === "architect")! + + // Test with undefined promptComponent (which is what getPromptComponent returns for empty objects) + const result = getModeSelection("architect", undefined, []) + + // Should use built-in mode values + expect(result.roleDefinition).toBe(architectMode.roleDefinition) + expect(result.baseInstructions).toBe(architectMode.customInstructions) + expect(result.baseInstructions).toContain("Do some information gathering") + }) + + it("should use built-in mode instructions when promptComponent is null", () => { + const debugMode = modes.find((m) => m.slug === "debug")! + + // Test with null promptComponent + const result = getModeSelection("debug", null as any, []) + + // Should use built-in mode values + expect(result.roleDefinition).toBe(debugMode.roleDefinition) + expect(result.baseInstructions).toBe(debugMode.customInstructions) + expect(result.baseInstructions).toContain("Reflect on 5-7 different possible sources") + }) + + it("should use promptComponent when it has actual content", () => { + // Test with promptComponent that has actual content + const validPromptComponent: PromptComponent = { + roleDefinition: "Custom role", + customInstructions: "Custom instructions", + } + const result = getModeSelection("architect", validPromptComponent, []) + + // Should use promptComponent values + expect(result.roleDefinition).toBe("Custom role") + expect(result.baseInstructions).toBe("Custom instructions") + }) + + it("should merge promptComponent with built-in mode when it has partial content", () => { + const architectMode = modes.find((m) => m.slug === "architect")! + + // Test with promptComponent that only has customInstructions + const partialPromptComponent: PromptComponent = { + customInstructions: "Only custom instructions", + } + const result = getModeSelection("architect", partialPromptComponent, []) + + // Should merge: use promptComponent's customInstructions but fall back to built-in roleDefinition + expect(result.roleDefinition).toBe(architectMode.roleDefinition) // Falls back to built-in + expect(result.baseInstructions).toBe("Only custom instructions") // Uses promptComponent + }) + + it("should merge promptComponent with built-in mode when it only has roleDefinition", () => { + const debugMode = modes.find((m) => m.slug === "debug")! + + // Test with promptComponent that only has roleDefinition + const partialPromptComponent: PromptComponent = { + roleDefinition: "Custom debug role", + } + const result = getModeSelection("debug", partialPromptComponent, []) + + // Should merge: use promptComponent's roleDefinition but fall back to built-in customInstructions + expect(result.roleDefinition).toBe("Custom debug role") // Uses promptComponent + expect(result.baseInstructions).toBe(debugMode.customInstructions) // Falls back to built-in + }) + + it("should handle promptComponent with both roleDefinition and customInstructions", () => { + // Test with promptComponent that has both properties + const fullPromptComponent: PromptComponent = { + roleDefinition: "Full custom role", + customInstructions: "Full custom instructions", + } + const result = getModeSelection("architect", fullPromptComponent, []) + + // Should use promptComponent values for both + expect(result.roleDefinition).toBe("Full custom role") + expect(result.baseInstructions).toBe("Full custom instructions") + }) + + it("should fall back to default mode when built-in mode is not found", () => { + const defaultMode = modes[0] // First mode is the default + + // Test with non-existent mode + const partialPromptComponent: PromptComponent = { + customInstructions: "Custom instructions for unknown mode", + } + const result = getModeSelection("non-existent-mode", partialPromptComponent, []) + + // Should merge with default mode + expect(result.roleDefinition).toBe(defaultMode.roleDefinition) // Falls back to default mode + expect(result.baseInstructions).toBe("Custom instructions for unknown mode") // Uses promptComponent + }) +}) diff --git a/src/shared/__tests__/modes.spec.ts b/src/shared/__tests__/modes.spec.ts index acf7da84c8..6166c2445c 100644 --- a/src/shared/__tests__/modes.spec.ts +++ b/src/shared/__tests__/modes.spec.ts @@ -443,10 +443,11 @@ describe("getModeSelection", () => { expect(selection.baseInstructions).toBe(newCustomMode.customInstructions) }) - test("should return empty strings if slug does not exist in custom, prompt, or built-in modes", () => { + test("should fall back to default mode if slug does not exist in custom, prompt, or built-in modes", () => { const selection = getModeSelection("non-existent-mode", undefined, customModesList) - expect(selection.roleDefinition).toBe("") - expect(selection.baseInstructions).toBe("") + const defaultMode = modes[0] // First mode is the default + expect(selection.roleDefinition).toBe(defaultMode.roleDefinition) + expect(selection.baseInstructions).toBe(defaultMode.customInstructions || "") }) test("customMode's properties are used if customMode exists, ignoring promptComponent's properties", () => { diff --git a/src/shared/modes.ts b/src/shared/modes.ts index 23efdc45f7..f876aa56fa 100644 --- a/src/shared/modes.ts +++ b/src/shared/modes.ts @@ -72,7 +72,7 @@ export const modes: readonly ModeConfig[] = [ description: "Plan and design before implementation", groups: ["read", ["edit", { fileRegex: "\\.md$", description: "Markdown files only" }], "browser", "mcp"], customInstructions: - "1. Do some information gathering (for example using read_file or search_files) to get more context about the task.\n\n2. You should also ask the user clarifying questions to get a better understanding of the task.\n\n3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.\n\n4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.\n\n5. Use the switch_mode tool to request that the user switch to another mode to implement the solution.\n\n**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.**", + "1. Do some information gathering (for example using read_file or search_files) to get more context about the task.\n\n2. You should also ask the user clarifying questions to get a better understanding of the task.\n\n3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:\n - Specific and actionable\n - Listed in logical execution order\n - Focused on a single, well-defined outcome\n - Clear enough that another mode could execute it independently\n\n4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.\n\n5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture.\n\n6. Use the switch_mode tool to request that the user switch to another mode to implement the solution.\n\n**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**", }, { slug: "code", @@ -183,23 +183,29 @@ export function findModeBySlug(slug: string, modes: readonly ModeConfig[] | unde /** * Get the mode selection based on the provided mode slug, prompt component, and custom modes. * If a custom mode is found, it takes precedence over the built-in modes. - * If no custom mode is found, the built-in mode is used. + * If no custom mode is found, the built-in mode is used with partial merging from promptComponent. * If neither is found, the default mode is used. */ export function getModeSelection(mode: string, promptComponent?: PromptComponent, customModes?: ModeConfig[]) { const customMode = findModeBySlug(mode, customModes) const builtInMode = findModeBySlug(mode, modes) - const modeToUse = customMode || promptComponent || builtInMode + // If we have a custom mode, use it entirely + if (customMode) { + return { + roleDefinition: customMode.roleDefinition || "", + baseInstructions: customMode.customInstructions || "", + description: customMode.description || "", + } + } - const roleDefinition = modeToUse?.roleDefinition || "" - const baseInstructions = modeToUse?.customInstructions || "" - const description = (customMode || builtInMode)?.description || "" + // Otherwise, use built-in mode as base and merge with promptComponent + const baseMode = builtInMode || modes[0] // fallback to default mode return { - roleDefinition, - baseInstructions, - description, + roleDefinition: promptComponent?.roleDefinition || baseMode.roleDefinition || "", + baseInstructions: promptComponent?.customInstructions || baseMode.customInstructions || "", + description: baseMode.description || "", } } diff --git a/src/utils/__tests__/object.spec.ts b/src/utils/__tests__/object.spec.ts new file mode 100644 index 0000000000..ce9d9f5cc7 --- /dev/null +++ b/src/utils/__tests__/object.spec.ts @@ -0,0 +1,38 @@ +import { describe, it, expect } from "vitest" +import { isEmpty } from "../object" + +describe("isEmpty", () => { + describe("should return true for empty values", () => { + it.each([ + ["empty object", {}], + ["empty array", []], + ["null", null], + ["undefined", undefined], + ["string", "string"], + ["number", 123], + ["boolean true", true], + ["boolean false", false], + ])("%s", (_, value) => { + expect(isEmpty(value)).toBe(true) + }) + }) + + describe("should return false for non-empty values", () => { + it.each([ + ["object with properties", { a: 1 }], + ["object with multiple properties", { a: 1, b: 2 }], + ["array with one item", [1]], + ["array with multiple items", [1, 2, 3]], + ])("%s", (_, value) => { + expect(isEmpty(value)).toBe(false) + }) + }) + + it("should handle objects with null prototype", () => { + const obj = Object.create(null) + expect(isEmpty(obj)).toBe(true) + + obj.prop = "value" + expect(isEmpty(obj)).toBe(false) + }) +}) diff --git a/src/utils/object.ts b/src/utils/object.ts new file mode 100644 index 0000000000..1aec4a1309 --- /dev/null +++ b/src/utils/object.ts @@ -0,0 +1,18 @@ +/** + * Check if an object is empty (has no own enumerable properties) + * @param obj The object to check + * @returns true if the object is empty, false otherwise + */ +export function isEmpty(obj: unknown): boolean { + if (!obj || typeof obj !== "object") { + return true + } + + // Check if it's an array + if (Array.isArray(obj)) { + return obj.length === 0 + } + + // Check if it's an object with no own properties + return Object.keys(obj).length === 0 +}