mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-15 12:55:51 +00:00
feat: Remote Control 条件工具注入 — PushNotification/SendUserFile/Brief 仅 bridge 启用时可用
- PushNotificationTool、SendUserFileTool 添加 isEnabled() 使用 isBridgeEnabled() - BriefTool 的 isEnabled() 从 isBriefEnabled() 改为 isBridgeEnabled() - ExecuteTool 添加 isEnabled() 兜底检查,不可用时返回友好错误 - useReplBridge bridge 首次连接时插入 system 消息通知模型新工具可用 - 移除 toolSearch 中 firstParty base URL 白名单检测,默认启用 tool search Co-Authored-By: glm-5.1[1m] <zai-org@claude-code-best.win>
This commit is contained in:
@@ -8,6 +8,7 @@ import { buildTool, type ToolDef } from 'src/Tool.js'
|
||||
import { isEnvTruthy } from 'src/utils/envUtils.js'
|
||||
import { lazySchema } from 'src/utils/lazySchema.js'
|
||||
import { plural } from 'src/utils/stringUtils.js'
|
||||
import { isBridgeEnabled } from 'src/bridge/bridgeEnabled.js'
|
||||
import { resolveAttachments, validateAttachmentPaths } from './attachments.js'
|
||||
import {
|
||||
BRIEF_TOOL_NAME,
|
||||
@@ -149,7 +150,7 @@ export const BriefTool = buildTool({
|
||||
return outputSchema()
|
||||
},
|
||||
isEnabled() {
|
||||
return isBriefEnabled()
|
||||
return isBridgeEnabled()
|
||||
},
|
||||
isConcurrencySafe() {
|
||||
return true
|
||||
|
||||
@@ -74,6 +74,21 @@ export const ExecuteTool = buildTool({
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the target tool is currently enabled
|
||||
if (!targetTool.isEnabled()) {
|
||||
return {
|
||||
data: {
|
||||
result: null,
|
||||
tool_name: input.tool_name,
|
||||
},
|
||||
newMessages: [
|
||||
createUserMessage({
|
||||
content: `工具 "${input.tool_name}" 当前不可用:Remote Control 未连接。`,
|
||||
}),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
// Check permissions on the target tool
|
||||
const permResult = await targetTool.checkPermissions?.(
|
||||
input.params as Record<string, unknown>,
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { ToolResultBlockParam } from 'src/Tool.js'
|
||||
import { buildTool } from 'src/Tool.js'
|
||||
import { lazySchema } from 'src/utils/lazySchema.js'
|
||||
import { logForDebugging } from 'src/utils/debug.js'
|
||||
import { isBridgeEnabled } from 'src/bridge/bridgeEnabled.js'
|
||||
|
||||
const PUSH_NOTIFICATION_TOOL_NAME = 'PushNotification'
|
||||
|
||||
@@ -48,6 +49,9 @@ Use this when:
|
||||
Requires Remote Control to be configured. Respects user notification settings (taskCompleteNotifEnabled, inputNeededNotifEnabled, agentPushNotifEnabled).`
|
||||
},
|
||||
|
||||
isEnabled() {
|
||||
return isBridgeEnabled()
|
||||
},
|
||||
isConcurrencySafe() {
|
||||
return true
|
||||
},
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { ToolResultBlockParam } from 'src/Tool.js'
|
||||
import { buildTool } from 'src/Tool.js'
|
||||
import { lazySchema } from 'src/utils/lazySchema.js'
|
||||
import { SEND_USER_FILE_TOOL_NAME } from './prompt.js'
|
||||
import { isBridgeEnabled } from 'src/bridge/bridgeEnabled.js'
|
||||
|
||||
const inputSchema = lazySchema(() =>
|
||||
z.strictObject({
|
||||
@@ -42,6 +43,9 @@ Guidelines:
|
||||
- Large files may take time to transfer`
|
||||
},
|
||||
|
||||
isEnabled() {
|
||||
return isBridgeEnabled()
|
||||
},
|
||||
isConcurrencySafe() {
|
||||
return true
|
||||
},
|
||||
|
||||
@@ -302,6 +302,7 @@ export function useReplBridge(
|
||||
});
|
||||
break;
|
||||
case 'connected': {
|
||||
const wasSessionActive = store.getState().replBridgeSessionActive;
|
||||
setAppState(prev => {
|
||||
if (prev.replBridgeSessionActive) return prev;
|
||||
return {
|
||||
@@ -312,6 +313,16 @@ export function useReplBridge(
|
||||
replBridgeError: undefined,
|
||||
};
|
||||
});
|
||||
// Notify model about newly available bridge-dependent tools
|
||||
if (!wasSessionActive) {
|
||||
setMessages(prev => [
|
||||
...prev,
|
||||
createSystemMessage(
|
||||
'Remote Control 已连接。现在可以使用 PushNotification、SendUserFile、Brief 工具,请使用 ToolSearch 搜索发现。',
|
||||
'info',
|
||||
),
|
||||
]);
|
||||
}
|
||||
// Send system/init so remote clients (web/iOS/Android) get
|
||||
// session metadata. REPL uses query() directly — never hits
|
||||
// QueryEngine's SDKMessage layer — so this is the only path
|
||||
|
||||
@@ -34,10 +34,6 @@ import { getMergedBetas } from './betas.js'
|
||||
import { getContextWindowForModel } from './context.js'
|
||||
import { logForDebugging } from './debug.js'
|
||||
import { isEnvDefinedFalsy, isEnvTruthy } from './envUtils.js'
|
||||
import {
|
||||
getAPIProvider,
|
||||
isFirstPartyAnthropicBaseUrl,
|
||||
} from './model/providers.js'
|
||||
import { jsonStringify } from './slowOperations.js'
|
||||
import { zodToJsonSchema } from './zodToJsonSchema.js'
|
||||
|
||||
@@ -279,36 +275,10 @@ export function isToolSearchEnabledOptimistic(): boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
// tool_reference is a beta content type that third-party API gateways
|
||||
// (ANTHROPIC_BASE_URL proxies) typically don't support. When the provider
|
||||
// is 'firstParty' but the base URL points elsewhere, the proxy will reject
|
||||
// tool_reference blocks with a 400. Vertex/Bedrock/Foundry are unaffected —
|
||||
// they have their own endpoints and beta headers.
|
||||
// https://github.com/anthropics/claude-code/issues/30912
|
||||
//
|
||||
// HOWEVER: some proxies DO support tool_reference (LiteLLM passthrough,
|
||||
// Cloudflare AI Gateway, corp gateways that forward beta headers). The
|
||||
// blanket disable breaks defer_loading for those users — all MCP tools
|
||||
// loaded into main context instead of on-demand (gh-31936 / CC-457,
|
||||
// likely the real cause of CC-330 "v2.1.70 defer_loading regression").
|
||||
// This gate only applies when ENABLE_TOOL_SEARCH is unset/empty (default
|
||||
// behavior). Setting any non-empty value — 'true', 'auto', 'auto:N' —
|
||||
// means the user is explicitly configuring tool search and asserts their
|
||||
// setup supports it. The falsy check (rather than === undefined) aligns
|
||||
// with getToolSearchMode(), which also treats "" as unset.
|
||||
if (
|
||||
!process.env.ENABLE_TOOL_SEARCH &&
|
||||
getAPIProvider() === 'firstParty' &&
|
||||
!isFirstPartyAnthropicBaseUrl()
|
||||
) {
|
||||
if (!loggedOptimistic) {
|
||||
loggedOptimistic = true
|
||||
logForDebugging(
|
||||
`[ToolSearch:optimistic] disabled: ANTHROPIC_BASE_URL=${process.env.ANTHROPIC_BASE_URL} is not a first-party Anthropic host. Set ENABLE_TOOL_SEARCH=true (or auto / auto:N) if your proxy forwards tool_reference blocks.`,
|
||||
)
|
||||
}
|
||||
return false
|
||||
}
|
||||
// 此项目为逆向工程版本,用户均使用第三方代理(如 open.bigmodel.cn),
|
||||
// 原版的 firstParty base URL 白名单检测会导致 tool search 默认禁用。
|
||||
// 移除该检测,默认启用 tool search。
|
||||
// 用户仍可通过 ENABLE_TOOL_SEARCH=false 显式禁用。
|
||||
|
||||
if (!loggedOptimistic) {
|
||||
loggedOptimistic = true
|
||||
|
||||
Reference in New Issue
Block a user