Files
picoclaw/pkg/agent/turn_state_test.go
T

113 lines
3.1 KiB
Go

package agent
import (
"strings"
"testing"
"github.com/sipeed/picoclaw/pkg/providers"
)
func TestMatchingTurnMessageTail_IgnoresInternalRuntimeFields(t *testing.T) {
history := []providers.Message{
{Role: "user", Content: "question"},
{
Role: "assistant",
ToolCalls: []providers.ToolCall{
{
ID: "call_1",
Type: "function",
Function: &providers.FunctionCall{
Name: "read_file",
Arguments: `{"path":"/tmp/test"}`,
},
},
},
},
}
persisted := []providers.Message{
userPromptMessage("question", nil),
{
Role: "assistant",
ToolCalls: []providers.ToolCall{
{
ID: "call_1",
Type: "function",
Name: "read_file",
Arguments: map[string]any{"path": "/tmp/test"},
ThoughtSignature: "internal-signature",
Function: &providers.FunctionCall{
Name: "read_file",
Arguments: `{"path":"/tmp/test"}`,
ThoughtSignature: "internal-signature",
},
},
},
},
}
if got := matchingTurnMessageTail(history, persisted); got != 2 {
t.Fatalf("matchingTurnMessageTail() = %d, want 2", got)
}
}
func TestSplitHistoryForActiveTurn_ProtectsPersistedTail(t *testing.T) {
history := []providers.Message{
{Role: "user", Content: "old question"},
{Role: "assistant", Content: "old answer"},
{Role: "user", Content: "current question"},
{Role: "tool", Content: "tool output", ToolCallID: "call_1"},
}
persisted := []providers.Message{
userPromptMessage("current question", nil),
{Role: "tool", Content: "tool output", ToolCallID: "call_1"},
}
stable, protected := splitHistoryForActiveTurn(history, persisted)
if len(stable) != 2 {
t.Fatalf("stable history len = %d, want 2", len(stable))
}
if len(protected) != 2 {
t.Fatalf("protected tail len = %d, want 2", len(protected))
}
if protected[0].Content != "current question" {
t.Fatalf("protected[0].Content = %q, want current question", protected[0].Content)
}
}
func TestTrimHistoryToFitContextWindow_WithProtectedTurnTailKeepsActiveTurn(t *testing.T) {
current := strings.Repeat("current turn ", 80)
history := []providers.Message{
{Role: "user", Content: strings.Repeat("old turn ", 60)},
{Role: "assistant", Content: strings.Repeat("old reply ", 60)},
{Role: "user", Content: current},
}
stable, protected := splitHistoryForActiveTurn(history, []providers.Message{
userPromptMessage(current, nil),
})
trimmedStable, messages, fit := trimHistoryToFitContextWindow(
stable,
func(trimmedHistory []providers.Message) []providers.Message {
return append(append([]providers.Message(nil), trimmedHistory...), protected...)
},
120,
nil,
0,
)
if fit {
t.Fatal("expected protected active turn alone to remain over budget")
}
if len(trimmedStable) != 0 {
t.Fatalf("trimmed stable history len = %d, want 0", len(trimmedStable))
}
if len(messages) != 1 {
t.Fatalf("messages len = %d, want 1 protected active-turn message", len(messages))
}
if messages[0].Content != current {
t.Fatalf("messages[0].Content = %q, want protected current turn", messages[0].Content)
}
}