| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- import { TOOL_GROUPS, ToolGroup, ALWAYS_AVAILABLE_TOOLS } from "./tool-groups"
- // Mode types
- export type Mode = string
- // Mode configuration type
- export type ModeConfig = {
- slug: string
- name: string
- roleDefinition: string
- customInstructions?: string
- groups: readonly ToolGroup[] // Now uses groups instead of tools array
- }
- // Mode-specific prompts only
- export type PromptComponent = {
- roleDefinition?: string
- customInstructions?: string
- }
- export type CustomModePrompts = {
- [key: string]: PromptComponent | undefined
- }
- // Helper to get all tools for a mode
- export function getToolsForMode(groups: readonly ToolGroup[]): string[] {
- const tools = new Set<string>()
- // Add tools from each group
- groups.forEach((group) => {
- TOOL_GROUPS[group].forEach((tool) => tools.add(tool))
- })
- // Always add required tools
- ALWAYS_AVAILABLE_TOOLS.forEach((tool) => tools.add(tool))
- return Array.from(tools)
- }
- // Main modes configuration as an ordered array
- export const modes: readonly ModeConfig[] = [
- {
- slug: "code",
- name: "Code",
- roleDefinition:
- "You are Roo, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.",
- groups: ["read", "edit", "browser", "command", "mcp"],
- },
- {
- slug: "architect",
- name: "Architect",
- roleDefinition:
- "You are Roo, a software architecture expert specializing in analyzing codebases, identifying patterns, and providing high-level technical guidance. You excel at understanding complex systems, evaluating architectural decisions, and suggesting improvements while maintaining a read-only approach to the codebase. Make sure to help the user come up with a solid implementation plan for their project and don't rush to switch to implementing code.",
- groups: ["read", "browser", "mcp"],
- },
- {
- slug: "ask",
- name: "Ask",
- roleDefinition:
- "You are Roo, a knowledgeable technical assistant focused on answering questions and providing information about software development, technology, and related topics. You can analyze code, explain concepts, and access external resources while maintaining a read-only approach to the codebase. Make sure to answer the user's questions and don't rush to switch to implementing code.",
- groups: ["read", "browser", "mcp"],
- },
- ] as const
- // Export the default mode slug
- export const defaultModeSlug = modes[0].slug
- // Helper functions
- export function getModeBySlug(slug: string, customModes?: ModeConfig[]): ModeConfig | undefined {
- // Check custom modes first
- const customMode = customModes?.find((mode) => mode.slug === slug)
- if (customMode) {
- return customMode
- }
- // Then check built-in modes
- return modes.find((mode) => mode.slug === slug)
- }
- export function getModeConfig(slug: string, customModes?: ModeConfig[]): ModeConfig {
- const mode = getModeBySlug(slug, customModes)
- if (!mode) {
- throw new Error(`No mode found for slug: ${slug}`)
- }
- return mode
- }
- // Get all available modes, with custom modes overriding built-in modes
- export function getAllModes(customModes?: ModeConfig[]): ModeConfig[] {
- if (!customModes?.length) {
- return [...modes]
- }
- // Start with built-in modes
- const allModes = [...modes]
- // Process custom modes
- customModes.forEach((customMode) => {
- const index = allModes.findIndex((mode) => mode.slug === customMode.slug)
- if (index !== -1) {
- // Override existing mode
- allModes[index] = customMode
- } else {
- // Add new mode
- allModes.push(customMode)
- }
- })
- return allModes
- }
- // Check if a mode is custom or an override
- export function isCustomMode(slug: string, customModes?: ModeConfig[]): boolean {
- return !!customModes?.some((mode) => mode.slug === slug)
- }
- export function isToolAllowedForMode(
- tool: string,
- modeSlug: string,
- customModes: ModeConfig[],
- toolRequirements?: Record<string, boolean>,
- ): boolean {
- // Always allow these tools
- if (ALWAYS_AVAILABLE_TOOLS.includes(tool as any)) {
- return true
- }
- // Check tool requirements if any exist
- if (toolRequirements && tool in toolRequirements) {
- if (!toolRequirements[tool]) {
- return false
- }
- }
- const mode = getModeBySlug(modeSlug, customModes)
- if (!mode) {
- return false
- }
- // Check if tool is in any of the mode's groups
- return mode.groups.some((group) => TOOL_GROUPS[group].includes(tool as string))
- }
- // Create the mode-specific default prompts
- export const defaultPrompts: Readonly<CustomModePrompts> = Object.freeze(
- Object.fromEntries(modes.map((mode) => [mode.slug, { roleDefinition: mode.roleDefinition }])),
- )
- // Helper function to safely get role definition
- export function getRoleDefinition(modeSlug: string, customModes?: ModeConfig[]): string {
- const mode = getModeBySlug(modeSlug, customModes)
- if (!mode) {
- console.warn(`No mode found for slug: ${modeSlug}`)
- return ""
- }
- return mode.roleDefinition
- }
|