What happened?
While investigating #4815, we verified that microcompactHistory() only runs inside the UserQuery / Cron branch in packages/core/src/core/client.ts.
/goal uses Stop-hook continuations that recursively call sendMessageStream() with SendMessageType.Hook. Those Hook turns bypass the microcompaction branch, so a long-running /goal loop can keep accumulating old tool result contents until a later UserQuery or Cron turn happens.
Relevant flow:
microcompactHistory() runs only when messageType === SendMessageType.UserQuery || messageType === SendMessageType.Cron.
- Stop-hook continuation calls
sendMessageStream(..., { type: SendMessageType.Hook, ... }).
- Current memory-pressure cleanup only evicts/clears file cache and optional GC; it does not compact chat history.
Expected behavior
Hook continuations that can drive long-running autonomous work, especially /goal, should still give old tool results a cleanup point without waiting for a future user/cron turn.
Suggested fix direction
Keep the fix narrow: reuse the existing microcompaction logic for SendMessageType.Hook turns, while continuing to avoid ToolResult turns so functionCall/functionResponse pairing is not disturbed.
Add a focused regression test that builds old read_file tool results, sets lastApiCompletionTimestamp beyond the idle threshold, runs a Hook turn, and verifies history is compacted.
Related
Follow-up from #4815.
What happened?
While investigating #4815, we verified that
microcompactHistory()only runs inside theUserQuery/Cronbranch inpackages/core/src/core/client.ts./goaluses Stop-hook continuations that recursively callsendMessageStream()withSendMessageType.Hook. Those Hook turns bypass the microcompaction branch, so a long-running/goalloop can keep accumulating old tool result contents until a laterUserQueryorCronturn happens.Relevant flow:
microcompactHistory()runs only whenmessageType === SendMessageType.UserQuery || messageType === SendMessageType.Cron.sendMessageStream(..., { type: SendMessageType.Hook, ... }).Expected behavior
Hook continuations that can drive long-running autonomous work, especially
/goal, should still give old tool results a cleanup point without waiting for a future user/cron turn.Suggested fix direction
Keep the fix narrow: reuse the existing microcompaction logic for
SendMessageType.Hookturns, while continuing to avoidToolResultturns so functionCall/functionResponse pairing is not disturbed.Add a focused regression test that builds old
read_filetool results, setslastApiCompletionTimestampbeyond the idle threshold, runs a Hook turn, and verifies history is compacted.Related
Follow-up from #4815.