Skip to content

Conversation

@cpacker
Copy link
Collaborator

@cpacker cpacker commented Jan 23, 2026

When switching toolsets via /toolset, the registry was cleared synchronously then tools loaded asynchronously. Messages could be sent during this window with stale/partial tools, causing parallel tool calls to have mixed success/failure ("Tool not found" for some).

Changes:

  • Add replaceRegistry() helper for atomic clear+populate
  • Add switch lock mechanism (acquireSwitchLock/releaseSwitchLock) with ref-counting to handle overlapping switches
  • Export waitForToolsetReady() and await it in sendMessageStream() before reading tools
  • Add clearToolsWithLock() for forceToolsetSwitch("none") case

👾 Generated with Letta Code

When switching toolsets via /toolset, the registry was cleared
synchronously then tools loaded asynchronously. Messages could be
sent during this window with stale/partial tools, causing parallel
tool calls to have mixed success/failure ("Tool not found" for some).

Changes:
- Add replaceRegistry() helper for atomic clear+populate
- Add switch lock mechanism (acquireSwitchLock/releaseSwitchLock)
  with ref-counting to handle overlapping switches
- Export waitForToolsetReady() and await it in sendMessageStream()
  before reading tools
- Add clearToolsWithLock() for forceToolsetSwitch("none") case

👾 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>
@cpacker cpacker merged commit e32b10f into main Jan 23, 2026
10 checks passed
@cpacker cpacker deleted the fix/toolset-switch-race branch January 23, 2026 01:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants