Summary
In a long agent session with a large toolset (~106 registered tools), the virtual tools packer recomputed its grouping at a turn boundary and dropped a tool from the request toolset entirely — it was neither top-level nor inside any activate_* virtual group. The same tool had been called successfully 12 times in the minutes immediately before. Subsequent calls failed with:
Tool exo-run is currently disabled by the user, and cannot be called.
No user action had occurred (no Configure Tools interaction at all)
Evidence
From the session's debug logs (debug-logs/<sessionId>/tools_N.json snapshots plus main.jsonl):
| Snapshot |
Time |
exo-run status |
tools_0.json |
20:25 |
Present as a top-level tool; 12 successful tool_call events follow (20:49–20:53) |
tools_1.json |
21:00 |
Absent from the entire payload — content.includes("exo-run") === false. Not top-level, not in any virtual group, not even mentioned in group prose |
tools_2.json |
21:04 |
Still absent (mentioned only inside a sibling tool's description text) |
The tools_0 / tools_1 diff shows the repack was lossy in both directions: 5 tools dropped from the top level (exo-run, exo-ping, and three tools from a browser-automation extension), while 7 different tools from the same browser extension surfaced. A sibling tool (exo-ping) survived by being folded into an activate_diagnostic_tools group description — exo-run just vanished.
A second occurrence exists in the same session log: tools_5.json (previous day) is missing all five exo-* tools the same way.
Reproduced on: VS Code stable, macOS, default github.copilot.chat.virtualTools.threshold (not set by user). Notably, grouping was active at ~106 tools even though the setting's documented default threshold is 128.
Problems
Needless to say, this is a pretty broken and confusing experience for both the agent and the user. The problems compound on each other.
- The repack loses tools outright. A registered, enabled tool ended up neither top-level nor inside any virtual group after regrouping.
- Recency/usage does not pin tools. The dropped tool was in active, successful use in the same session minutes before the repack.
- The error message misattributes the failure to the user. "Currently disabled by the user" sent both me and the agent down a false debugging path (toggling tools in Configure Tools, running tool-reset commands, reloading). The actual state was "not present in this turn's assembled toolset."
- Each repack changes the serialized tool list, which sits at the front of the prompt — invalidating provider-side prompt caches on every regroup even when no tools actually changed. With Anthropic-style prefix caching this is a full re-ingestion of the conversation.
Suggested fixes
- Treat "successfully called this session" as a pinning signal so in-use tools survive regrouping.
- Guarantee the packer is lossless: every registered tool must be reachable either top-level or via some
activate_* group.
- Reword the error to distinguish "tool not in this turn's toolset (regrouped/dropped)" from "disabled by the user."
- Consider stabilizing the grouping across turns within a session unless the underlying tool registrations actually change (also helps prompt-cache hit rates).
Happy to attach sanitized tools_N.json diffs and main.jsonl excerpts if they would be helpful.
Summary
In a long agent session with a large toolset (~106 registered tools), the virtual tools packer recomputed its grouping at a turn boundary and dropped a tool from the request toolset entirely — it was neither top-level nor inside any
activate_*virtual group. The same tool had been called successfully 12 times in the minutes immediately before. Subsequent calls failed with:No user action had occurred (no Configure Tools interaction at all)
Evidence
From the session's debug logs (
debug-logs/<sessionId>/tools_N.jsonsnapshots plusmain.jsonl):exo-runstatustools_0.jsontool_callevents follow (20:49–20:53)tools_1.jsoncontent.includes("exo-run") === false. Not top-level, not in any virtual group, not even mentioned in group prosetools_2.jsonThe
tools_0/tools_1diff shows the repack was lossy in both directions: 5 tools dropped from the top level (exo-run,exo-ping, and three tools from a browser-automation extension), while 7 different tools from the same browser extension surfaced. A sibling tool (exo-ping) survived by being folded into anactivate_diagnostic_toolsgroup description —exo-runjust vanished.A second occurrence exists in the same session log:
tools_5.json(previous day) is missing all fiveexo-*tools the same way.Reproduced on: VS Code stable, macOS, default
github.copilot.chat.virtualTools.threshold(not set by user). Notably, grouping was active at ~106 tools even though the setting's documented default threshold is 128.Problems
Needless to say, this is a pretty broken and confusing experience for both the agent and the user. The problems compound on each other.
Suggested fixes
activate_*group.Happy to attach sanitized
tools_N.jsondiffs andmain.jsonlexcerpts if they would be helpful.