mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-17 05:45:51 +00:00
fix: 内存优化 — 预测性 compact 阈值、增量 lookups orphaned 修复、deferred slice 引用优化
- P0: REPL.tsx 用 useMemo 包裹 deferred messages slice,避免每次渲染创建新数组引用导致不必要的后台重渲染 - P1: 预测性 compact 阈值改用 effectiveContextWindow - growth,消除与 autocompact buffer 的双重预留;TOOL_RESULT_GROWTH_ESTIMATE 从 20K 降至 15K - P2: 增量 lookups 增加 lastAssistantMsgId 一致性检查和 orphaned server_tool_use/mcp_tool_use 扫描,防止 UI 永久 loading - P3: reactiveCompact 类型断言改为直接使用 'compact' 字面量 - docs: CLAUDE.md 统一使用 precheck 替代分散的 typecheck/lint/test 命令 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,7 @@ import type { Tools } from '../Tool.js';
|
||||
import { findToolByName } from '../Tool.js';
|
||||
import type { AgentDefinitionsResult } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js';
|
||||
import type {
|
||||
AssistantMessage,
|
||||
Message as MessageType,
|
||||
NormalizedMessage,
|
||||
ProgressMessage as ProgressMessageType,
|
||||
@@ -36,6 +37,7 @@ import {
|
||||
buildMessageLookups,
|
||||
computeMessageStructureKey,
|
||||
type MessageLookups,
|
||||
updateMessageLookupsIncremental,
|
||||
createAssistantMessage,
|
||||
deriveUUID,
|
||||
getMessagesAfterCompactBoundary,
|
||||
@@ -516,7 +518,13 @@ const MessagesImpl = ({
|
||||
// message content changed during streaming (text/thinking deltas). The key
|
||||
// captures only structural info (types, IDs), so content-only deltas skip
|
||||
// the rebuild entirely.
|
||||
const lookupsCacheRef = useRef<{ key: string; lookups: MessageLookups } | null>(null);
|
||||
const lookupsCacheRef = useRef<{
|
||||
key: string;
|
||||
lookups: MessageLookups;
|
||||
normalizedCount: number;
|
||||
messageCount: number;
|
||||
lastAssistantMsgId: string | undefined;
|
||||
} | null>(null);
|
||||
|
||||
// Expensive message transforms — filter, reorder, group, collapse, lookups.
|
||||
// All O(n) over 27k messages. Split from the renderRange slice so scrolling
|
||||
@@ -587,12 +595,57 @@ const MessagesImpl = ({
|
||||
);
|
||||
|
||||
const lookupsKey = computeMessageStructureKey(normalizedMessages, messagesToShow as MessageType[]);
|
||||
const currentLastAssistantMsgId = (() => {
|
||||
const lastMsg = (messagesToShow as MessageType[]).at(-1);
|
||||
return lastMsg?.type === 'assistant' ? (lastMsg as AssistantMessage).message?.id : undefined;
|
||||
})();
|
||||
let lookups: MessageLookups;
|
||||
if (lookupsCacheRef.current && lookupsCacheRef.current.key === lookupsKey) {
|
||||
lookups = lookupsCacheRef.current.lookups;
|
||||
} else if (
|
||||
lookupsCacheRef.current &&
|
||||
normalizedMessages.length >= lookupsCacheRef.current.normalizedCount &&
|
||||
(messagesToShow as MessageType[]).length >= lookupsCacheRef.current.messageCount &&
|
||||
// If lastAssistantMsgId changed, previous "in-progress" assistant may
|
||||
// now be orphaned — force a full rebuild to pick up the new status.
|
||||
lookupsCacheRef.current.lastAssistantMsgId === currentLastAssistantMsgId
|
||||
) {
|
||||
// Try incremental update when only new messages were appended
|
||||
const updated = updateMessageLookupsIncremental(
|
||||
lookupsCacheRef.current.lookups,
|
||||
lookupsCacheRef.current.normalizedCount,
|
||||
lookupsCacheRef.current.messageCount,
|
||||
normalizedMessages,
|
||||
messagesToShow as MessageType[],
|
||||
);
|
||||
if (updated) {
|
||||
lookups = updated;
|
||||
lookupsCacheRef.current = {
|
||||
key: lookupsKey,
|
||||
lookups,
|
||||
normalizedCount: normalizedMessages.length,
|
||||
messageCount: (messagesToShow as MessageType[]).length,
|
||||
lastAssistantMsgId: currentLastAssistantMsgId,
|
||||
};
|
||||
} else {
|
||||
lookups = buildMessageLookups(normalizedMessages, messagesToShow as MessageType[]);
|
||||
lookupsCacheRef.current = {
|
||||
key: lookupsKey,
|
||||
lookups,
|
||||
normalizedCount: normalizedMessages.length,
|
||||
messageCount: (messagesToShow as MessageType[]).length,
|
||||
lastAssistantMsgId: currentLastAssistantMsgId,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
lookups = buildMessageLookups(normalizedMessages, messagesToShow as MessageType[]);
|
||||
lookupsCacheRef.current = { key: lookupsKey, lookups };
|
||||
lookupsCacheRef.current = {
|
||||
key: lookupsKey,
|
||||
lookups,
|
||||
normalizedCount: normalizedMessages.length,
|
||||
messageCount: (messagesToShow as MessageType[]).length,
|
||||
lastAssistantMsgId: currentLastAssistantMsgId,
|
||||
};
|
||||
}
|
||||
|
||||
const hiddenMessageCount = messagesToShowNotTruncated.length - MAX_MESSAGES_TO_SHOW_IN_TRANSCRIPT_MODE;
|
||||
|
||||
Reference in New Issue
Block a user