Skip to content

fix(responses-bridge): expand namespace tools instead of dropping them - #36253

Open
devin-ai-integration[bot] wants to merge 2 commits into
litellm_internal_stagingfrom
litellm_responses_bridge_namespace_tools
Open

fix(responses-bridge): expand namespace tools instead of dropping them#36253
devin-ai-integration[bot] wants to merge 2 commits into
litellm_internal_stagingfrom
litellm_responses_bridge_namespace_tools

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

  • namespace tools are dropped whole on the chat completions bridge
  • every function tool nested inside one disappears with the container

How it solves it:

  • replace each namespace with the tools it contains
  • the nested tools then convert like any top level tool

User Flow

Before: a developer using a client that groups its tools in a namespace, against a model routed through the chat completions bridge, watches the model act as if it has no tools

  1. They send POST https://litellm-domain/v1/responses with "tool_choice": "required" and one tool of "type": "namespace" holding a get_weather function tool
  2. They get a 200 back whose output holds a single message with empty text, no function_call item
  3. Their client sits waiting for a tool call that never arrives, so the sub-agent and app tools the namespace declared are unusable

After: the same request produces the tool call the client asked for

  1. They send the same POST https://litellm-domain/v1/responses with the same namespace tool
  2. They get a 200 whose output now holds a function_call item named get_weather with {"city":"Tokyo"}
  3. Their client answers the call and the conversation continues as it does against providers with native Responses support

Relevant issues

Issue 2 of #35878. Issue 1 of it was fixed separately in #35885, so #35878 is reopened for this half

Linear ticket

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment @greptileai to re-request a review after pushing changes)

Screenshots / Proof of Fix

A namespace is a grouping container: it has no callable schema of its own, and its tools array holds ordinary function tools. The bridge treated it as an unsupported built-in next to computer_use and image_generation and dropped it, taking the nested tools with it, so a bridged client silently lost them

Config used for both runs, a real OpenAI model forced onto the bridge:

model_list:
  - model_name: bridged-model
    litellm_params:
      model: openai/gpt-5.6
      api_key: os.environ/OPENAI_API_KEY
      use_chat_completions_api: true
general_settings:
  master_key: sk-1234

Request body used for both runs, saved as request.json:

{
  "model": "bridged-model",
  "input": "Call the get_weather tool for Tokyo. Do not answer in text.",
  "tool_choice": "required",
  "reasoning": {"effort": "none"},
  "tools": [
    {
      "type": "namespace",
      "name": "collaboration",
      "description": "sub-agent tools",
      "tools": [
        {
          "type": "function",
          "name": "get_weather",
          "description": "Get the weather for a city",
          "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}
        }
      ]
    }
  ]
}
curl -s http://localhost:4000/v1/responses -H "Authorization: Bearer sk-1234" \
  -H "Content-Type: application/json" -d @request.json

Before, at 0a606cb258 (this branch's base, with the fix not applied), the namespace and its nested tool are gone and the model answers with empty text:

{"id":"resp_IgIOoTcP_Yh74rI4g71pGHiyjTMiTyGSF...","created_at":1786159520,"model":"bridged-model","object":"response","output":[{"type":"message","id":"chatcmpl-EARySoR9kgGZISjvuz8ENhVPgLPWZ","status":"completed","role":"assistant","content":[{"type":"output_text","text":"","annotations":[]}],"phase":null}],"parallel_tool_calls":false,"temperature":0.0,"tool_choice":"auto","tools":[]}

and the proxy log for that request says so outright:

Dropping Responses API tool of type 'namespace': it has no Chat Completions equivalent and the target provider would reject the request.

After, same curl at 82df8a9489, the nested tool survives and the model calls it:

{"id":"resp_yHqPRxKGKlEGJTd8kDGrEg4tqOVjzYJEqNL8...","created_at":1786160325,"model":"bridged-model","object":"response","output":[{"type":"message","id":"chatcmpl-EASBXPb2DkLGzFPpjBWX8PaWycLgD","status":"completed","role":"assistant","content":[{"type":"output_text","text":null,"annotations":[]}],"phase":null},{"arguments":"{\"city\":\"Tokyo\"}","call_id":"call_TrzCsyrJhvCHcF5ut2gb0yyj","name":"get_weather","type":"function_call","id":"call_TrzCsyrJhvCHcF5ut2gb0yyj","namespace":null,"status":"completed"}],"parallel_tool_calls":false,"temperature":0.0,"tool_choice":"auto","tools":[]}

No Dropping Responses API tool line appears in the log for the after run

The two new regression tests fail on the unfixed tree and pass with the fix, and tests/test_litellm/responses/ stays green

Type

🐛 Bug Fix

Changes

litellm/responses/litellm_completion_transformation/namespace_tools.py is new and holds flatten_namespace_tools, which walks the requested tools and swaps each namespace for the tools it contains

litellm/responses/litellm_completion_transformation/transformation.py runs the requested tools through that helper before its conversion loop. Flattening up front rather than adding a branch inside the loop keeps that already long function from growing another path, and it avoids the recursion the code-quality check bans. Nested tools then go through the same function, custom, mcp, and web_search handling as top level ones, so an unsupported built-in nested inside a namespace is still dropped, and namespace stays in the drop list so a namespace nested inside a namespace never reaches the provider

This matches what the Anthropic chat transformation already does with namespaces, which flattens them rather than dropping

Not included: #35878 also asks for tool_search to be converted into a function tool. That one is a server side Responses tool, so turning it into a client facing function tool would have the model emit tool_search calls the client never intended to answer. #33783 already drops it, which is the right handling for chat only providers, so this PR leaves that path alone

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR

Link to Devin session: https://app.devin.ai/sessions/f4699e222aab44d5a016abc259d9f19b
Requested by: @yucheng-berri

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@yucheng-berri yucheng-berri self-assigned this Aug 8, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@greptile-apps

greptile-apps Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the Responses-to-Chat-Completions bridge so namespace containers are recursively expanded rather than discarded.

  • Adds a recursive namespace-flattening helper.
  • Runs flattened nested tools through the existing function, custom, MCP, web-search, and unsupported-tool conversion paths.
  • Adds regression coverage for namespace functions, top-level siblings, and unsupported nested tools.

Confidence Score: 5/5

The PR appears safe to merge, with namespace tools now flowing through the bridge’s existing conversion behavior without an identified regression.

The flattening helper preserves the order and content of non-namespace tools, recursively exposes nested tools to the established conversion loop, and the added tests cover the primary fixed behavior and mixed-tool case.

Important Files Changed

Filename Overview
litellm/responses/litellm_completion_transformation/namespace_tools.py Adds a focused, non-mutating recursive helper that preserves tool order while replacing namespace containers with their nested tools.
litellm/responses/litellm_completion_transformation/transformation.py Applies namespace expansion before the existing conversion loop and removes namespace from the unsupported-tool drop list.
tests/test_litellm/responses/litellm_completion_transformation/test_litellm_completion_responses.py Adds meaningful regression tests covering nested function conversion, ordering alongside top-level tools, parameter defaults, and dropping unsupported nested built-ins.

Reviews (1): Last reviewed commit: "fix(responses-bridge): expand namespace ..." | Re-trigger Greptile

@codecov

codecov Bot commented Aug 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@codspeed-hq

codspeed-hq Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing litellm_responses_bridge_namespace_tools (82df8a9) with litellm_internal_staging (f05d468)1

Open in CodSpeed

Footnotes

  1. No successful run was found on litellm_internal_staging (b6e3ff6) during the generation of this report, so f05d468 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

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.

1 participant