TestPackDropsStrayToolResultDespiteIDReuse: dropOrphanTools is positional too. A stray tool result whose own (dangling, dropped) assistant reused an older turn's ID must not survive via that older assistant's issuance - it would land right after a user message and 400 strict backends.
(t *testing.T)
| 433 | } |
| 434 | } |
| 435 | |
| 436 | // TestPackDropsStrayToolResultDespiteIDReuse: dropOrphanTools is positional |
| 437 | // too. A stray tool result whose own (dangling, dropped) assistant reused an |
| 438 | // older turn's ID must not survive via that older assistant's issuance - it |
| 439 | // would land right after a user message and 400 strict backends. |
| 440 | func TestPackDropsStrayToolResultDespiteIDReuse(t *testing.T) { |
| 441 | history := []Message{ |
| 442 | {Role: RoleUser, Content: "task"}, |
| 443 | // Turn 1 completes with call_0. |
| 444 | {Role: RoleAssistant, ToolCalls: []ToolCall{{ID: "call_0", Name: "bash"}}}, |
| 445 | {Role: RoleTool, ToolCallID: "call_0", Content: "ok"}, |
| 446 | {Role: RoleAssistant, Content: "done"}, |
| 447 | {Role: RoleUser, Content: "again"}, |
| 448 | // Turn 2 reuses call_0 in a parallel set and is aborted after one result. |
| 449 | {Role: RoleAssistant, ToolCalls: []ToolCall{ |
| 450 | {ID: "call_0", Name: "bash"}, {ID: "call_1", Name: "bash"}, |
| 451 | }}, |
| 452 | {Role: RoleTool, ToolCallID: "call_0", Content: "partial"}, |
| 453 | {Role: RoleUser, Content: "next"}, |
| 454 | } |
| 455 | r := Pack(history, 100000) |
| 456 | for i, m := range r.Messages { |
| 457 | if m.Role != RoleTool { |
| 458 | continue |
| 459 | } |
| 460 | if i == 0 || r.Messages[i-1].Role == RoleUser || m.Content == "partial" { |
| 461 | t.Fatalf("stray tool result survived via reused ID: %+v", r.Messages) |
| 462 | } |