fix: move built-in browser to direct model tools
Browser control was grouped with client PC control even though it operates GoodBuddy's isolated browser. It now appears as Built-in Browser under direct-model tools with its existing master switch, profiles, and diagnostics, while Computer Control only lists capabilities that act on the client PC. The existing capability ID and saved state are preserved. Enabling the browser lets direct models use it in Execute mode without per-action prompts. Release note: 将内置浏览器移至直连模型工具,并明确它不会控制客户端已安装的浏览器;原有开关状态保持不变。
This commit is contained in:
+2
-1
@@ -64,7 +64,8 @@
|
||||
|
||||
### 浏览器、通信、语音与应用维护
|
||||
|
||||
- [x] **浏览器和桌面受控工具**:保留范围、取消、超时、输出边界和执行记录。
|
||||
- [x] **直连模型内置浏览器**:使用 GoodBuddy 内置的隔离 Chromium,不控制客户端已安装的浏览器;用户通过独立总开关决定是否提供给 Execute,开启后不逐次询问。
|
||||
- [x] **客户端电脑控制工具**:与内置浏览器分开管理,并保留范围、取消、超时、输出边界和执行记录。
|
||||
- [x] **远程消息通道项目**:微信 ClawBot、企业微信和钉钉分别拥有系统管理的项目、独立远程会话、工作目录、处理后端、默认 Ask/Execute 模式及任务活动归属。
|
||||
- [x] **微信 ClawBot 扫码与媒体**:通过独立 Sidecar 完成本机扫码、验证码、加密凭据和文字收发;支持个人微信私聊图片与文件,单条消息最多 4 个附件、解密后合计不超过 12MB。
|
||||
- [x] **微信安全回传**:支持返回当前任务生成的图片,或在用户明确要求时将本次最终文本生成为 Markdown 附件;不自动读取或发送已有工作区文件。
|
||||
|
||||
+1
-1
@@ -539,7 +539,7 @@ GoodBuddy 是可调整窗口大小的桌面应用。响应式设计优先保证
|
||||
- Agent Runtime 页面在低层程序与配置覆盖之外提供“能力与默认配置”区域。能力清单使用共享 `PageTabs`,按 Agents、Tools、Commands、Skills、MCP、Rules、Prompts、Resources、LSP、Formatters 和上下文 11 类单行滚动展示,一次只呈现当前分类的 `tabpanel`;清单只显示 Runtime 自有能力,不混入 GoodBuddy 分配的 Skills、临时 MCP 或 Continue 预设。Tools 必须独立于 Commands、LSP 和 Formatters,显示工具类型、来源及 Ask/Execute 可用性;清单状态必须区分完整、部分、不可用、仅连接和不支持,不能用进程连通性冒充清单可读。
|
||||
- “能力与默认配置”只显示一个模块标题,刷新入口位于该标题右侧,能力状态压缩为一行并排在默认 Agent 或 Continue 预设编辑器之前;不得再复制“Runtime 原生能力”等同义标题、说明或状态结论。刷新只更新能力快照,不覆盖未保存的原生定制草稿。
|
||||
- OpenCode 的默认 Agent 使用原生下拉选择;Continue 预设编辑器允许管理名称、说明、启用的 Rules 以及 Prompt 名称、说明和正文,并可展开查看原生 Rules 与启用预设 Rules 的最终合并顺序。持久启停仍使用共享 Switch,添加与删除使用明确按钮和可访问名称。
|
||||
- MCP 设置按“内置 MCP / 直连模型 / 自定义 MCP / 电脑控制”四个同级 `PageTabs` 组织。直连模型中的联网搜索与其他内置工具组使用一致的折叠卡片,展开后显示开关、测试状态、隐私说明和工具列表。内置 MCP 卡片与 Skills 一样提供持久启停和 Runtime 分配;直连模型、GoodBuddy 管理的 OpenCode 与 Continue 默认选中且可调整,DeepSeek Harness 必须以置灰、未选择和“暂不支持”文案持续显示,不能呈现为可保存的分配。魔法笔记 MCP 的自身启停与平台功能依赖分别显示,依赖未开启时保留用户配置并说明当前不会加载。
|
||||
- MCP 设置按“内置 MCP / 直连模型 / 自定义 MCP / 电脑控制”四个同级 `PageTabs` 组织。直连模型中的联网搜索与内置浏览器使用一致的折叠卡片和独立总开关;内置浏览器必须明确说明其操作 GoodBuddy 隔离浏览器,不控制客户端已安装的浏览器,开启后可由 Execute 直接使用,不逐次询问。托管浏览器配置归入直连模型,“电脑控制”只显示实际操作客户端电脑的能力。内置 MCP 卡片与 Skills 一样提供持久启停和 Runtime 分配;直连模型、GoodBuddy 管理的 OpenCode 与 Continue 默认选中且可调整,DeepSeek Harness 必须以置灰、未选择和“暂不支持”文案持续显示,不能呈现为可保存的分配。魔法笔记 MCP 的自身启停与平台功能依赖分别显示,依赖未开启时保留用户配置并说明当前不会加载。
|
||||
- MCP Server 测试结果在同一展开卡片中分组显示 Tools、Prompts 和 Resources 的支持状态、数量与有界元数据;Prompt 参数标明必填项,Resource 只显示 URI、名称、类型和说明,不读取或渲染 Resource 内容。
|
||||
|
||||
### 13.8 文档解析设置
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
| --- | --- |
|
||||
| 文档类型 | 实施进度 |
|
||||
| 状态 | 持续更新 |
|
||||
| 版本 | 0.1 |
|
||||
| 日期 | 2026-08-07 |
|
||||
| 适用能力 | 电脑控制与托管浏览器 |
|
||||
| 版本 | 0.2 |
|
||||
| 日期 | 2026-08-18 |
|
||||
| 适用能力 | 内置浏览器与客户端电脑控制 |
|
||||
|
||||
## 范围
|
||||
|
||||
@@ -60,10 +60,12 @@ Linux x64 和 Linux arm64。
|
||||
### 设置与安全边界
|
||||
|
||||
- 能力存储已迁移到版本 2。
|
||||
- 已增加电脑控制能力卡片、诊断、托管浏览器配置元数据、IPC 和 preload
|
||||
契约。
|
||||
- 电脑控制能力默认关闭;启用、配置变更和本地数据清除会替换或清理相关
|
||||
Runtime 和会话。
|
||||
- 内置浏览器已归入“直连模型”工具,与联网搜索并列,并明确说明不会控制
|
||||
客户端已安装的浏览器;原有开关和配置 ID 保持不变,用户状态无需迁移。
|
||||
- 用户通过内置浏览器总开关决定是否向直连模型提供工具;开启后可在 Execute
|
||||
模式直接使用,不逐次询问。托管浏览器配置和诊断也位于同一分类。
|
||||
- “电脑控制”只显示实际操作客户端电脑的能力。能力启用、配置变更和本地
|
||||
数据清除仍会替换或清理相关 Runtime 和会话。
|
||||
|
||||
## 本轮已修复缺陷
|
||||
|
||||
|
||||
@@ -41,6 +41,9 @@ describe('computer capability catalog', () => {
|
||||
new Set(['managed-linux-desktop-driver'])
|
||||
)
|
||||
).toBe(true)
|
||||
expect(browser.name).toBe('内置浏览器')
|
||||
expect(browser.description).toContain('不会控制客户端已安装的浏览器')
|
||||
expect(browser.riskSummary).toContain('不再逐次询问')
|
||||
expect(desktop.description).toContain('技术预览')
|
||||
expect(desktop.riskSummary).toContain('尚未')
|
||||
})
|
||||
|
||||
@@ -34,9 +34,9 @@ export const computerCapabilityCatalog: readonly ComputerCapabilityCatalogEntry[
|
||||
Object.freeze([
|
||||
Object.freeze({
|
||||
id: 'host-browser-control',
|
||||
name: '浏览器控制',
|
||||
name: '内置浏览器',
|
||||
description:
|
||||
'使用临时隔离会话执行网页操作;命名配置当前仅保存未来托管隔离所需的元数据。',
|
||||
'使用 GoodBuddy 内置的临时隔离浏览器执行网页操作,不会控制客户端已安装的浏览器;命名配置当前仅保存未来托管隔离所需的元数据。',
|
||||
enabledByDefault: false,
|
||||
implementationKind: 'managed-browser-driver',
|
||||
supportedTargets: Object.freeze([
|
||||
@@ -54,7 +54,7 @@ export const computerCapabilityCatalog: readonly ComputerCapabilityCatalogEntry[
|
||||
})
|
||||
]),
|
||||
riskSummary:
|
||||
'可读取网页内容并代表用户操作网站;当前执行不会复用命名配置,仍必须保持临时隔离和审批策略。',
|
||||
'总开关关闭时不会向直连模型提供浏览器工具;开启后可在 Execute 模式直接读取网页并操作网站,不再逐次询问。',
|
||||
requiredDiagnostics: Object.freeze([
|
||||
'browser-executable',
|
||||
'managed-profile-root'
|
||||
|
||||
@@ -396,6 +396,12 @@ export function McpSettingsSection({
|
||||
}
|
||||
|
||||
const computerCapabilities = snapshot?.computerCapabilities ?? []
|
||||
const browserCapability = computerCapabilities.find(
|
||||
(capability) => capability.id === 'host-browser-control'
|
||||
)
|
||||
const desktopCapabilities = computerCapabilities.filter(
|
||||
(capability) => capability.id !== 'host-browser-control'
|
||||
)
|
||||
const builtinMcpStates = new Map(
|
||||
snapshot?.builtinMcpServers?.map((server) => [server.id, server])
|
||||
)
|
||||
@@ -501,7 +507,7 @@ export function McpSettingsSection({
|
||||
</small>
|
||||
</div>
|
||||
<div className="capability-list">
|
||||
{computerCapabilities.map((capability) => {
|
||||
{desktopCapabilities.map((capability) => {
|
||||
const report = diagnostics[capability.id]
|
||||
return (
|
||||
<article className="capability-card" key={capability.id}>
|
||||
@@ -553,38 +559,6 @@ export function McpSettingsSection({
|
||||
<CircleAlert aria-hidden="true" size={13} />
|
||||
{capability.riskSummary}
|
||||
</p>
|
||||
{capability.id === 'host-browser-control' && (
|
||||
<label className="field computer-capability-profile">
|
||||
<span>{t('mcp.computer.browserProfile')}</span>
|
||||
<select
|
||||
aria-label={t('mcp.computer.profileAriaLabel')}
|
||||
disabled={Boolean(busy)}
|
||||
onChange={(event) =>
|
||||
void run('computer:profile', () =>
|
||||
window.goodbuddy.capabilities.setComputerCapabilityBrowserProfile?.(
|
||||
capability.id,
|
||||
event.target.value || null
|
||||
) ??
|
||||
Promise.reject(
|
||||
new Error(
|
||||
t('mcp.errors.unsupportedProfiles')
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
value={capability.browserProfileId ?? ''}
|
||||
>
|
||||
<option value="">
|
||||
{t('mcp.computer.defaultProfile')}
|
||||
</option>
|
||||
{browserProfiles.profiles.map((profile) => (
|
||||
<option key={profile.id} value={profile.id}>
|
||||
{profile.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
)}
|
||||
<div className="capability-diagnostic">
|
||||
<button
|
||||
aria-label={t('mcp.computer.diagnoseAriaLabel', {
|
||||
@@ -627,7 +601,7 @@ export function McpSettingsSection({
|
||||
</section>
|
||||
)}
|
||||
|
||||
{activeTab === 'computer' && (
|
||||
{activeTab === 'model-tools' && browserCapability && (
|
||||
<section
|
||||
aria-labelledby="browser-profiles-heading"
|
||||
className="mcp-tool-section"
|
||||
@@ -1150,6 +1124,18 @@ export function McpSettingsSection({
|
||||
const expansionId = `model-tools:${group.id}`
|
||||
const expanded = expandedItemIds.has(expansionId)
|
||||
const panelId = `model-tool-group-${group.id}`
|
||||
const groupName =
|
||||
group.id === 'browser'
|
||||
? t('mcp.browser.title')
|
||||
: group.name
|
||||
const groupDescription =
|
||||
group.id === 'browser'
|
||||
? t('mcp.browser.description')
|
||||
: group.description
|
||||
const report =
|
||||
group.id === 'browser' && browserCapability
|
||||
? diagnostics[browserCapability.id]
|
||||
: undefined
|
||||
return (
|
||||
<article className="mcp-server-card" key={group.id}>
|
||||
<button
|
||||
@@ -1159,15 +1145,19 @@ export function McpSettingsSection({
|
||||
expanded
|
||||
? 'mcp.modelTools.collapseGroup'
|
||||
: 'mcp.modelTools.expandGroup',
|
||||
{ name: group.name }
|
||||
{ name: groupName }
|
||||
)}
|
||||
className="mcp-server-card__toggle"
|
||||
onClick={() => toggleItem(expansionId)}
|
||||
type="button"
|
||||
>
|
||||
<div>
|
||||
<strong>{group.name}</strong>
|
||||
<small>{t('mcp.modelTools.summary')}</small>
|
||||
<strong>{groupName}</strong>
|
||||
<small>
|
||||
{group.id === 'browser'
|
||||
? t('mcp.browser.subtitle')
|
||||
: t('mcp.modelTools.summary')}
|
||||
</small>
|
||||
</div>
|
||||
<span className="mcp-server-card__summary">
|
||||
{t('mcp.builtin.toolCount', {
|
||||
@@ -1186,11 +1176,137 @@ export function McpSettingsSection({
|
||||
</button>
|
||||
{expanded && (
|
||||
<div className="mcp-server-card__body" id={panelId}>
|
||||
<p>{group.description}</p>
|
||||
<section
|
||||
aria-label={t('mcp.builtin.toolsAriaLabel', {
|
||||
name: group.name
|
||||
{group.id === 'browser' && browserCapability ? (
|
||||
<>
|
||||
<label className="toggle-row">
|
||||
<input
|
||||
aria-label={t(
|
||||
'mcp.browser.enableAriaLabel'
|
||||
)}
|
||||
checked={browserCapability.enabled}
|
||||
disabled={
|
||||
Boolean(busy) ||
|
||||
!browserCapability.supported
|
||||
}
|
||||
onChange={(event) =>
|
||||
void run(
|
||||
`browser:${browserCapability.id}`,
|
||||
() =>
|
||||
window.goodbuddy.capabilities.setComputerCapabilityEnabled?.(
|
||||
browserCapability.id,
|
||||
event.target.checked
|
||||
) ??
|
||||
Promise.reject(
|
||||
new Error(
|
||||
t(
|
||||
'mcp.errors.unsupportedBuiltinBrowser'
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
role="switch"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span>
|
||||
{browserCapability.enabled
|
||||
? t('mcp.browser.enabled')
|
||||
: t('mcp.browser.disabled')}
|
||||
</span>
|
||||
</label>
|
||||
<p>{groupDescription}</p>
|
||||
<p className="computer-capability-risk">
|
||||
<CircleAlert aria-hidden="true" size={13} />
|
||||
{t('mcp.browser.control')}
|
||||
</p>
|
||||
<label className="field computer-capability-profile">
|
||||
<span>{t('mcp.browser.profile')}</span>
|
||||
<select
|
||||
aria-label={t('mcp.browser.profileAriaLabel')}
|
||||
disabled={Boolean(busy)}
|
||||
onChange={(event) =>
|
||||
void run('browser:profile', () =>
|
||||
window.goodbuddy.capabilities.setComputerCapabilityBrowserProfile?.(
|
||||
browserCapability.id,
|
||||
event.target.value || null
|
||||
) ??
|
||||
Promise.reject(
|
||||
new Error(
|
||||
t('mcp.errors.unsupportedProfiles')
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
value={
|
||||
browserCapability.browserProfileId ?? ''
|
||||
}
|
||||
>
|
||||
<option value="">
|
||||
{t('mcp.browser.defaultProfile')}
|
||||
</option>
|
||||
{browserProfiles.profiles.map((profile) => (
|
||||
<option key={profile.id} value={profile.id}>
|
||||
{profile.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
<div className="capability-diagnostic">
|
||||
<button
|
||||
aria-label={t(
|
||||
'mcp.browser.diagnoseAriaLabel'
|
||||
)}
|
||||
className="secondary-button"
|
||||
disabled={Boolean(busy)}
|
||||
onClick={() =>
|
||||
void diagnose(browserCapability.id)
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
<RefreshCw size={13} />
|
||||
{busy ===
|
||||
`diagnose:${browserCapability.id}`
|
||||
? t('mcp.computer.diagnosing')
|
||||
: t('mcp.computer.diagnose')}
|
||||
</button>
|
||||
{report && (
|
||||
<div
|
||||
aria-live="polite"
|
||||
className="capability-diagnostic__result"
|
||||
>
|
||||
<strong>
|
||||
{t('mcp.computer.result', {
|
||||
status:
|
||||
diagnosticStatusLabels[
|
||||
report.status
|
||||
]
|
||||
})}
|
||||
</strong>
|
||||
{report.checks.map((check) => (
|
||||
<p key={check.id}>
|
||||
{check.summary}
|
||||
{check.remedy
|
||||
? t('mcp.computer.remedy', {
|
||||
remedy: check.remedy
|
||||
})
|
||||
: ''}
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<p>{groupDescription}</p>
|
||||
)}
|
||||
<section
|
||||
aria-label={
|
||||
group.id === 'browser'
|
||||
? t('mcp.browser.toolsAriaLabel')
|
||||
: t('mcp.builtin.toolsAriaLabel', {
|
||||
name: groupName
|
||||
})
|
||||
}
|
||||
className="mcp-server-tools"
|
||||
>
|
||||
<div className="mcp-server-tools__heading">
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -469,7 +469,7 @@ export const app = {
|
||||
sendFailed: '发送失败',
|
||||
stopFailed: '停止生成失败,请重试',
|
||||
projectNotLoaded: '当前项目尚未加载。',
|
||||
browserControlUnavailable: '浏览器控制组件尚未加载,请重启 GoodBuddy',
|
||||
browserControlUnavailable: '内置浏览器组件尚未加载,请重启 GoodBuddy',
|
||||
browserStopFailed: '停止浏览器失败,请重试',
|
||||
scheduleStarted: '定时任务已开始执行',
|
||||
conversationPersistenceFailed: '会话持久化失败,请检查本地存储',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -4,7 +4,7 @@ export const warnings = {
|
||||
'document-parsing-settings-recovered':
|
||||
'文档解析设置文件已损坏。原文件已隔离,当前使用安全默认设置。',
|
||||
'capability-settings-recovered':
|
||||
'能力设置文件已损坏。原文件已隔离,网页搜索和电脑控制已保持关闭,请检查后手动启用。',
|
||||
'能力设置文件已损坏。原文件已隔离,联网搜索、内置浏览器和电脑控制已保持关闭,请检查后手动启用。',
|
||||
'runtime-settings-recovered':
|
||||
'Runtime 设置文件已损坏。原文件已隔离,当前使用默认设置。',
|
||||
'runtime-model-credential-unreadable':
|
||||
|
||||
@@ -106,9 +106,9 @@ export const builtinModelToolGroups = [
|
||||
},
|
||||
{
|
||||
id: 'browser',
|
||||
name: '浏览器操作',
|
||||
name: '内置浏览器',
|
||||
description:
|
||||
'启用“浏览器控制”后,在 Execute 模式下操作 GoodBuddy 隔离浏览器。',
|
||||
'启用“内置浏览器”后,在 Execute 模式下操作 GoodBuddy 隔离浏览器。',
|
||||
tools: builtinModelTools.filter((tool) => tool.group === 'browser')
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user