litellm/tests
Fede Kamelhar 68759a239f
fix(oci): drop non-function tools under drop_params and gate reasoning_effort on declared levels (#40732)
* fix(oci): skip non-function tools and gate reasoning_effort on models that reject it

Fixes #31449.

Two OCI GENERIC request-building defects that made Grok-on-OCI unusable
for tool-using coding-agent clients (Codex over the Responses API, Claude
Code over the Anthropic Messages API):

1. `adapt_tool_definition_to_oci_standard` raised `OCIError("OCI only
   supports function tools")` for any tool whose type is not "function",
   aborting the whole request when a client mixed a built-in/server tool
   in with its function tools. Non-function tools are now skipped with a
   warning; if none remain, `tools`/`toolChoice` are omitted from the
   request instead of sending an empty array.

2. The GENERIC param map forwarded `reasoning_effort` to every non-Cohere
   model, but OCI rejects it for all served xAI Grok models
   (`Model grok-4.20 does not support parameter reasoningEffort`) and for
   OpenAI's non-reasoning models (`Unrecognized request argument supplied:
   reasoning_effort` on gpt-4o / gpt-4.1); gpt-5, the o-series, gpt-oss-*
   and Meta/Google models accept it. `_model_supports_reasoning_effort`
   encodes that, `get_supported_openai_params` stops advertising the param
   for those models, and `map_openai_params` follows the standard
   unsupported-param contract (dropped under drop_params, clear error
   otherwise) so `drop_params` / `additional_drop_params` now work as
   documented instead of the 400 surfacing from the service.

Behaviour verified against OCI GenAI in us-chicago-1 (2026-09-11) per model.
The two existing reasoning_effort normalisation tests move from a Grok
model to openai.gpt-5, which is the case they exercise. 21 new tests; the
OCI suite is 406 passed.

* fix(oci): drive reasoning_effort gating from the model catalog and drop tool_choice for skipped tools

Review follow-ups on #40732:

- `_model_supports_reasoning_effort` now reads the `supports_reasoning` flag
  of the model's `oci/` catalog entry through `get_model_info` instead of
  hardcoding xAI / gpt-oss branches. Catalogued models without the flag
  (xAI Grok, Meta Llama) no longer receive `reasoningEffort`; models absent
  from the catalog keep the historical pass-through.
- Catalog: flag `oci/google.gemini-2.5-{flash,pro,flash-lite}` as reasoning
  models and add `oci/openai.gpt-oss-120b` / `oci/openai.gpt-oss-20b`
  (pricing from Oracle's public price list, 128K context per OCI docs).
- `_model_uses_max_completion_tokens` routes on the `openai.*` prefix only.
  OCI-hosted Gemini accepts `maxCompletionTokens` but ignores it (the output
  cap silently disappears) and Llama rejects it with 400, so the catalog's
  reasoning flag must not drive that switch.
- After tool adaptation, a `FUNCTION` tool_choice naming a tool that was
  skipped (built-in / server tools) is dropped with a warning instead of
  being sent to OCI, which rejects the unmatched choice.

Verified live against OCI GenAI (us-chicago-1): Grok with mixed tools plus a
forced built-in now completes and still calls the function tool; Gemini and
gpt-oss forward reasoningEffort with maxTokens honoured; Llama drops it under
drop_params; gpt-5 keeps maxCompletionTokens.

* style(oci): use an immutable set for the tool-name lookup

Keeps the type-discipline gate (LIT002, mutable collections) within its
budget; the lookup is read-only.

* fix(oci): fail closed when a forced tool_choice names a tool OCI will not receive

Review follow-ups on #40732:

- When tool_choice forces a function that is not among the adapted tools
  (a skipped built-in or a misspelled name), send `toolChoice: NONE` instead
  of removing the choice. Falling back to the service default would let the
  model call any other supplied function even though the caller forced a
  specific one, which an agent processing untrusted content must not do.
- Move the #31449 regression tests into the mapped test module
  (`test_oci_chat_transformation.py`) instead of a separate file.

Verified live against OCI GenAI: Grok and Llama with a forced skipped
built-in now complete with no tool call; a forced kept function is still
honoured.

* test(oci): point reasoning_effort comments at the in-module gating tests

The referenced module was folded into this file.

* fix(oci): drop non-function tools only under drop_params and gate reasoning_effort on declared levels

Non-function tools now follow the unsupported-param contract: a 400 naming
drop_params without it, and dropped with a warning under it, with a forced
dropped tool turning tool calls off. reasoning_effort is gated on the model's
reasoning_effort_levels catalog entry, so OCI Llama keeps forwarding it and the
Grok 4.20 models OCI serves, now in the catalog with their Oracle prices, stop
sending a param the service rejects

* fix(oci): gate reasoning_effort on oci/xai.grok-4.20, which rejects it

* fix(oci): disable tool calls when tool_choice forces a dropped custom tool by name

* fix(oci): drop tool_choice that forces a dropped tool and keep a kept function's name

* fix(oci): keep Gemini 2.5 Flash Lite unflagged for reasoning so released proxies keep its max_tokens cap

* fix(oci): answer 400 when a request depends on a dropped tool and leave Gemini max_tokens routing to its own PR

Under drop_params, non-function tools still drop when function tools remain and
tool_choice does not force a dropped tool. A request whose every tool is dropped,
or whose tool_choice forces one, now answers 400 instead of a tool-less reply the
model can fill with invented results, or a swap to another tool.

The maxTokens routing change for OCI Gemini goes back to base, since it is
outside this fix and an open PR carries it.

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-10-15 22:20:02 +00:00
..
_support fix(params): validate stream_chunk_size once, before any provider call (#43222) 2026-09-26 23:01:20 +00:00
base_sdk_tests test: extend runtime regression contracts for Messages and SDK (#46641) 2026-10-15 17:51:15 +00:00
benchmarks refactor: expose core private helpers under public names (#44871) 2026-10-07 00:05:27 +00:00
code_coverage_tests feat(proxy): split Azure PTU deployments across teams with per-team PTU ceilings and PTU-hour reporting (#43043) 2026-10-15 18:44:30 +00:00
documentation_tests fix(proxy): let configured pass-through endpoints outrank built-in provider prefix routes (#44133) 2026-10-10 12:26:17 -07:00
e2e fix(proxy-extras): hold only Prisma's lock key during migrate deploy so it never waits on the request log index build (#46660) 2026-10-15 14:47:33 -07:00
e2e_harness test(e2e): rename load to perf and consolidate the opt-in into E2E_PERF_TESTS (#46077) 2026-10-12 13:54:03 -07:00
fixtures test: migrate tests/llm_translation into unit, integration and e2e tiers (#45759) 2026-10-11 07:58:53 +00:00
harness_e2e feat: add litellm.agent() to run claude code, codex, opencode and deep agents through the ai gateway (#43885) 2026-10-01 22:27:49 +00:00
integration fix(oci): drop non-function tools under drop_params and gate reasoning_effort on declared levels (#40732) 2026-10-15 22:20:02 +00:00
rust-python-harness docs(agents): ban semicolons and colons in human-facing text (#45684) 2026-10-09 16:36:32 -07:00
test_litellm_rust test(rust-bridge): select native routes per test without LITELLM_RUST (#46620) 2026-10-15 09:12:08 -07:00
typing fix: support OpenAI SDK 3 while retaining SDK 2 compatibility (#44927) 2026-10-09 19:45:50 -07:00
unit fix(oci): drop non-function tools under drop_params and gate reasoning_effort on declared levels (#40732) 2026-10-15 22:20:02 +00:00
windows_tests test: move packaging and install checks off CircleCI build_and_test (#45757) 2026-10-10 09:33:51 -07:00
__init__.py refactor: expose core private helpers under public names (#44871) 2026-10-07 00:05:27 +00:00
_fake_openai_endpoint_server.py
_flush_vcr_cache.py
_live_test_helpers.py
_master_key.py fix(security): remove the publicly known master key from the repo (#44718) 2026-10-06 10:55:24 -07:00
_openai_record_replay_proxy.py
_process_helpers.py test: count a zombie grandchild as gone in the migrate deploy timeout test (#42570) 2026-09-22 14:59:26 -07:00
_vcr_conftest_common.py test: migrate tests/llm_translation into unit, integration and e2e tiers (#45759) 2026-10-11 07:58:53 +00:00
_vcr_redis_persister.py
_wait_helpers.py
_ws_vcr.py
AGENTS.md docs(agents): ban semicolons and colons in human-facing text (#45684) 2026-10-09 16:36:32 -07:00
capturing_transport.py test(vcr): guard leaked cassette patches and make injected-transport embedding tests immune (#42542) 2026-09-22 14:20:18 -07:00
eval_swe_bench.py
fake_openai_endpoint.py
gettysburg.wav
large_text.py
openai_batch_completions.jsonl
pyrightconfig.json
README.MD test: finish the non-proxy half of tests/test_litellm (#43281) 2026-09-25 22:43:41 -07:00
test_logging.conf
test_rust_python_harness.py test: move 76 live top-level tests to offline unit and integration coverage (#45352) 2026-10-08 10:33:35 -07:00
VCR_TESTING.md test: migrate tests/llm_translation into unit, integration and e2e tiers (#45759) 2026-10-11 07:58:53 +00:00
white_100x100.png test: stop CI tests from downloading tokenizer files and images (#43257) 2026-09-25 19:27:48 -07:00

In total litellm runs 1000+ tests

[02/20/2025] Update:

To make it easier to contribute and map what behavior is tested,

we've started mapping the litellm directory in tests/unit

This folder can only run mock tests.