system.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import * as vscode from "vscode"
  2. import * as os from "os"
  3. import { type ModeConfig, type PromptComponent, type CustomModePrompts, type TodoItem } from "@roo-code/types"
  4. import { Mode, modes, defaultModeSlug, getModeBySlug, getGroupName, getModeSelection } from "../../shared/modes"
  5. import { DiffStrategy } from "../../shared/tools"
  6. import { formatLanguage } from "../../shared/language"
  7. import { isEmpty } from "../../utils/object"
  8. import { McpHub } from "../../services/mcp/McpHub"
  9. import { CodeIndexManager } from "../../services/code-index/manager"
  10. import { SkillsManager } from "../../services/skills/SkillsManager"
  11. import { PromptVariables, loadSystemPromptFile } from "./sections/custom-system-prompt"
  12. import type { SystemPromptSettings } from "./types"
  13. import {
  14. getRulesSection,
  15. getSystemInfoSection,
  16. getObjectiveSection,
  17. getSharedToolUseSection,
  18. getToolUseGuidelinesSection,
  19. getCapabilitiesSection,
  20. getModesSection,
  21. addCustomInstructions,
  22. markdownFormattingSection,
  23. getSkillsSection,
  24. } from "./sections"
  25. // Helper function to get prompt component, filtering out empty objects
  26. export function getPromptComponent(
  27. customModePrompts: CustomModePrompts | undefined,
  28. mode: string,
  29. ): PromptComponent | undefined {
  30. const component = customModePrompts?.[mode]
  31. // Return undefined if component is empty
  32. if (isEmpty(component)) {
  33. return undefined
  34. }
  35. return component
  36. }
  37. async function generatePrompt(
  38. context: vscode.ExtensionContext,
  39. cwd: string,
  40. supportsComputerUse: boolean,
  41. mode: Mode,
  42. mcpHub?: McpHub,
  43. diffStrategy?: DiffStrategy,
  44. browserViewportSize?: string,
  45. promptComponent?: PromptComponent,
  46. customModeConfigs?: ModeConfig[],
  47. globalCustomInstructions?: string,
  48. experiments?: Record<string, boolean>,
  49. language?: string,
  50. rooIgnoreInstructions?: string,
  51. settings?: SystemPromptSettings,
  52. todoList?: TodoItem[],
  53. modelId?: string,
  54. skillsManager?: SkillsManager,
  55. ): Promise<string> {
  56. if (!context) {
  57. throw new Error("Extension context is required for generating system prompt")
  58. }
  59. // Get the full mode config to ensure we have the role definition (used for groups, etc.)
  60. const modeConfig = getModeBySlug(mode, customModeConfigs) || modes.find((m) => m.slug === mode) || modes[0]
  61. const { roleDefinition, baseInstructions } = getModeSelection(mode, promptComponent, customModeConfigs)
  62. // Check if MCP functionality should be included
  63. const hasMcpGroup = modeConfig.groups.some((groupEntry) => getGroupName(groupEntry) === "mcp")
  64. const hasMcpServers = mcpHub && mcpHub.getServers().length > 0
  65. const shouldIncludeMcp = hasMcpGroup && hasMcpServers
  66. const codeIndexManager = CodeIndexManager.getInstance(context, cwd)
  67. // Tool calling is native-only.
  68. const effectiveProtocol = "native"
  69. const [modesSection, skillsSection] = await Promise.all([
  70. getModesSection(context),
  71. getSkillsSection(skillsManager, mode as string),
  72. ])
  73. // Tools catalog is not included in the system prompt.
  74. const toolsCatalog = ""
  75. const basePrompt = `${roleDefinition}
  76. ${markdownFormattingSection()}
  77. ${getSharedToolUseSection()}${toolsCatalog}
  78. ${getToolUseGuidelinesSection()}
  79. ${getCapabilitiesSection(cwd, shouldIncludeMcp ? mcpHub : undefined)}
  80. ${modesSection}
  81. ${skillsSection ? `\n${skillsSection}` : ""}
  82. ${getRulesSection(cwd, settings)}
  83. ${getSystemInfoSection(cwd)}
  84. ${getObjectiveSection()}
  85. ${await addCustomInstructions(baseInstructions, globalCustomInstructions || "", cwd, mode, {
  86. language: language ?? formatLanguage(vscode.env.language),
  87. rooIgnoreInstructions,
  88. settings,
  89. })}`
  90. return basePrompt
  91. }
  92. export const SYSTEM_PROMPT = async (
  93. context: vscode.ExtensionContext,
  94. cwd: string,
  95. supportsComputerUse: boolean,
  96. mcpHub?: McpHub,
  97. diffStrategy?: DiffStrategy,
  98. browserViewportSize?: string,
  99. mode: Mode = defaultModeSlug,
  100. customModePrompts?: CustomModePrompts,
  101. customModes?: ModeConfig[],
  102. globalCustomInstructions?: string,
  103. experiments?: Record<string, boolean>,
  104. language?: string,
  105. rooIgnoreInstructions?: string,
  106. settings?: SystemPromptSettings,
  107. todoList?: TodoItem[],
  108. modelId?: string,
  109. skillsManager?: SkillsManager,
  110. ): Promise<string> => {
  111. if (!context) {
  112. throw new Error("Extension context is required for generating system prompt")
  113. }
  114. // Try to load custom system prompt from file
  115. const variablesForPrompt: PromptVariables = {
  116. workspace: cwd,
  117. mode: mode,
  118. language: language ?? formatLanguage(vscode.env.language),
  119. shell: vscode.env.shell,
  120. operatingSystem: os.type(),
  121. }
  122. const fileCustomSystemPrompt = await loadSystemPromptFile(cwd, mode, variablesForPrompt)
  123. // Check if it's a custom mode
  124. const promptComponent = getPromptComponent(customModePrompts, mode)
  125. // Get full mode config from custom modes or fall back to built-in modes
  126. const currentMode = getModeBySlug(mode, customModes) || modes.find((m) => m.slug === mode) || modes[0]
  127. // If a file-based custom system prompt exists, use it
  128. if (fileCustomSystemPrompt) {
  129. const { roleDefinition, baseInstructions: baseInstructionsForFile } = getModeSelection(
  130. mode,
  131. promptComponent,
  132. customModes,
  133. )
  134. const customInstructions = await addCustomInstructions(
  135. baseInstructionsForFile,
  136. globalCustomInstructions || "",
  137. cwd,
  138. mode,
  139. {
  140. language: language ?? formatLanguage(vscode.env.language),
  141. rooIgnoreInstructions,
  142. settings,
  143. },
  144. )
  145. // For file-based prompts, don't include the tool sections
  146. return `${roleDefinition}
  147. ${fileCustomSystemPrompt}
  148. ${customInstructions}`
  149. }
  150. return generatePrompt(
  151. context,
  152. cwd,
  153. supportsComputerUse,
  154. currentMode.slug,
  155. mcpHub,
  156. diffStrategy,
  157. browserViewportSize,
  158. promptComponent,
  159. customModes,
  160. globalCustomInstructions,
  161. experiments,
  162. language,
  163. rooIgnoreInstructions,
  164. settings,
  165. todoList,
  166. modelId,
  167. skillsManager,
  168. )
  169. }