Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions agent/compaction/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,26 @@ func computeContentByteCount(content message.Content) int {
return stringByteCount(typed.Message) + stringByteCount(typed.ErrorCode) + stringByteCount(typed.Details)
case *message.HostedFileContent:
return stringByteCount(typed.FileID) + stringByteCount(typed.MediaType) + stringByteCount(typed.Name)
case *message.MCPServerToolCallContent:
return stringByteCount(typed.CallID) + stringByteCount(typed.Name) + stringByteCount(typed.ServerName) + stringByteCount(typed.Arguments)
case *message.MCPServerToolResultContent:
total := stringByteCount(typed.CallID) + stringByteCount(typed.Name) + stringByteCount(typed.ServerName) + stringByteCount(typed.Error)
for _, output := range typed.Outputs {
total += computeContentByteCount(output)
}
return total
case *message.CodeInterpreterToolCallContent:
total := stringByteCount(typed.CallID)
for _, input := range typed.Inputs {
total += computeContentByteCount(input)
}
Comment on lines +410 to +414
return total
case *message.CodeInterpreterToolResultContent:
total := stringByteCount(typed.CallID)
for _, output := range typed.Outputs {
total += computeContentByteCount(output)
}
return total
default:
return 0
}
Expand Down
29 changes: 29 additions & 0 deletions agent/compaction/index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package compaction_test
import (
"context"
"slices"
"strings"
"testing"

"github.com/microsoft/agent-framework-go/agent/compaction"
Expand Down Expand Up @@ -370,3 +371,31 @@ func TestMessageIndex_Update_RepeatedContentDoesNotDropMessages(t *testing.T) {
t.Fatalf("after turn 2 (repeated \"continue\"): got %v, want %v — appended turns were dropped", got, want)
}
}

func TestMessageIndex_CountsHostedToolResultBytes(t *testing.T) {
big := strings.Repeat("x", 10000)
// A hosted tool result carrying 10k bytes of Outputs must be byte-accounted
// like the equivalent FunctionResultContent, so token/byte-based compaction
// triggers see the payload that most needs compacting.
fnMsg := &message.Message{Role: message.RoleTool, Contents: message.Contents{
&message.FunctionResultContent{CallID: "c1", Result: big},
}}
mcpMsg := &message.Message{Role: message.RoleTool, Contents: message.Contents{
&message.MCPServerToolResultContent{CallID: "c1", Outputs: message.Contents{&message.TextContent{Text: big}}},
}}
ciMsg := &message.Message{Role: message.RoleTool, Contents: message.Contents{
&message.CodeInterpreterToolResultContent{CallID: "c1", Outputs: message.Contents{&message.TextContent{Text: big}}},
}}
prefix := textMessage(message.RoleUser, "hi")

fnBytes := compaction.CreateMessageIndex([]*message.Message{prefix, fnMsg}, nil).TotalByteCount()
mcpBytes := compaction.CreateMessageIndex([]*message.Message{prefix, mcpMsg}, nil).TotalByteCount()
ciBytes := compaction.CreateMessageIndex([]*message.Message{prefix, ciMsg}, nil).TotalByteCount()

if mcpBytes < fnBytes {
t.Errorf("MCP tool-result bytes = %d, want >= FunctionResult bytes %d (Outputs undercounted)", mcpBytes, fnBytes)
}
if ciBytes < fnBytes {
t.Errorf("code-interpreter result bytes = %d, want >= FunctionResult bytes %d (Outputs undercounted)", ciBytes, fnBytes)
}
}
Comment on lines +377 to +401
Loading