mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-16 13:25:51 +00:00
Compare commits
1 Commits
codex/memo
...
v1.10.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5c3ee5b5d |
@@ -10,6 +10,10 @@ import {
|
||||
getOriginalCwd,
|
||||
getSessionId,
|
||||
regenerateSessionId,
|
||||
resetCostState,
|
||||
setLastAPIRequest,
|
||||
setLastAPIRequestMessages,
|
||||
setLastClassifierRequests,
|
||||
} from '../../bootstrap/state.js'
|
||||
import type { SDKStatusMessage } from '../../entrypoints/sdk/coreTypes.js'
|
||||
import {
|
||||
@@ -144,6 +148,14 @@ export async function clearConversation({
|
||||
// tracking) is retained so those agents keep functioning.
|
||||
clearSessionCaches(preservedAgentIds)
|
||||
|
||||
// Clear large STATE-held data that outlives the message array.
|
||||
// lastAPIRequestMessages can hold the full post-compaction conversation
|
||||
// (hundreds of KB–MB) for /share; resetCostState clears modelUsage.
|
||||
setLastAPIRequest(null)
|
||||
setLastAPIRequestMessages(null)
|
||||
setLastClassifierRequests(null)
|
||||
resetCostState()
|
||||
|
||||
setCwd(getOriginalCwd())
|
||||
readFileState.clear()
|
||||
discoveredSkillNames?.clear()
|
||||
|
||||
@@ -3051,12 +3051,22 @@ export function REPL({
|
||||
// are O(n) per render, so drop everything before the previous
|
||||
// boundary to keep n bounded across multi-day sessions.
|
||||
if (isFullscreenEnvEnabled()) {
|
||||
setMessages(old => [
|
||||
...getMessagesAfterCompactBoundary(old, {
|
||||
setMessages(old => {
|
||||
const postBoundary = getMessagesAfterCompactBoundary(old, {
|
||||
includeSnipped: true,
|
||||
}),
|
||||
newMessage,
|
||||
]);
|
||||
})
|
||||
// Hard cap: keep at most 500 messages in fullscreen scrollback
|
||||
// to prevent unbounded memory growth in multi-day sessions.
|
||||
// normalizeMessages/applyGrouping are O(n), and Ink fiber
|
||||
// trees cost ~250KB RSS per message. Without this cap,
|
||||
// scrollback after several compactions can reach thousands
|
||||
// of messages (observed: 13k+, 1GB+ heap).
|
||||
const MAX_FULLSCREEN_SCROLLBACK = 500
|
||||
const kept = postBoundary.length > MAX_FULLSCREEN_SCROLLBACK
|
||||
? postBoundary.slice(-MAX_FULLSCREEN_SCROLLBACK)
|
||||
: postBoundary
|
||||
return [...kept, newMessage]
|
||||
});
|
||||
} else {
|
||||
setMessages(() => [newMessage]);
|
||||
}
|
||||
@@ -3082,17 +3092,23 @@ export function REPL({
|
||||
// history). Replacing those leaves the AgentTool UI stuck at
|
||||
// "Initializing…" because it renders the full progress trail.
|
||||
setMessages(oldMessages => {
|
||||
const last = oldMessages.at(-1);
|
||||
const lastData = last?.data as Record<string, unknown> | undefined;
|
||||
const newData = newMessage.data as Record<string, unknown>;
|
||||
if (
|
||||
last?.type === 'progress' &&
|
||||
last.parentToolUseID === newMessage.parentToolUseID &&
|
||||
lastData?.type === newData.type
|
||||
) {
|
||||
const copy = oldMessages.slice();
|
||||
copy[copy.length - 1] = newMessage;
|
||||
return copy;
|
||||
// Scan backwards to find the last ephemeral progress with matching
|
||||
// parentToolUseID and type. Previously only checked the last message,
|
||||
// so interleaved non-ephemeral messages caused duplicate progress
|
||||
// entries to accumulate (observed 13k+ entries in sleep-heavy sessions).
|
||||
for (let i = oldMessages.length - 1; i >= 0; i--) {
|
||||
const m = oldMessages[i]!
|
||||
if (m.type !== 'progress') break
|
||||
const mData = m.data as Record<string, unknown> | undefined
|
||||
if (
|
||||
m.parentToolUseID === newMessage.parentToolUseID &&
|
||||
mData?.type === newData.type
|
||||
) {
|
||||
const copy = oldMessages.slice();
|
||||
copy[i] = newMessage;
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
return [...oldMessages, newMessage];
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user