fix(tools): dedup tool names at API boundary for Vertex/Azure/Bedrock (salvage #18532)#18748
Merged
Conversation
…edrock Providers like Google Vertex, Azure, and Amazon Bedrock reject API requests with duplicate tool names (HTTP 400: 'Tool names must be unique'). The upstream injection paths in run_agent.py already dedup after PR #17335, but two API-boundary functions pass tools through without checking: - agent/auxiliary_client.py: _build_call_kwargs() (all non-Anthropic providers in chat_completions mode) - agent/anthropic_adapter.py: convert_tools_to_anthropic() (Anthropic Messages API path) Add defensive dedup guards at both sites. Duplicates are dropped with a warning log, converting a hard 400 failure into a recoverable condition. This is intentionally conservative — the root-cause dedup in run_agent.py is the primary defense; these guards add resilience against future injection-path regressions. Includes 8 new tests covering unique passthrough, duplicate removal, empty/None edge cases. Closes #18478
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Providers that enforce tool-name uniqueness (Google Vertex, Azure, Amazon Bedrock, Anthropic) now receive deduplicated tool lists even if an upstream injection path regresses. Before this change, a duplicate from any source (context-engine plugin re-registration, cache poisoning, re-init path) caused HTTP 400
Tool names must be unique— non-retryable and silent when fallback chains exhausted.Cherry-picked from @liuhao1024's #18532 onto current main.
What changed
agent/auxiliary_client.py:_build_call_kwargs()dedups tools beforekwargs["tools"] = …(covers all chat_completions providers).agent/anthropic_adapter.py:convert_tools_to_anthropic()dedups in the loop (covers the native Anthropic Messages API path).logger.warning, first occurrence wins.Why this layer (and not just the root-cause fix)
The root-cause dedup in
run_agent.py(context-engine + memory-tool injection) is already on main — this PR adds defensive guards at the two API-boundary functions so any future injection-path regression converts a hard 400 into a warning rather than silently exhausting the fallback chain. Intentionally conservative.Validation
scripts/run_tests.sh tests/agent/test_auxiliary_client.py tests/agent/test_anthropic_adapter.py→ 260 passed._build_call_kwargs(provider="openrouter", …)andconvert_tools_to_anthropic(…)called with a 7-tool list containing 2 duplicates (simulating the hermes-lcm plugin double-registration). Both paths return 5 unique tools, first-occurrence ordering preserved.Closes #18478.