mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
fix(agent): findSafeBoundary returns 0 for single-Turn history
When the entire history is a single Turn (one user message followed by tool calls and responses, no subsequent user message), the only Turn boundary is at index 0. Previously the fallback returned targetIndex, which could land on a tool or assistant message — splitting the Turn. Return 0 instead, so callers (forceCompression, summarizeSession) see mid <= 0 and skip compression rather than cutting inside the Turn.
This commit is contained in:
@@ -79,7 +79,11 @@ func findSafeBoundary(history []providers.Message, targetIndex int) int {
|
||||
}
|
||||
}
|
||||
|
||||
return targetIndex
|
||||
// No Turn boundary after targetIndex either. The only boundary is at
|
||||
// index 0, meaning the entire history is a single Turn. Return 0 to
|
||||
// signal that safe compression is not possible — callers check for
|
||||
// mid <= 0 and skip compression in that case.
|
||||
return 0
|
||||
}
|
||||
|
||||
// estimateMessageTokens estimates the token count for a single message,
|
||||
|
||||
@@ -346,6 +346,23 @@ func TestFindSafeBoundary(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindSafeBoundary_SingleTurnReturnsZero(t *testing.T) {
|
||||
// A single Turn with no subsequent user message. The only Turn boundary
|
||||
// is at index 0; cutting anywhere else would split the Turn's tool
|
||||
// sequence. findSafeBoundary must return 0 so callers skip compression.
|
||||
history := []providers.Message{
|
||||
msgUser("do everything"), // 0 ← only Turn boundary
|
||||
msgAssistantTC("tc1"), // 1
|
||||
msgTool("tc1", "result"), // 2
|
||||
msgAssistant("all done"), // 3
|
||||
}
|
||||
|
||||
got := findSafeBoundary(history, 2)
|
||||
if got != 0 {
|
||||
t.Errorf("findSafeBoundary(single_turn, 2) = %d, want 0 (cannot split single Turn)", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindSafeBoundary_BackwardScanSkipsToolSequence(t *testing.T) {
|
||||
// A long tool-call chain: user → assistant+TC → tool → tool → ... → assistant → user
|
||||
// Target is inside the chain; boundary should skip the entire chain backward.
|
||||
|
||||
Reference in New Issue
Block a user