Skip to content

fix(tools): deduplicate tool names at API boundary for Vertex/Azure/Bedrock#18532

Closed
liuhao1024 wants to merge 1 commit into
NousResearch:mainfrom
liuhao1024:fix/tool-name-dedup-api-boundary
Closed

fix(tools): deduplicate tool names at API boundary for Vertex/Azure/Bedrock#18532
liuhao1024 wants to merge 1 commit into
NousResearch:mainfrom
liuhao1024:fix/tool-name-dedup-api-boundary

Conversation

@liuhao1024

Copy link
Copy Markdown
Contributor

Summary

Add defensive dedup guards at two API-boundary functions that pass tool schemas to providers without checking for duplicate names. Providers like Google Vertex, Azure, and Amazon Bedrock reject requests with duplicate tool names (HTTP 400: Tool names must be unique).

Root cause context: The upstream injection paths in run_agent.py already dedup after PR #17335, but two last-mile functions pass tools through without any safety net:

  • 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

If any upstream injection path regresses (plugin re-registration, cache poisoning, context engine re-init), duplicates reach the API and produce silent 400 failures that exhaust the fallback chain.

Changes

File Change
agent/auxiliary_client.py Dedup guard in _build_call_kwargs() before kwargs["tools"] = tools
agent/anthropic_adapter.py Dedup guard in convert_tools_to_anthropic() loop
tests/agent/test_auxiliary_client.py 4 tests: unique passthrough, duplicate removal, empty, None
tests/agent/test_anthropic_adapter.py 4 tests: unique passthrough, duplicate removal, empty, None

Design Decisions

  • Intentionally conservative: Duplicates are dropped with logger.warning(), not raising errors. The root-cause dedup in run_agent.py is the primary defense; these guards convert a hard 400 failure into a recoverable condition.
  • First occurrence wins: Later duplicates are dropped, preserving the tool schema from the earliest registration path.
  • No performance impact: The dedup set is O(n) in the number of tools (typically 10-50).

Test Plan

  • RED: new tests fail without the fix
  • GREEN: all 8 new tests pass with the fix
  • No regressions in existing test suites for both modules

Related

…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 NousResearch#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 NousResearch#18478
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent loop, run_agent.py, prompt builder labels May 1, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related to #18497 (same root cause fix for #18478, different code paths). Both provide dedup guards — this one targets auxiliary_client + anthropic_adapter; #18497 targets transports.

@teknium1

teknium1 commented May 2, 2026

Copy link
Copy Markdown
Contributor

Merged via #18748 — your commit cherry-picked onto current main with authorship preserved via rebase-merge. Thanks for the defensive dedup guards and the thorough test coverage!

#18748

@teknium1 teknium1 closed this May 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent loop, run_agent.py, prompt builder P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Duplicate tool names cause silent 400 failures on strict providers (Google Vertex, Azure, Bedrock) after 4d363499d

3 participants