mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
113 lines
3.1 KiB
Go
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)
|
|
}
|
|
}
|