Power steering

This commit is contained in:
Matt Rubens 2025-02-20 00:59:39 -05:00
parent c4bc1c0861
commit df46f60117
3 changed files with 72 additions and 4 deletions

View file

@ -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 (

View file

@ -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(

View file

@ -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)