Commit 366be3e
committed
fix(cache): make skill list ordering deterministic to stop KV cache busts
SkillRegistry stores skills in a HashMap, and list() returned
self.skills.values() in per-instance randomized order. The 'Available
Skills' system-prompt section is built from this, and current_skills_snapshot
can hand back a different HashMap instance via its lock-contended
self.skills.clone() fallback. Under tool-loop lock contention this emitted
the skills section in different orders across calls: a system prompt with
identical length but different bytes, which silently invalidated Anthropic's
strict-prefix KV cache mid-conversation.
This matches the observed KV_CACHE_USAGE signature: system_changed=true with
system_chars==baseline_system_chars (same width, different content).
Sort list() by name so ordering is stable regardless of HashMap seed or
instance. Add a regression test.1 parent db373f5 commit 366be3e
1 file changed
Lines changed: 49 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
321 | 321 | | |
322 | 322 | | |
323 | 323 | | |
324 | | - | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
325 | 333 | | |
326 | | - | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
327 | 337 | | |
328 | 338 | | |
329 | 339 | | |
| |||
705 | 715 | | |
706 | 716 | | |
707 | 717 | | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
| 721 | + | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
708 | 755 | | |
709 | 756 | | |
710 | 757 | | |
| |||
0 commit comments