@@ -1489,6 +1489,7 @@ import { ApprovalManager } from './approval-manager';
14891489⋮----
14901490import type { ToolSet } from 'ai';
14911491⋮----
1492+ import { coerceBoolean } from '@/agent/utils';
14921493import { Task } from '@/task';
14931494⋮----
14941495export const createAiderToolset = (task: Task, profile: AgentProfile, promptContext?: PromptContext): ToolSet =>
@@ -1628,7 +1629,7 @@ import logger from '@/logger';
16281629import { ensureRipgrepBinary, filterIgnoredFiles, scrapeWeb } from '@/utils';
16291630import { isAbortError, isFileNotFoundError } from '@/utils/errors';
16301631import { getShellCommandArgs, getShellPath } from '@/utils/shell';
1631- import { expandTilde, readFileContent, truncateToolResult } from '@/agent/utils';
1632+ import { expandTilde, readFileContent, truncateToolResult, coerceBoolean } from '@/agent/utils';
16321633import { RIPGREP_BINARY_PATH } from '@/constants';
16331634⋮----
16341635/**
@@ -1849,6 +1850,7 @@ import { fileExists, isUuid } from '@common/utils';
18491850⋮----
18501851import { ApprovalManager } from './approval-manager';
18511852⋮----
1853+ import { coerceBoolean } from '@/agent/utils';
18521854import { AIDER_DESK_TASKS_DIR } from '@/constants';
18531855import { search } from '@/utils/probe';
18541856import logger from '@/logger';
@@ -1910,6 +1912,7 @@ import { AgentProfile, PromptContext, ToolApprovalState } from '@common/types';
19101912⋮----
19111913import { ApprovalManager } from './approval-manager';
19121914⋮----
1915+ import { coerceBoolean } from '@/agent/utils';
19131916import { Task } from '@/task';
19141917⋮----
19151918export const createTodoToolset = (task: Task, profile: AgentProfile, promptContext?: PromptContext): ToolSet =>
@@ -2962,8 +2965,14 @@ import path from 'path';
29622965// @ts-expect-error istextorbinary is not typed properly
29632966import { isBinary } from 'istextorbinary';
29642967import { encode } from 'gpt-tokenizer/model/gpt-4o';
2968+ import { z } from 'zod';
29652969import { ContextMessage, ContextUserMessage, MessageRole, PromptContext } from '@common/types';
29662970⋮----
2971+ /**
2972+ * Zod schema that coerces string values to booleans before validation.
2973+ * Handles the case where LLMs send boolean parameters as strings ("true"/"false").
2974+ */
2975+ ⋮----
29672976/**
29682977 * Extracts PromptContext from a tool result if available.
29692978 * @param toolResult - The tool result object to extract PromptContext from
@@ -3756,8 +3765,10 @@ import path from 'path';
37563765import { FSWatcher, watch } from 'chokidar';
37573766import debounce from 'lodash/debounce';
37583767import { z } from 'zod';
3759- import { AvailableExtension, ExtensionConfigComponent, SettingsData, SkillDefinition, ToolApprovalState } from '@common/types';
3768+ import { AvailableExtension, ExtensionConfigComponent, ExtensionToolInfo, SettingsData, SkillDefinition, ToolApprovalState } from '@common/types';
3769+ import { TOOL_GROUP_NAME_SEPARATOR } from '@common/tools';
37603770import { AIDER_DESK_EXTENSIONS_REPO_URL, ProviderDefinition, Tool, UIComponentDefinition } from '@common/extensions';
3771+ import { DEFAULT_AGENT_PROFILE } from '@common/agent';
37613772⋮----
37623773import { ExtensionLoader } from './extension-loader';
37633774import { ExtensionRegistry, LoadedExtension } from './extension-registry';
@@ -3819,6 +3830,7 @@ import type { ToolCallOptions, ToolSet } from 'ai';
38193830import { shouldUsePolling } from '@/utils/file-watch';
38203831import logger from '@/logger';
38213832import { AIDER_DESK_EXTENSIONS_DIR, AIDER_DESK_GLOBAL_EXTENSIONS_DIR } from '@/constants';
3833+ import { ApprovalManager } from '@/agent/tools/approval-manager';
38223834import { Project } from '@/project';
38233835import { Task } from '@/task';
38243836⋮----
@@ -4013,6 +4025,8 @@ private async restartWatchers(): Promise<void>
40134025⋮----
40144026validateToolDefinition(tool: ToolDefinition):
40154027⋮----
4028+ getToolsInfo(projectDir?: string): ExtensionToolInfo[]
4029+ ⋮----
40164030getTools(task: Task, mode: string, profile: AgentProfile): RegisteredTool[]
40174031⋮----
40184032/**
@@ -4026,9 +4040,20 @@ getTools(task: Task, mode: string, profile: AgentProfile): RegisteredTool[]
40264040 * @param abortSignal - Optional AbortSignal for cancellation support
40274041 * @returns A ToolSet containing all approved extension tools
40284042 */
4029- createExtensionToolset(task: Task, mode: string, profile: AgentProfile, allTools: ToolSet, abortSignal?: AbortSignal): ToolSet
4043+ createExtensionToolset(
4044+ task: Task,
4045+ mode: string,
4046+ profile: AgentProfile,
4047+ allTools: ToolSet,
4048+ approvalManager: ApprovalManager,
4049+ abortSignal?: AbortSignal,
4050+ ): ToolSet
4051+ ⋮----
4052+ // Tool approval filtering is handled in getTools()
40304053⋮----
4031- // Skip if tool is marked as Never approved
4054+ // --- Tool Approval Logic ---
4055+ ⋮----
4056+ // --- End Tool Approval Logic ---
40324057⋮----
40334058// Error isolation - log and return error message
40344059⋮----
@@ -7286,6 +7311,8 @@ registerRoutes(router: Router): void
72867311⋮----
72877312// Get installed extensions
72887313⋮----
7314+ // Get extension tools info
7315+ ⋮----
72897316// Get available extensions from repositories
72907317⋮----
72917318// Install extension
@@ -11176,6 +11203,7 @@ import {
1117611203 EnvironmentVariable,
1117711204 FileEdit,
1117811205 InstalledExtension,
11206+ ExtensionToolInfo,
1117911207 McpServerConfig,
1118011208 McpTool,
1118111209 MemoryEntry,
@@ -11530,6 +11558,8 @@ getMemoryEmbeddingProgress()
1153011558⋮----
1153111559getInstalledExtensions(projectDir?: string): InstalledExtension[]
1153211560⋮----
11561+ getExtensionToolsInfo(projectDir?: string): ExtensionToolInfo[]
11562+ ⋮----
1153311563async getAvailableExtensions(repositories: string[], forceRefresh?: boolean, fetchOnly?: boolean)
1153411564⋮----
1153511565async installExtension(extensionId: string, repositoryUrl: string, projectDir?: string)
@@ -12600,6 +12630,7 @@ import {
1260012630 InstalledExtension,
1260112631 AvailableExtension,
1260212632 ExtensionConfigComponent,
12633+ ExtensionToolInfo,
1260312634 ExtensionUIComponent,
1260412635 ModalOverlayUrlData,
1260512636 AiderConnectorStatus,
@@ -12972,6 +13003,8 @@ addSystemLogListener(callback: (data: SystemLogData) => void): () => void
1297213003⋮----
1297313004getInstalledExtensions(projectDir?: string): Promise<InstalledExtension[]>
1297413005⋮----
13006+ getExtensionToolsInfo(projectDir?: string): Promise<ExtensionToolInfo[]>
13007+ ⋮----
1297513008getAvailableExtensions(repositories: string[], forceRefresh?: boolean, fetchOnly?: boolean): Promise<AvailableExtension[]>
1297613009⋮----
1297713010installExtension(extensionId: string, repositoryUrl: string, projectDir?: string): Promise<boolean>
@@ -20035,6 +20068,7 @@ import {
2003520068 AgentProfile,
2003620069 ContextCompactionType,
2003720070 ContextMemoryMode,
20071+ ExtensionToolInfo,
2003820072 GenericTool,
2003920073 InvocationMode,
2004020074 McpServerConfig,
@@ -20046,7 +20080,17 @@ import {
2004620080import React, { ReactNode, useEffect, useMemo, useRef, useState } from 'react';
2004720081import { v4 as uuidv4 } from 'uuid';
2004820082import { FaChevronLeft, FaChevronRight, FaList, FaPaste, FaPencilAlt, FaPlus, FaSyncAlt, FaTimes, FaBrain } from 'react-icons/fa';
20049- import { MdFlashOn, MdOutlineChecklist, MdOutlineFileCopy, MdOutlineHdrAuto, MdOutlineMap, MdRepeat, MdThermostat, MdPsychology } from 'react-icons/md';
20083+ import {
20084+ MdExtension,
20085+ MdFlashOn,
20086+ MdOutlineChecklist,
20087+ MdOutlineFileCopy,
20088+ MdOutlineHdrAuto,
20089+ MdOutlineMap,
20090+ MdRepeat,
20091+ MdThermostat,
20092+ MdPsychology,
20093+ } from 'react-icons/md';
2005020094import { DEFAULT_AGENT_PROFILE, getProviderModelId, DEFAULT_AGENT_PROFILES } from '@common/agent';
2005120095import { BiTrash } from 'react-icons/bi';
2005220096import { clsx } from 'clsx';
@@ -20272,6 +20316,8 @@ onChange=
2027220316⋮----
2027320317{/* Compaction Type */}
2027420318⋮----
20319+ const handleExtEnabledChange = (enabled: boolean) =>
20320+ ⋮----
2027520321onRemove=
2027620322onEdit=
2027720323⋮----
@@ -20313,6 +20359,7 @@ import { Checkbox } from '@/components/common/Checkbox';
2031320359⋮----
2031420360type Props = {
2031520361 name: string;
20362+ displayName?: string;
2031620363 tools: GenericTool[];
2031720364 profile: AgentProfile;
2031820365 onApprovalChange: (toolId: string, approval: ToolApprovalState) => void;
0 commit comments