/ src / lib / server / tool-aliases.ts
tool-aliases.ts
  1  const EXTENSION_ALIAS_GROUPS: string[][] = [
  2    ['shell', 'execute_command', 'process_tool', 'git'],
  3    ['execute', 'sandbox'],
  4    ['files', 'read_file', 'write_file', 'list_files', 'copy_file', 'move_file', 'delete_file', 'send_file'],
  5    ['edit_file'],
  6    ['web', 'web_search', 'web_fetch', 'http_request', 'http'],
  7    ['browser', 'openclaw_browser'],
  8    ['delegate', 'claude_code', 'codex_cli', 'opencode_cli', 'gemini_cli', 'copilot_cli', 'droid_cli', 'cursor_cli', 'qwen_code_cli', 'delegate_to_claude_code', 'delegate_to_codex_cli', 'delegate_to_opencode_cli', 'delegate_to_gemini_cli', 'delegate_to_copilot_cli', 'delegate_to_droid_cli', 'delegate_to_cursor_cli', 'delegate_to_qwen_code_cli'],
  9    ['manage_platform'],
 10    ['manage_agents'],
 11    ['manage_projects'],
 12    ['manage_tasks'],
 13    ['manage_schedules'],
 14    ['manage_skills'],
 15    ['manage_webhooks'],
 16    ['manage_secrets'],
 17    ['manage_connectors', 'connectors', 'connector_message_tool'],
 18    ['manage_chatrooms', 'chatroom'],
 19    ['manage_protocols', 'protocol'],
 20    ['spawn_subagent', 'subagent', 'delegate_to_agent'],
 21    ['manage_sessions', 'session_info', 'sessions_tool', 'whoami_tool', 'search_history_tool'],
 22    ['schedule_wake', 'schedule'],
 23    // http_request/http now aliased into web group above
 24    ['memory', 'memory_tool', 'memory_search', 'memory_get', 'memory_store', 'memory_update'],
 25    ['monitor', 'monitor_tool'],
 26    ['context_mgmt', 'context_status', 'context_summarize'],
 27    ['openclaw_workspace'],
 28    ['openclaw_nodes'],
 29    ['image_gen', 'generate_image'],
 30    ['email', 'send_email'],
 31    ['replicate', 'replicate_run', 'replicate_models'],
 32    ['google_workspace', 'gws', 'google-workspace'],
 33    ['mailbox', 'inbox'],
 34    ['ask_human', 'human_loop'],
 35    ['extension_creator'],
 36    ['extension_creator_tool'],
 37  ]
 38  
 39  const EXTENSION_IMPLICATIONS: Record<string, string[]> = {
 40    shell: ['process'],
 41    manage_platform: [
 42      'manage_agents',
 43      'manage_projects',
 44      'manage_tasks',
 45      'manage_schedules',
 46      'manage_skills',
 47      'manage_webhooks',
 48      'manage_connectors',
 49      'manage_sessions',
 50      'manage_secrets',
 51    ],
 52  }
 53  
 54  const EXTENSION_CANONICAL_MAP = (() => {
 55    const map = new Map<string, string>()
 56    for (const group of EXTENSION_ALIAS_GROUPS) {
 57      const normalized = group.map((id) => id.trim().toLowerCase()).filter(Boolean)
 58      const canonical = normalized[0]
 59      if (!canonical) continue
 60      for (const id of normalized) map.set(id, canonical)
 61    }
 62    return map
 63  })()
 64  
 65  const EXTENSION_ALIAS_MAP = (() => {
 66    const map = new Map<string, Set<string>>()
 67    for (const group of EXTENSION_ALIAS_GROUPS) {
 68      const normalized = group.map((id) => id.trim().toLowerCase()).filter(Boolean)
 69      for (const id of normalized) {
 70        const current = map.get(id) || new Set<string>()
 71        for (const alias of normalized) current.add(alias)
 72        map.set(id, current)
 73      }
 74    }
 75    return map
 76  })()
 77  
 78  export function normalizeExtensionId(value: unknown): string {
 79    return typeof value === 'string' ? value.trim().toLowerCase() : ''
 80  }
 81  
 82  export function canonicalizeExtensionId(value: unknown): string {
 83    const raw = typeof value === 'string' ? value.trim() : ''
 84    const normalized = normalizeExtensionId(value)
 85    if (!normalized) return raw
 86    return EXTENSION_CANONICAL_MAP.get(normalized) || raw
 87  }
 88  
 89  export function getExtensionAliases(value: unknown): string[] {
 90    const normalized = normalizeExtensionId(value)
 91    if (!normalized) return []
 92    const aliases = EXTENSION_ALIAS_MAP.get(normalized)
 93    if (!aliases) return [normalized]
 94    return Array.from(aliases)
 95  }
 96  
 97  export function expandExtensionIds(values: string[] | null | undefined): string[] {
 98    if (!Array.isArray(values) || values.length === 0) return []
 99    const expanded = new Set<string>()
100    const queue: string[] = values
101      .map((id) => typeof id === 'string' ? id.trim() : '')
102      .filter(Boolean)
103  
104    while (queue.length > 0) {
105      const next = queue.shift()!
106      const normalized = normalizeExtensionId(next)
107      const canonical = canonicalizeExtensionId(next)
108      const aliases = EXTENSION_ALIAS_MAP.get(normalized)
109      const key = aliases ? normalized : (canonical || next)
110      if (expanded.has(key)) continue
111      expanded.add(key)
112      if (aliases) {
113        for (const alias of aliases) {
114          if (!expanded.has(alias)) queue.push(alias)
115        }
116      }
117      const implicationSources = [key, normalized, normalizeExtensionId(canonical)]
118      for (const source of implicationSources) {
119        if (!source) continue
120        for (const implied of EXTENSION_IMPLICATIONS[source] || []) {
121          if (!expanded.has(implied)) queue.push(implied)
122        }
123      }
124    }
125  
126    return Array.from(expanded)
127  }
128  
129  export function extensionIdMatches(enabledExtensions: string[] | null | undefined, extensionId: string): boolean {
130    const raw = typeof extensionId === 'string' ? extensionId.trim() : ''
131    const normalized = normalizeExtensionId(extensionId)
132    if (!normalized && !raw) return false
133    const expanded = expandExtensionIds(enabledExtensions)
134    return expanded.includes(raw) || expanded.includes(normalized) || expanded.includes(canonicalizeExtensionId(extensionId))
135  }
136  
137  /** @deprecated Use normalizeExtensionId */
138  export const normalizeToolId = normalizeExtensionId
139  /** @deprecated Use canonicalizeExtensionId */
140  export const canonicalizeToolId = canonicalizeExtensionId
141  /** @deprecated Use expandExtensionIds */
142  export const expandToolIds = expandExtensionIds
143  /** @deprecated Use extensionIdMatches */
144  export const toolIdMatches = extensionIdMatches