+ {group.id === 'browser' && browserCapability ? (
+ <>
+
diff --git a/src/renderer/src/SettingsPanel.test.tsx b/src/renderer/src/SettingsPanel.test.tsx
index e9703d0..e4eb88e 100644
--- a/src/renderer/src/SettingsPanel.test.tsx
+++ b/src/renderer/src/SettingsPanel.test.tsx
@@ -233,7 +233,7 @@ const capabilitySnapshot = {
computerCapabilities: [
{
id: 'host-browser-control' as const,
- name: '浏览器控制',
+ name: '内置浏览器',
description: '使用隔离的托管浏览器配置执行网页操作。',
enabled: false,
supported: true,
@@ -3600,9 +3600,46 @@ describe('SettingsPanel runtime files', () => {
within(mcpTabs).getByRole('tab', { name: '电脑控制' })
)
expect(await screen.findByText('电脑控制能力')).toBeInTheDocument()
- expect(screen.getAllByText('托管浏览器配置').length).toBeGreaterThan(0)
+ expect(
+ screen.getByText('仅显示实际操作客户端电脑的能力')
+ ).toBeInTheDocument()
+ expect(
+ screen.queryByRole('switch', {
+ name: '启用直连模型内置浏览器'
+ })
+ ).not.toBeInTheDocument()
+ expect(screen.queryByText('托管浏览器配置')).not.toBeInTheDocument()
+ expect(
+ screen.getByRole('switch', {
+ name: '启用 Linux 桌面控制'
+ })
+ ).toBeDisabled()
fireEvent.click(
- screen.getByRole('switch', { name: '启用 浏览器控制' })
+ within(mcpTabs).getByRole('tab', { name: '直连模型' })
+ )
+ expect(await screen.findByText('文件系统操作')).toBeInTheDocument()
+ expect(screen.getByText('内置浏览器')).toBeInTheDocument()
+ expect(screen.getByText('联网搜索')).toBeInTheDocument()
+ expect(
+ screen.queryByRole('switch', {
+ name: '启用直连模型内置浏览器'
+ })
+ ).not.toBeInTheDocument()
+ const builtinBrowserToggle = screen.getByRole('button', {
+ name: '展开工具组 内置浏览器'
+ })
+ fireEvent.click(builtinBrowserToggle)
+ expect(builtinBrowserToggle).toHaveAttribute('aria-expanded', 'true')
+ expect(
+ screen.getByText(/不会控制客户端已安装的 Chrome、Edge/)
+ ).toBeInTheDocument()
+ expect(
+ screen.getByText(/此总开关完全由你控制/)
+ ).toHaveTextContent('不再逐次询问')
+ fireEvent.click(
+ screen.getByRole('switch', {
+ name: '启用直连模型内置浏览器'
+ })
)
await waitFor(() =>
expect(setComputerCapabilityEnabled).toHaveBeenCalledWith(
@@ -3610,7 +3647,9 @@ describe('SettingsPanel runtime files', () => {
true
)
)
- fireEvent.click(screen.getByRole('button', { name: '诊断 浏览器控制' }))
+ fireEvent.click(
+ screen.getByRole('button', { name: '诊断内置浏览器' })
+ )
expect(
await screen.findByText('诊断结果:部分可用')
).toBeInTheDocument()
@@ -3647,19 +3686,17 @@ describe('SettingsPanel runtime files', () => {
expect(removeBrowserProfile).toHaveBeenCalledWith(browserProfileId)
)
expect(
- screen.getByRole('switch', {
+ screen.queryByRole('switch', {
name: '启用 Linux 桌面控制'
})
- ).toBeDisabled()
+ ).not.toBeInTheDocument()
expect(
- screen.getByRole('switch', { name: '启用 浏览器控制' })
+ screen.getByRole('switch', {
+ name: '启用直连模型内置浏览器'
+ })
).toBeInTheDocument()
- fireEvent.click(
- within(mcpTabs).getByRole('tab', { name: '直连模型' })
- )
- expect(await screen.findByText('文件系统操作')).toBeInTheDocument()
- expect(screen.getByText('浏览器操作')).toBeInTheDocument()
- expect(screen.getByText('联网搜索')).toBeInTheDocument()
+ fireEvent.click(builtinBrowserToggle)
+ expect(builtinBrowserToggle).toHaveAttribute('aria-expanded', 'false')
expect(screen.queryByText('web_search')).not.toBeInTheDocument()
expect(screen.queryByText('web_fetch')).not.toBeInTheDocument()
const webSearchToggle = screen.getByRole('button', {
@@ -3750,7 +3787,7 @@ describe('SettingsPanel runtime files', () => {
name: '展开工具组 文件系统操作'
})
const browserToggle = screen.getByRole('button', {
- name: '展开工具组 浏览器操作'
+ name: '展开工具组 内置浏览器'
})
fireEvent.click(filesystemToggle)
expect(screen.getByText('读取工作区文本')).toBeInTheDocument()
diff --git a/src/renderer/src/i18n/locales/en-US/app.ts b/src/renderer/src/i18n/locales/en-US/app.ts
index 5167153..23a8ac8 100644
--- a/src/renderer/src/i18n/locales/en-US/app.ts
+++ b/src/renderer/src/i18n/locales/en-US/app.ts
@@ -499,7 +499,7 @@ export const app = {
stopFailed: 'Failed to stop generating. Try again.',
projectNotLoaded: 'The current project has not loaded yet.',
browserControlUnavailable:
- 'Browser controls have not loaded. Restart GoodBuddy.',
+ 'The built-in browser has not loaded. Restart GoodBuddy.',
browserStopFailed: 'Failed to stop the browser. Try again.',
scheduleStarted: 'Scheduled task started',
conversationPersistenceFailed:
diff --git a/src/renderer/src/i18n/locales/en-US/integrations.ts b/src/renderer/src/i18n/locales/en-US/integrations.ts
index c327c6b..31941f4 100644
--- a/src/renderer/src/i18n/locales/en-US/integrations.ts
+++ b/src/renderer/src/i18n/locales/en-US/integrations.ts
@@ -167,6 +167,8 @@ export const integrations = {
unsupportedProfiles:
'Managed browser profiles are unavailable in this version',
test: 'MCP connection test failed',
+ unsupportedBuiltinBrowser:
+ 'The built-in browser is unavailable in this version',
unsupportedComputerControl:
'Computer control capabilities are unavailable in this version'
},
@@ -185,17 +187,12 @@ export const integrations = {
'Built-in tools are provided by GoodBuddy and are not MCP servers. Custom MCP servers and tools run with the current user’s permissions, so add only trusted services. Remote access tokens are encrypted in secure system storage, and tool calls still require GoodBuddy approval.',
computer: {
title: 'Computer control capabilities',
- subtitle: 'Off by default; approval still applies when enabled',
- browserTitle: 'Browser capabilities',
- browserSubtitle: 'Managed browser and built-in browser tools',
+ subtitle: 'Only capabilities that control the client computer',
supported: 'Supported on this device',
unsupported: 'Not supported on this device',
enabled: 'Enabled',
disabled: 'Disabled',
enableAriaLabel: 'Enable {{name}}',
- browserProfile: 'Managed browser profile',
- profileAriaLabel: 'Managed profile used by browser control',
- defaultProfile: 'Use the default managed profile',
diagnoseAriaLabel: 'Diagnose {{name}}',
diagnosing: 'Diagnosing…',
diagnose: 'Run diagnostics',
@@ -219,7 +216,7 @@ export const integrations = {
rename: 'Rename',
deleteAriaLabel: 'Delete profile {{name}}',
delete: 'Delete',
- inUse: 'This profile is used by a computer control capability'
+ inUse: 'This profile is used by the built-in browser'
},
builtin: {
title: 'Built-in GoodBuddy MCP',
@@ -259,6 +256,22 @@ export const integrations = {
expandGroup: 'Expand tool group {{name}}',
summary: 'Built-in GoodBuddy capability for direct models'
},
+ browser: {
+ title: 'Built-in browser',
+ subtitle: 'Direct-model tool · Isolated GoodBuddy browser · Execute',
+ description:
+ 'Opens and operates webpages in GoodBuddy’s temporary isolated browser. It does not control Chrome, Edge, or another browser installed on the client computer.',
+ control:
+ 'You control this master switch. When off, browser tools are unavailable to direct models. When on, direct models can use them directly in Execute mode without per-action prompts.',
+ enableAriaLabel: 'Enable the direct-model built-in browser',
+ enabled: 'Enabled',
+ disabled: 'Disabled',
+ profile: 'Built-in browser profile',
+ profileAriaLabel: 'Managed profile used by the built-in browser',
+ defaultProfile: 'Use the default managed profile',
+ diagnoseAriaLabel: 'Diagnose the built-in browser',
+ toolsAriaLabel: 'Direct-model built-in browser tools'
+ },
webSearch: {
title: 'Web search',
subtitle: 'Direct-model tool · Exa MCP · Ask / Execute',
diff --git a/src/renderer/src/i18n/locales/en-US/warnings.ts b/src/renderer/src/i18n/locales/en-US/warnings.ts
index defdaf2..4cb2ebe 100644
--- a/src/renderer/src/i18n/locales/en-US/warnings.ts
+++ b/src/renderer/src/i18n/locales/en-US/warnings.ts
@@ -7,7 +7,7 @@ export const warnings = {
'document-parsing-settings-recovered':
'The document parsing settings file was corrupt. The original file was isolated, and safe defaults are now in use.',
'capability-settings-recovered':
- 'The capability settings file was corrupt. The original file was isolated. Web search and computer control remain off until you review and enable them.',
+ 'The capability settings file was corrupt. The original file was isolated. Web search, the built-in browser, and computer control remain off until you review and enable them.',
'runtime-settings-recovered':
'The Runtime settings file was corrupt. The original file was isolated, and defaults are now in use.',
'runtime-model-credential-unreadable':
diff --git a/src/renderer/src/i18n/locales/zh-CN/app.ts b/src/renderer/src/i18n/locales/zh-CN/app.ts
index 024f0cf..40201a3 100644
--- a/src/renderer/src/i18n/locales/zh-CN/app.ts
+++ b/src/renderer/src/i18n/locales/zh-CN/app.ts
@@ -469,7 +469,7 @@ export const app = {
sendFailed: '发送失败',
stopFailed: '停止生成失败,请重试',
projectNotLoaded: '当前项目尚未加载。',
- browserControlUnavailable: '浏览器控制组件尚未加载,请重启 GoodBuddy',
+ browserControlUnavailable: '内置浏览器组件尚未加载,请重启 GoodBuddy',
browserStopFailed: '停止浏览器失败,请重试',
scheduleStarted: '定时任务已开始执行',
conversationPersistenceFailed: '会话持久化失败,请检查本地存储',
diff --git a/src/renderer/src/i18n/locales/zh-CN/integrations.ts b/src/renderer/src/i18n/locales/zh-CN/integrations.ts
index 88a6b97..15b9d30 100644
--- a/src/renderer/src/i18n/locales/zh-CN/integrations.ts
+++ b/src/renderer/src/i18n/locales/zh-CN/integrations.ts
@@ -155,6 +155,7 @@ export const integrations = {
diagnostics: '能力诊断失败',
unsupportedProfiles: '当前版本不支持托管浏览器配置',
test: 'MCP 连接测试失败',
+ unsupportedBuiltinBrowser: '当前版本不支持内置浏览器',
unsupportedComputerControl: '当前版本不支持电脑控制能力'
},
addServer: '添加 Server',
@@ -172,17 +173,12 @@ export const integrations = {
'内置工具由 GoodBuddy 提供,不属于 MCP Server。自定义 MCP Server 及其工具具有当前用户权限,请仅添加可信服务;远程访问令牌将由系统安全存储加密,工具调用前仍需 GoodBuddy 审批。',
computer: {
title: '电脑控制能力',
- subtitle: '默认停用,启用后仍遵循审批',
- browserTitle: '浏览器能力',
- browserSubtitle: '托管浏览器与内置浏览器工具',
+ subtitle: '仅显示实际操作客户端电脑的能力',
supported: '当前设备支持',
unsupported: '当前设备不支持',
enabled: '已启用',
disabled: '已停用',
enableAriaLabel: '启用 {{name}}',
- browserProfile: '托管浏览器配置',
- profileAriaLabel: '浏览器控制使用的托管配置',
- defaultProfile: '使用默认托管配置',
diagnoseAriaLabel: '诊断 {{name}}',
diagnosing: '诊断中…',
diagnose: '运行诊断',
@@ -206,7 +202,7 @@ export const integrations = {
rename: '重命名',
deleteAriaLabel: '删除配置 {{name}}',
delete: '删除',
- inUse: '此配置正被电脑控制能力使用'
+ inUse: '此配置正被内置浏览器使用'
},
builtin: {
title: 'GoodBuddy 内置 MCP',
@@ -242,6 +238,22 @@ export const integrations = {
expandGroup: '展开工具组 {{name}}',
summary: 'GoodBuddy 直连模型内置能力'
},
+ browser: {
+ title: '内置浏览器',
+ subtitle: '直连模型工具 · GoodBuddy 隔离浏览器 · Execute',
+ description:
+ '在 GoodBuddy 内置的临时隔离浏览器中打开并操作网页,不会控制客户端已安装的 Chrome、Edge 或其他浏览器。',
+ control:
+ '此总开关完全由你控制:关闭时不向直连模型提供浏览器工具;开启后,直连模型可在 Execute 模式直接使用,不再逐次询问。',
+ enableAriaLabel: '启用直连模型内置浏览器',
+ enabled: '已启用',
+ disabled: '已停用',
+ profile: '内置浏览器配置',
+ profileAriaLabel: '内置浏览器使用的托管配置',
+ defaultProfile: '使用默认托管配置',
+ diagnoseAriaLabel: '诊断内置浏览器',
+ toolsAriaLabel: '直连模型内置浏览器工具'
+ },
webSearch: {
title: '联网搜索',
subtitle: '直连模型工具 · Exa MCP · Ask / Execute',
diff --git a/src/renderer/src/i18n/locales/zh-CN/warnings.ts b/src/renderer/src/i18n/locales/zh-CN/warnings.ts
index d760393..91b2d15 100644
--- a/src/renderer/src/i18n/locales/zh-CN/warnings.ts
+++ b/src/renderer/src/i18n/locales/zh-CN/warnings.ts
@@ -4,7 +4,7 @@ export const warnings = {
'document-parsing-settings-recovered':
'文档解析设置文件已损坏。原文件已隔离,当前使用安全默认设置。',
'capability-settings-recovered':
- '能力设置文件已损坏。原文件已隔离,网页搜索和电脑控制已保持关闭,请检查后手动启用。',
+ '能力设置文件已损坏。原文件已隔离,联网搜索、内置浏览器和电脑控制已保持关闭,请检查后手动启用。',
'runtime-settings-recovered':
'Runtime 设置文件已损坏。原文件已隔离,当前使用默认设置。',
'runtime-model-credential-unreadable':
diff --git a/src/shared/builtin-model-tools.ts b/src/shared/builtin-model-tools.ts
index 39dcb40..4292042 100644
--- a/src/shared/builtin-model-tools.ts
+++ b/src/shared/builtin-model-tools.ts
@@ -106,9 +106,9 @@ export const builtinModelToolGroups = [
},
{
id: 'browser',
- name: '浏览器操作',
+ name: '内置浏览器',
description:
- '启用“浏览器控制”后,在 Execute 模式下操作 GoodBuddy 隔离浏览器。',
+ '启用“内置浏览器”后,在 Execute 模式下操作 GoodBuddy 隔离浏览器。',
tools: builtinModelTools.filter((tool) => tool.group === 'browser')
},
{