TestMessageTokensCountsToolCallArguments pins ToolCall.Arguments accounting in Message.Tokens: it feeds the budget on every tool-using turn, yet no other test populates Arguments. Asserts the delta so the +8 per-message overhead can't mask a dropped Arguments loop.
(t *testing.T)
| 43 | // other test populates Arguments. Asserts the delta so the +8 per-message |
| 44 | // overhead can't mask a dropped Arguments loop. |
| 45 | func TestMessageTokensCountsToolCallArguments(t *testing.T) { |
| 46 | base := Message{Role: RoleAssistant, ToolCalls: []ToolCall{{Name: "bash"}}}.Tokens() |
| 47 | withArgs := Message{Role: RoleAssistant, ToolCalls: []ToolCall{ |
| 48 | {Name: "bash", Arguments: map[string]any{"cmd": "echo hello world"}}, |
| 49 | }}.Tokens() |
| 50 | // args add Tokens("cmd")=1 + Tokens(fmt.Sprint("echo hello world"))=4 = 5. |
| 51 | if got := withArgs - base; got != 5 { |
| 52 | t.Fatalf("argument cost = %d, want 5 (Message.Tokens must account for ToolCall.Arguments)", got) |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | func TestTruncateSmallUntouched(t *testing.T) { |
| 57 | in := strings.Repeat("x", 20000) // 5000 tokens, under 6k cap |