fix(agent): include SystemParts in token estimation and add reasoning guards

This commit is contained in:
Badgerbees 2026-03-26 00:31:22 +07:00
parent dd54601f2d
commit 93f391a6bf
2 changed files with 25 additions and 4 deletions

View file

@ -91,11 +91,12 @@ func findSafeBoundary(history []providers.Message, targetIndex int) int {
// metadata, and Media items. Uses a heuristic of 2.5 characters per token. // metadata, and Media items. Uses a heuristic of 2.5 characters per token.
func estimateMessageTokens(msg providers.Message) int { func estimateMessageTokens(msg providers.Message) int {
chars := utf8.RuneCountInString(msg.Content) chars := utf8.RuneCountInString(msg.Content)
chars += utf8.RuneCountInString(msg.ReasoningContent)
// ReasoningContent (extended thinking / chain-of-thought) can be // SystemParts are structured system blocks that can be substantial
// substantial and is stored in session history via AddFullMessage. // when using instruction-heavy agents or KV-cache-aware adapters.
if msg.ReasoningContent != "" { for _, part := range msg.SystemParts {
chars += utf8.RuneCountInString(msg.ReasoningContent) chars += utf8.RuneCountInString(part.Text)
} }
for _, tc := range msg.ToolCalls { for _, tc := range msg.ToolCalls {

View file

@ -529,6 +529,26 @@ func TestEstimateMessageTokens_MediaItems(t *testing.T) {
} }
} }
func TestEstimateMessageTokens_SystemParts(t *testing.T) {
plain := providers.Message{Role: "system", Content: "instructions"}
withParts := providers.Message{
Role: "system",
Content: "instructions",
SystemParts: []providers.ContentBlock{
{Type: "text", Text: "some more system context"},
{Type: "text", Text: "even more cached blocks"},
},
}
plainTokens := estimateMessageTokens(plain)
partsTokens := estimateMessageTokens(withParts)
if partsTokens <= plainTokens {
t.Errorf("system message with SystemParts (%d) should exceed plain message (%d)",
partsTokens, plainTokens)
}
}
// --- estimateToolDefsTokens tests --- // --- estimateToolDefsTokens tests ---
func TestEstimateToolDefsTokens(t *testing.T) { func TestEstimateToolDefsTokens(t *testing.T) {