Ver Fonte

Power steering

Matt Rubens há 10 meses atrás
pai
commit
df46f60117
3 ficheiros alterados com 72 adições e 4 exclusões
  1. 24 4
      src/core/Cline.ts
  2. 7 0
      src/shared/experiments.ts
  3. 41 0
      src/shared/modes.ts

+ 24 - 4
src/core/Cline.ts

@@ -54,7 +54,7 @@ import { parseMentions } from "./mentions"
 import { AssistantMessageContent, parseAssistantMessage, ToolParamName, ToolUseName } from "./assistant-message"
 import { formatResponse } from "./prompts/responses"
 import { SYSTEM_PROMPT } from "./prompts/system"
-import { modes, defaultModeSlug, getModeBySlug } from "../shared/modes"
+import { modes, defaultModeSlug, getModeBySlug, getFullModeDetails } from "../shared/modes"
 import { truncateConversationIfNeeded } from "./sliding-window"
 import { ClineProvider, GlobalFileNames } from "./webview/ClineProvider"
 import { detectCodeOmission } from "../integrations/editor/detect-omission"
@@ -63,7 +63,7 @@ import { OpenRouterHandler } from "../api/providers/openrouter"
 import { McpHub } from "../services/mcp/McpHub"
 import crypto from "crypto"
 import { insertGroups } from "./diff/insert-groups"
-import { EXPERIMENT_IDS, experiments as Experiments } from "../shared/experiments"
+import { EXPERIMENT_IDS, experiments as Experiments, ExperimentId } from "../shared/experiments"
 
 const cwd =
 	vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution
@@ -3235,9 +3235,29 @@ export class Cline {
 		details += `\n\n# Current Context Size (Tokens)\n${contextTokens ? `${contextTokens.toLocaleString()} (${contextPercentage}%)` : "(Not available)"}`
 
 		// Add current mode and any mode-specific warnings
-		const { mode, customModes } = (await this.providerRef.deref()?.getState()) ?? {}
+		const {
+			mode,
+			customModes,
+			customModePrompts,
+			experiments = {} as Record<ExperimentId, boolean>,
+			customInstructions: globalCustomInstructions,
+			preferredLanguage,
+		} = (await this.providerRef.deref()?.getState()) ?? {}
 		const currentMode = mode ?? defaultModeSlug
-		details += `\n\n# Current Mode\n${currentMode}`
+		const modeDetails = await getFullModeDetails(currentMode, customModes, customModePrompts, {
+			cwd,
+			globalCustomInstructions,
+			preferredLanguage,
+		})
+		details += `\n\n# Current Mode\n`
+		details += `<slug>${currentMode}</slug>\n`
+		details += `<name>${modeDetails.name}</name>\n`
+		if (Experiments.isEnabled(experiments ?? {}, EXPERIMENT_IDS.POWER_STEERING)) {
+			details += `<role>${modeDetails.roleDefinition}</role>\n`
+			if (modeDetails.customInstructions) {
+				details += `<custom_instructions>${modeDetails.customInstructions}</custom_instructions>\n`
+			}
+		}
 
 		// Add warning if not in code mode
 		if (

+ 7 - 0
src/shared/experiments.ts

@@ -2,6 +2,7 @@ export const EXPERIMENT_IDS = {
 	DIFF_STRATEGY: "experimentalDiffStrategy",
 	SEARCH_AND_REPLACE: "search_and_replace",
 	INSERT_BLOCK: "insert_content",
+	POWER_STEERING: "powerSteering",
 } as const
 
 export type ExperimentKey = keyof typeof EXPERIMENT_IDS
@@ -35,6 +36,12 @@ export const experimentConfigsMap: Record<ExperimentKey, ExperimentConfig> = {
 			"Enable the experimental insert content tool, allowing Roo to insert content at specific line numbers without needing to create a diff.",
 		enabled: false,
 	},
+	POWER_STEERING: {
+		name: 'Use experimental "power steering" mode',
+		description:
+			"When enabled, Roo will remind the model about the details of its current mode definition more frequently. This will lead to stronger adherence to role definitions and custom instructions, but will use additional tokens.",
+		enabled: false,
+	},
 }
 
 export const experimentDefault = Object.fromEntries(

+ 41 - 0
src/shared/modes.ts

@@ -1,5 +1,6 @@
 import * as vscode from "vscode"
 import { TOOL_GROUPS, ToolGroup, ALWAYS_AVAILABLE_TOOLS } from "./tool-groups"
+import { addCustomInstructions } from "../core/prompts/sections/custom-instructions"
 
 // Mode types
 export type Mode = string
@@ -262,6 +263,46 @@ export async function getAllModesWithPrompts(context: vscode.ExtensionContext):
 	}))
 }
 
+// Helper function to get complete mode details with all overrides
+export async function getFullModeDetails(
+	modeSlug: string,
+	customModes?: ModeConfig[],
+	customModePrompts?: CustomModePrompts,
+	options?: {
+		cwd?: string
+		globalCustomInstructions?: string
+		preferredLanguage?: string
+	},
+): Promise<ModeConfig> {
+	// First get the base mode config from custom modes or built-in modes
+	const baseMode = getModeBySlug(modeSlug, customModes) || modes.find((m) => m.slug === modeSlug) || modes[0]
+
+	// Check for any prompt component overrides
+	const promptComponent = customModePrompts?.[modeSlug]
+
+	// Get the base custom instructions
+	const baseCustomInstructions = promptComponent?.customInstructions || baseMode.customInstructions || ""
+
+	// If we have cwd, load and combine all custom instructions
+	let fullCustomInstructions = baseCustomInstructions
+	if (options?.cwd) {
+		fullCustomInstructions = await addCustomInstructions(
+			baseCustomInstructions,
+			options.globalCustomInstructions || "",
+			options.cwd,
+			modeSlug,
+			{ preferredLanguage: options.preferredLanguage },
+		)
+	}
+
+	// Return mode with any overrides applied
+	return {
+		...baseMode,
+		roleDefinition: promptComponent?.roleDefinition || baseMode.roleDefinition,
+		customInstructions: fullCustomInstructions,
+	}
+}
+
 // Helper function to safely get role definition
 export function getRoleDefinition(modeSlug: string, customModes?: ModeConfig[]): string {
 	const mode = getModeBySlug(modeSlug, customModes)