Files
claude-code/src/services/compact/apiMicrocompact.ts
claude-code-best 2fb1c9dcd8 feat: 工具层及 mcp 大重构 (#252)
* feat: 第一版大重构

* fix: 修复类型问题

* chore: 更新版本到 1.3.2

* Add brave as alternative WebSearchTool

* fix: 修正顺序

* fix: 修复对穷鬼模式的 auto dream 和 session memory 越过

* feat: 穷鬼模式去除 session-summary

* feat: 创建 builtin-tools 包,搬运所有工具实现

将 src/tools/ 下的全部 60 个工具目录迁移至 packages/builtin-tools/src/tools/,
内部导入路径已更新为 src/ alias 模式。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: 更新 src/ 中所有工具引用至 builtin-tools 包,删除 src/tools/

- src/tools.ts 及 178 个 src/ 文件的 import 路径从 ./tools/ 改为 builtin-tools/tools/
- 删除 src/tools/ 整个目录(已迁移至 packages/builtin-tools/)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: 添加 builtin-tools 路径别名至 tsconfig,更新 bun.lock

- tsconfig.json 新增 builtin-tools/* 和 builtin-tools 路径映射
- 新增 packages/builtin-tools/src 至 include

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: 为 builtin-tools、mcp-client、agent-tools 添加 @claude-code-best 作用域前缀

所有包名及 import 路径统一添加 @claude-code-best/ 前缀:
- builtin-tools → @claude-code-best/builtin-tools
- mcp-client → @claude-code-best/mcp-client
- agent-tools → @claude-code-best/agent-tools

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: 修复 node 环境没有 bun 的问题

---------

Co-authored-by: Eric-Guo <eric.guocz@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 09:52:05 +08:00

154 lines
5.1 KiB
TypeScript

import { FILE_EDIT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/FileEditTool/constants.js'
import { FILE_READ_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/FileReadTool/prompt.js'
import { FILE_WRITE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/FileWriteTool/prompt.js'
import { GLOB_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/GlobTool/prompt.js'
import { GREP_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/GrepTool/prompt.js'
import { NOTEBOOK_EDIT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/NotebookEditTool/constants.js'
import { WEB_FETCH_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/WebFetchTool/prompt.js'
import { WEB_SEARCH_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/WebSearchTool/prompt.js'
import { SHELL_TOOL_NAMES } from 'src/utils/shell/shellToolUtils.js'
import { isEnvTruthy } from '../../utils/envUtils.js'
// docs: https://docs.google.com/document/d/1oCT4evvWTh3P6z-kcfNQwWTCxAhkoFndSaNS9Gm40uw/edit?tab=t.0
// Default values for context management strategies
// Match client-side microcompact token values
const DEFAULT_MAX_INPUT_TOKENS = 180_000 // Typical warning threshold
const DEFAULT_TARGET_INPUT_TOKENS = 40_000 // Keep last 40k tokens like client-side
const TOOLS_CLEARABLE_RESULTS = [
...SHELL_TOOL_NAMES,
GLOB_TOOL_NAME,
GREP_TOOL_NAME,
FILE_READ_TOOL_NAME,
WEB_FETCH_TOOL_NAME,
WEB_SEARCH_TOOL_NAME,
]
const TOOLS_CLEARABLE_USES = [
FILE_EDIT_TOOL_NAME,
FILE_WRITE_TOOL_NAME,
NOTEBOOK_EDIT_TOOL_NAME,
]
// Context management strategy types matching API documentation
export type ContextEditStrategy =
| {
type: 'clear_tool_uses_20250919'
trigger?: {
type: 'input_tokens'
value: number
}
keep?: {
type: 'tool_uses'
value: number
}
clear_tool_inputs?: boolean | string[]
exclude_tools?: string[]
clear_at_least?: {
type: 'input_tokens'
value: number
}
}
| {
type: 'clear_thinking_20251015'
keep: { type: 'thinking_turns'; value: number } | 'all'
}
// Context management configuration wrapper
export type ContextManagementConfig = {
edits: ContextEditStrategy[]
}
// API-based microcompact implementation that uses native context management
export function getAPIContextManagement(options?: {
hasThinking?: boolean
isRedactThinkingActive?: boolean
clearAllThinking?: boolean
}): ContextManagementConfig | undefined {
const {
hasThinking = false,
isRedactThinkingActive = false,
clearAllThinking = false,
} = options ?? {}
const strategies: ContextEditStrategy[] = []
// Preserve thinking blocks in previous assistant turns. Skip when
// redact-thinking is active — redacted blocks have no model-visible content.
// When clearAllThinking is set (>1h idle = cache miss), keep only the last
// thinking turn — the API schema requires value >= 1, and omitting the edit
// falls back to the model-policy default (often "all"), which wouldn't clear.
if (hasThinking && !isRedactThinkingActive) {
strategies.push({
type: 'clear_thinking_20251015',
keep: clearAllThinking ? { type: 'thinking_turns', value: 1 } : 'all',
})
}
// Tool clearing strategies are ant-only
if (process.env.USER_TYPE !== 'ant') {
return strategies.length > 0 ? { edits: strategies } : undefined
}
const useClearToolResults = isEnvTruthy(
process.env.USE_API_CLEAR_TOOL_RESULTS,
)
const useClearToolUses = isEnvTruthy(process.env.USE_API_CLEAR_TOOL_USES)
// If no tool clearing strategy is enabled, return early
if (!useClearToolResults && !useClearToolUses) {
return strategies.length > 0 ? { edits: strategies } : undefined
}
if (useClearToolResults) {
const triggerThreshold = process.env.API_MAX_INPUT_TOKENS
? parseInt(process.env.API_MAX_INPUT_TOKENS)
: DEFAULT_MAX_INPUT_TOKENS
const keepTarget = process.env.API_TARGET_INPUT_TOKENS
? parseInt(process.env.API_TARGET_INPUT_TOKENS)
: DEFAULT_TARGET_INPUT_TOKENS
const strategy: ContextEditStrategy = {
type: 'clear_tool_uses_20250919',
trigger: {
type: 'input_tokens',
value: triggerThreshold,
},
clear_at_least: {
type: 'input_tokens',
value: triggerThreshold - keepTarget,
},
clear_tool_inputs: TOOLS_CLEARABLE_RESULTS,
}
strategies.push(strategy)
}
if (useClearToolUses) {
const triggerThreshold = process.env.API_MAX_INPUT_TOKENS
? parseInt(process.env.API_MAX_INPUT_TOKENS)
: DEFAULT_MAX_INPUT_TOKENS
const keepTarget = process.env.API_TARGET_INPUT_TOKENS
? parseInt(process.env.API_TARGET_INPUT_TOKENS)
: DEFAULT_TARGET_INPUT_TOKENS
const strategy: ContextEditStrategy = {
type: 'clear_tool_uses_20250919',
trigger: {
type: 'input_tokens',
value: triggerThreshold,
},
clear_at_least: {
type: 'input_tokens',
value: triggerThreshold - keepTarget,
},
exclude_tools: TOOLS_CLEARABLE_USES,
}
strategies.push(strategy)
}
return strategies.length > 0 ? { edits: strategies } : undefined
}