refactor(setting): Improve settings migration and tool loading (#7445)

Co-authored-by: psinha40898 <pyushsinha20@gmail.com>
This commit is contained in:
Gal Zahavi
2025-09-03 19:23:25 -07:00
committed by GitHub
parent e7a4142b2a
commit 3885f7b6ae
7 changed files with 552 additions and 311 deletions
+85 -1
View File
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import type { Mock } from 'vitest';
import type { ConfigParameters, SandboxConfig } from './config.js';
import { Config, ApprovalMode } from './config.js';
@@ -671,6 +671,90 @@ describe('Server Config (config.ts)', () => {
).mock.calls.some((call) => call[0] instanceof vi.mocked(ReadFileTool));
expect(wasReadFileToolRegistered).toBe(false);
});
describe('with minified tool class names', () => {
beforeEach(() => {
Object.defineProperty(
vi.mocked(ShellTool).prototype.constructor,
'name',
{
value: '_ShellTool',
configurable: true,
},
);
});
afterEach(() => {
Object.defineProperty(
vi.mocked(ShellTool).prototype.constructor,
'name',
{
value: 'ShellTool',
},
);
});
it('should register a tool if coreTools contains the non-minified class name', async () => {
const params: ConfigParameters = {
...baseParams,
coreTools: ['ShellTool'],
};
const config = new Config(params);
await config.initialize();
const registerToolMock = (
(await vi.importMock('../tools/tool-registry')) as {
ToolRegistry: { prototype: { registerTool: Mock } };
}
).ToolRegistry.prototype.registerTool;
const wasShellToolRegistered = (
registerToolMock as Mock
).mock.calls.some((call) => call[0] instanceof vi.mocked(ShellTool));
expect(wasShellToolRegistered).toBe(true);
});
it('should not register a tool if excludeTools contains the non-minified class name', async () => {
const params: ConfigParameters = {
...baseParams,
coreTools: undefined, // all tools enabled by default
excludeTools: ['ShellTool'],
};
const config = new Config(params);
await config.initialize();
const registerToolMock = (
(await vi.importMock('../tools/tool-registry')) as {
ToolRegistry: { prototype: { registerTool: Mock } };
}
).ToolRegistry.prototype.registerTool;
const wasShellToolRegistered = (
registerToolMock as Mock
).mock.calls.some((call) => call[0] instanceof vi.mocked(ShellTool));
expect(wasShellToolRegistered).toBe(false);
});
it('should register a tool if coreTools contains an argument-specific pattern with the non-minified class name', async () => {
const params: ConfigParameters = {
...baseParams,
coreTools: ['ShellTool(git status)'],
};
const config = new Config(params);
await config.initialize();
const registerToolMock = (
(await vi.importMock('../tools/tool-registry')) as {
ToolRegistry: { prototype: { registerTool: Mock } };
}
).ToolRegistry.prototype.registerTool;
const wasShellToolRegistered = (
registerToolMock as Mock
).mock.calls.some((call) => call[0] instanceof vi.mocked(ShellTool));
expect(wasShellToolRegistered).toBe(true);
});
});
});
});
+6 -4
View File
@@ -844,20 +844,22 @@ export class Config {
const toolName = ToolClass.Name || className;
const coreTools = this.getCoreTools();
const excludeTools = this.getExcludeTools() || [];
// On some platforms, the className can be minified to _ClassName.
const normalizedClassName = className.replace(/^_+/, '');
let isEnabled = true; // Enabled by default if coreTools is not set.
if (coreTools) {
isEnabled = coreTools.some(
(tool) =>
tool === className ||
tool === toolName ||
tool.startsWith(`${className}(`) ||
tool.startsWith(`${toolName}(`),
tool === normalizedClassName ||
tool.startsWith(`${toolName}(`) ||
tool.startsWith(`${normalizedClassName}(`),
);
}
const isExcluded = excludeTools.some(
(tool) => tool === className || tool === toolName,
(tool) => tool === toolName || tool === normalizedClassName,
);
if (isExcluded) {