- Shipped
- September 29, 2026 at 1:14 AM UTC
- Author
- Kamo
- Commit
- 51766db
SP98-A-12. Member chat keyed a Tool Plane call chat:<session guid>:<tool call id>. A call id is unique only within its turn: HuggingFaceAdapter numbers id-less calls call_<index>, and StreamAssembler does the same on every streamed turn, so the second write of a session under call_0 was replayed as the first (same arguments) or refused as IDEMPOTENCY_KEY_REUSED (different ones). The key is now chat:<session guid>:<turn>:<tool call id>, the turn being the id of the assistant tool_use row saved before the round's calls run (REST and streamed turns alike, so two rounds of one turn differ too); the hashed form carries the turn as well. A call with no id or no turn still gets a fresh key. CopilotToolKeyPerTurnTest drives two REST turns, two streamed turns and two rounds of one turn that all call call_0 through the real CopilotTools and records the keys the Tool Plane receives.
