From 86111c4d54b9978aab0ab0656c6a025f969f9843 Mon Sep 17 00:00:00 2001 From: cynthialong0-0 <82900738+cynthialong0-0@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:16:48 -0700 Subject: [PATCH] feat(browser): dynamically discover read-only tools (#23805) --- .../agents/browser/browserAgentFactory.test.ts | 16 +++++++++++++--- .../src/agents/browser/browserAgentFactory.ts | 13 ++++++------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/packages/core/src/agents/browser/browserAgentFactory.test.ts b/packages/core/src/agents/browser/browserAgentFactory.test.ts index 270b400c3b..003ba465c4 100644 --- a/packages/core/src/agents/browser/browserAgentFactory.test.ts +++ b/packages/core/src/agents/browser/browserAgentFactory.test.ts @@ -379,9 +379,19 @@ describe('browserAgentFactory', () => { it('should register ALLOW rules for read-only tools', async () => { mockBrowserManager.getDiscoveredTools.mockResolvedValue([ - { name: 'take_snapshot', description: 'Take snapshot' }, - { name: 'take_screenshot', description: 'Take screenshot' }, - { name: 'list_pages', description: 'list all pages' }, + { + name: 'take_snapshot', + description: 'Take snapshot', + }, + { + name: 'take_screenshot', + description: 'Take screenshot', + }, + { + name: 'list_pages', + description: 'list all pages', + annotations: { readOnlyHint: true }, + }, ]); await createBrowserAgentDefinition(mockConfig, mockMessageBus); diff --git a/packages/core/src/agents/browser/browserAgentFactory.ts b/packages/core/src/agents/browser/browserAgentFactory.ts index ab42229e89..0d28651c12 100644 --- a/packages/core/src/agents/browser/browserAgentFactory.ts +++ b/packages/core/src/agents/browser/browserAgentFactory.ts @@ -120,13 +120,12 @@ export async function createBrowserAgentDefinition( } // Reduce noise for read-only tools in default mode - const readOnlyTools = [ - 'take_snapshot', - 'take_screenshot', - 'list_pages', - 'list_network_requests', - ]; - for (const toolName of readOnlyTools) { + const readOnlyTools = (await browserManager.getDiscoveredTools()) + .filter((t) => !!t.annotations?.readOnlyHint) + .map((t) => t.name); + const allowlistedReadonlyTools = ['take_snapshot', 'take_screenshot']; + + for (const toolName of [...readOnlyTools, ...allowlistedReadonlyTools]) { if (availableToolNames.includes(toolName)) { const rule = generateAllowRules(toolName); if (!existingRules.some((r) => isRuleEqual(r, rule))) {