Skip to content

fix(main): forward verbosity param to chat completion providers - #32254

Merged
mateo-berri merged 1 commit into
litellm_internal_stagingfrom
litellm_lit4124_forward_verbosity
Jul 6, 2026
Merged

fix(main): forward verbosity param to chat completion providers#32254
mateo-berri merged 1 commit into
litellm_internal_stagingfrom
litellm_lit4124_forward_verbosity

Conversation

@mateo-berri

@mateo-berri mateo-berri commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Relevant issues

Linear ticket

Resolves LIT-4124

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 requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

Delays in PR merge?

If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).

Screenshots / Proof of Fix

Ran a live proxy twice from an isolated git worktree with its own venv: once at the merge-base commit (before) and once at this PR's head (after). DB-free config with just the gpt-5.2 model entry and master_key: sk-1234, served on a random unused port (59053), hitting the real OpenAI API with gpt-5.2, no mocks. Proxy started with .venv/bin/python litellm/proxy/proxy_cli.py --config qa_config.yaml --port 59053 in both phases

Before (commit 6cecb6e)

/utils/transform_request shows the exact body LiteLLM would send to OpenAI; verbosity is silently dropped

curl -s http://localhost:59053/utils/transform_request -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" -d '{"call_type": "completion", "request_body": {"model": "gpt-5.2", "messages": [{"role": "user", "content": "hi"}], "verbosity": "high"}}' | jq '.raw_request_body'
{
  "model": "gpt-5.2",
  "messages": [
    {
      "role": "user",
      "content": "hi"
    }
  ]
}

Live call with verbosity: low

curl -s http://localhost:59053/v1/chat/completions -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" -d '{"model": "gpt-5.2", "messages": [{"role": "user", "content": "Explain about quantum computing"}], "verbosity": "low"}' | jq '{model, completion_tokens: .usage.completion_tokens, content_chars: (.choices[0].message.content | length)}'
{
  "model": "gpt-5.2",
  "completion_tokens": 751,
  "content_chars": 3573
}

Live call with verbosity: high

curl -s http://localhost:59053/v1/chat/completions -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" -d '{"model": "gpt-5.2", "messages": [{"role": "user", "content": "Explain about quantum computing"}], "verbosity": "high"}' | jq '{model, completion_tokens: .usage.completion_tokens, content_chars: (.choices[0].message.content | length)}'
{
  "model": "gpt-5.2",
  "completion_tokens": 709,
  "content_chars": 3345
}

low vs high is 751 vs 709 completion tokens (high is even slightly shorter), confirming the param never reached OpenAI

After (commit fd2e2ee)

Same worktree and venv, git checkout fd2e2eec70, same config and port. The transform now forwards verbosity

curl -s http://localhost:59053/utils/transform_request -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" -d '{"call_type": "completion", "request_body": {"model": "gpt-5.2", "messages": [{"role": "user", "content": "hi"}], "verbosity": "high"}}' | jq '.raw_request_body'
{
  "model": "gpt-5.2",
  "messages": [
    {
      "role": "user",
      "content": "hi"
    }
  ],
  "verbosity": "high"
}

Live call with verbosity: low

curl -s http://localhost:59053/v1/chat/completions -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" -d '{"model": "gpt-5.2", "messages": [{"role": "user", "content": "Explain about quantum computing"}], "verbosity": "low"}' | jq '{model, completion_tokens: .usage.completion_tokens, content_chars: (.choices[0].message.content | length)}'
{
  "model": "gpt-5.2",
  "completion_tokens": 627,
  "content_chars": 2956
}

Live call with verbosity: high

curl -s http://localhost:59053/v1/chat/completions -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" -d '{"model": "gpt-5.2", "messages": [{"role": "user", "content": "Explain about quantum computing"}], "verbosity": "high"}' | jq '{model, completion_tokens: .usage.completion_tokens, content_chars: (.choices[0].message.content | length)}'
{
  "model": "gpt-5.2",
  "completion_tokens": 1451,
  "content_chars": 6537
}

low vs high is now 627 vs 1451 completion tokens, a 2.3x divergence, matching the roughly 3x spread seen when calling OpenAI directly. Before the fix the spread was within 6%

Type

🐛 Bug Fix

Changes

verbosity ("low"/"medium"/"high") passed to litellm.completion()/acompletion(), and therefore to the proxy's /chat/completions, was silently dropped and never forwarded to the provider. A customer noticed that verbosity low vs high through the proxy produced near-identical gpt-5.2 outputs while calling OpenAI directly diverged about 3x in length

Root cause: completion() accepts verbosity as a named parameter, but the optional_param_args dict it passes to get_optional_params() omitted it. Because it is a named parameter it never landed in **kwargs/non_default_params either, so get_optional_params() (which already has a verbosity parameter and correct GPT-5 handling via litellm/llms/openai/chat/gpt_5_transformation.py) never received it. The async path had the same gap: acompletion() also omitted verbosity from the completion_kwargs it builds for completion()

The fix adds verbosity to both dicts, right next to reasoning_effort which follows the identical plumbing. Downstream behavior now matches reasoning_effort semantics: GPT-5 family models forward it, non-supporting models (e.g. gpt-4o) raise UnsupportedParamsError unless drop_params is set, and pre_process_non_default_params keeps it since it is already in DEFAULT_CHAT_COMPLETION_PARAM_VALUES

Regression tests in tests/test_litellm/test_main.py assert the provider request body contains verbosity for both the sync (return_raw_request) and async (acompletion via respx) paths; both fail on the base branch and pass with the fix

@greptile-apps

greptile-apps Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes verbosity being silently dropped before it reached get_optional_params() in both the sync and async completion paths. The parameter was already declared in both function signatures and the downstream GPT-5 transformation and constants infrastructure already handled it; only the forwarding into the intermediate kwargs dict was missing.

  • litellm/main.py: verbosity is added to completion_kwargs in acompletion() (line ~585) and to optional_param_args in completion() (line ~5197), immediately adjacent to the identical reasoning_effort entry.
  • tests/test_litellm/test_main.py: Two new regression tests verify the fix — a sync test using return_raw_request that inspects the raw request body, and an async test using respx_mock + acompletion that inspects the actual intercepted HTTP payload.

Confidence Score: 5/5

Safe to merge — the change is a two-line targeted addition that mirrors the already-working reasoning_effort plumbing.

The fix is minimal: two lines in main.py that close the gap between a declared named parameter and the dict that routes it downstream. All downstream handling (constants, get_optional_params, gpt_5_transformation.py) was already correct. The new tests exercise both code paths end-to-end with no real network calls, and no existing tests were weakened.

No files require special attention.

Important Files Changed

Filename Overview
litellm/main.py Adds verbosity to the completion_kwargs dict in acompletion() and to the optional_param_args dict in completion() so it reaches get_optional_params(); the downstream handler and constants already supported it.
tests/test_litellm/test_main.py Adds two regression tests — one sync (via return_raw_request) and one async (via respx_mock + acompletion) — that assert verbosity appears in the provider request body; both new tests and a shared mock helper are added without modifying existing tests.

Reviews (1): Last reviewed commit: "fix(main): forward verbosity param to ch..." | Re-trigger Greptile

@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@mateo-berri
mateo-berri merged commit 46a8025 into litellm_internal_staging Jul 6, 2026
125 of 126 checks passed
@mateo-berri
mateo-berri deleted the litellm_lit4124_forward_verbosity branch July 6, 2026 17:41
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.

2 participants