Skip to content

Codex cli sso form url#28271

Merged
Sameerlite merged 3 commits into
BerriAI:litellm_oss_staging_1from
boarder7395:codex-cli-sso-form-url
May 20, 2026
Merged

Codex cli sso form url#28271
Sameerlite merged 3 commits into
BerriAI:litellm_oss_staging_1from
boarder7395:codex-cli-sso-form-url

Conversation

@boarder7395

@boarder7395 boarder7395 commented May 19, 2026

Copy link
Copy Markdown
Contributor

Relevant issues

N/A - With the verification code changes that were merged the sso/cli/complete URL is using HTTP instead of HTTPS.

This fixes the CLI SSO verification page generating an http:// form action when LiteLLM is deployed behind an HTTPS ingress/proxy.

The fix changes the form action to use LiteLLM’s existing get_custom_url() helper, which honors PROXY_BASE_URL.

The branch also adds a regression test proving that even when the internal request base URL is http://internal-proxy.local, the rendered form action uses PROXY_BASE_URL=https://test.example.com.

Linear ticket

N/A

Pre-Submission checklist

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

  • [ X ] I have Added testing in the tests/test_litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • [ X ] My PR's scope is as isolated as possible, it only solves 1 specific problem
  • [ X ] 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).

CI (LiteLLM team)

CI status guideline:

  • 50-55 passing tests: main is stable with minor issues.
  • 45-49 passing tests: acceptable but needs attention
  • <= 40 passing tests: unstable; be careful with your merges and assess the risk.
  • Branch creation CI run
    Link:

  • CI run for the last commit
    Link:

  • Merge / cherry-pick CI run
    Links:

Screenshots / Proof of Fix

Type

🆕 New Feature
🐛 Bug Fix
🧹 Refactoring
📖 Documentation
🚄 Infrastructure
✅ Test

Changes

shin-berri and others added 2 commits May 13, 2026 22:37
@CLAassistant

CLAassistant commented May 19, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
2 out of 3 committers have signed the CLA.

✅ boarder7395
✅ yuneng-berri
❌ shin-berri
You have signed the CLA already but the status is still pending? Let us recheck it.

@boarder7395

Copy link
Copy Markdown
Contributor Author

@greptileai

@greptile-apps

greptile-apps Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the CLI SSO verification page generating an http:// form action URL when LiteLLM is deployed behind an HTTPS reverse proxy. The one-line production fix replaces request.url_for("cli_sso_complete", ...) with the existing get_custom_url(request.base_url, route) helper, which already consults PROXY_BASE_URL to produce an externally-correct URL.

  • ui_sso.py: verify_url is now built via get_custom_url, so PROXY_BASE_URL=https://... causes the rendered <form action="..."> to carry the HTTPS gateway URL instead of the internal HTTP one.
  • test_ui_sso.py: Test scaffolding updated to set an internal HTTP base_url, patch PROXY_BASE_URL to an external HTTPS host, and assert the HTML response body contains the HTTPS action URL; a stale url_for mock value is still present but no longer exercised.

Confidence Score: 4/5

Safe to merge; the production change is a minimal one-line swap to a well-tested helper, and the regression test correctly validates the HTTPS URL appears in the rendered HTML.

The production fix is small and correct — get_custom_url already handles PROXY_BASE_URL fallback and path joining throughout the codebase, so reusing it here is consistent. The test update proves the fix end-to-end, though it leaves behind a stale url_for mock that is never exercised by the new code path.

The test file has a leftover url_for mock setup that is no longer called; worth cleaning up to avoid misleading future readers.

Important Files Changed

Filename Overview
litellm/proxy/management_endpoints/ui_sso.py Replaces request.url_for("cli_sso_complete", ...) with get_custom_url(request.base_url, route) so PROXY_BASE_URL is honored when building the form action URL.
tests/test_litellm/proxy/management_endpoints/test_ui_sso.py Test updated to set base_url to an internal HTTP URL, patch PROXY_BASE_URL to the external HTTPS host, and assert the rendered form action uses HTTPS. mock_request.url_for.return_value remains set but is never called by the new code path.

Reviews (1): Last reviewed commit: "Use proxy base URL for CLI SSO form acti..." | Re-trigger Greptile

Comment on lines 2246 to 2248
mock_request.url_for.return_value = (
"https://test.example.com/sso/cli/complete/cli-session-4567890"
"http://internal-proxy.local/sso/cli/complete/cli-session-4567890"
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The mock_request.url_for.return_value assignment is now dead setup — the new code path calls get_custom_url(request.base_url, ...) and never invokes request.url_for. Leaving it in place is misleading: a future reader will expect this mock to influence behavior. It can simply be removed.

Suggested change
mock_request.url_for.return_value = (
"https://test.example.com/sso/cli/complete/cli-session-4567890"
"http://internal-proxy.local/sso/cli/complete/cli-session-4567890"
)
# url_for is no longer called; get_custom_url uses request.base_url directly

@greptile-apps

greptile-apps Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the CLI SSO verification form rendering an http:// action URL when LiteLLM is deployed behind an HTTPS ingress. The root cause was that request.url_for() derives the scheme from the internal request, ignoring the external proxy URL.

  • ui_sso.py: Replaces request.url_for(\"cli_sso_complete\", login_id=key) with get_custom_url(request_base_url=str(request.base_url), route=f\"sso/cli/complete/{key}\"), which correctly uses PROXY_BASE_URL when set, falling back to the request base URL otherwise.
  • test_ui_sso.py: Adds a regression test that sets PROXY_BASE_URL=https://test.example.com while simulating an internal http://internal-proxy.local/ request URL, and asserts the rendered form action contains the external HTTPS URL.

Confidence Score: 4/5

Safe to merge; the change is minimal and well-tested, with the only loose end being a now-dead url_for mock in the test file.

The production fix is a one-line change that reuses a well-established helper already used elsewhere in the proxy. The regression test directly proves the HTTPS form action is rendered correctly. The only residual noise is a dead mock_request.url_for.return_value assignment in the test that is never invoked by the updated code path, which could mislead future readers but does not affect correctness.

No files require special attention; test_ui_sso.py has a minor dead mock worth cleaning up.

Important Files Changed

Filename Overview
litellm/proxy/management_endpoints/ui_sso.py Replaces request.url_for() with get_custom_url() so the SSO form action URL honours PROXY_BASE_URL when the proxy sits behind an HTTPS ingress; straightforward one-line change with no side-effects.
tests/test_litellm/proxy/management_endpoints/test_ui_sso.py Adds PROXY_BASE_URL environment patch and a new body assertion to prove the rendered form action uses HTTPS; leaves a dead url_for mock that is never invoked by the updated production code.

Reviews (2): Last reviewed commit: "Use proxy base URL for CLI SSO form acti..." | Re-trigger Greptile

Comment on lines 2246 to 2248
mock_request.url_for.return_value = (
"https://test.example.com/sso/cli/complete/cli-session-4567890"
"http://internal-proxy.local/sso/cli/complete/cli-session-4567890"
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Dead mock assignment

Since the production code no longer calls request.url_for(), the mock_request.url_for.return_value assignment on these lines is never exercised. Leaving it in place can mislead future readers into thinking url_for is still part of the call path. Consider removing it, or at least adding a comment noting it's kept only for completeness.

@codecov

codecov Bot commented May 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@oss-pr-review-agent-shin

Copy link
Copy Markdown
Contributor

🤖 litellm-agent: This PR is currently BLOCKED from merge.

Score: 0/5

Why blocked:

  • all Phase B agent checks non-approving (phase_b_none_approved, -5 pts)

Details: Score docked for: all Phase B agent checks non-approving (karpathy + security + coverage gap). 1 check also red on neighboring PRs (misc / Run tests) — infra-wide noise, no penalty.

Fix the issues above and push an update — the bot will re-review automatically.

Note: This bot is still in beta and might not always work as expected. Please share any feedback via Slack.

@krrish-berri-2

Copy link
Copy Markdown
Contributor

@boarder7395 — could you add a screenshot or short video showing that this change works as expected? It really helps reviewers verify the fix quickly. Thanks!

@boarder7395 boarder7395 force-pushed the codex-cli-sso-form-url branch from 7350013 to c4ca2b8 Compare May 19, 2026 20:09
@boarder7395

Copy link
Copy Markdown
Contributor Author

@krrish-berri-2 - I'll work on that unfortunately our corporate proxy setup does not let me build the chainguard image you all use as your base. I'll try to get that first thing tomorrow tho

@boarder7395

Copy link
Copy Markdown
Contributor Author

image

@boarder7395

Copy link
Copy Markdown
Contributor Author

@krrish-berri-2 - I have included a screenshot showing the URL now includes https:// instead of http://

@Sameerlite Sameerlite changed the base branch from litellm_internal_staging to litellm_oss_staging_1 May 20, 2026 11:22
@Sameerlite Sameerlite merged commit 9736b29 into BerriAI:litellm_oss_staging_1 May 20, 2026
41 of 42 checks passed
mateo-berri added a commit that referenced this pull request May 21, 2026
* feat: add Xiaomi MiMo-V2.5-Pro and MiMo-V2.5 OpenRouter model entries (#27700)

Squash-merged by litellm-agent from TorvaldUtne's PR.

* fix(ui): trim whitespace from MCP inspector tool call inputs (#28203)

Co-authored-by: shin-berri <[email protected]>
Co-authored-by: yuneng-jiang <[email protected]>

* gemini-3.1-flash-lite pricing (#27933)

* feat(model_prices): add gemini-3.1-flash-lite pricing with standard/batch/flex/priority tiers

* fix pricing

* add service tier

---------

Co-authored-by: shin-berri <[email protected]>

* fix: incorrect /v1/agents request example (#28131)

* fix(anthropic): accept dict-shape reasoning_effort from Responses bridge (#28201)

* fix(anthropic): accept dict-shape reasoning_effort from Responses bridge

Issue #28196 — the Responses->Chat parser (transformation.py:184-200) keeps the full dict as reasoning_effort when summary is set; that branch was added in #25359. But the Anthropic transformation here still guarded on isinstance(value, str), silently dropping the param. Result: callers using the standard Reasoning(effort, summary) OpenAI-shaped object on Anthropic lose thinking entirely (0 reasoning_tokens, no thinking_blocks).

Coerce dict -> string before mapping. Same shape tolerance that gpt_5_transformation._normalize_reasoning_effort_for_chat_completion already implements. summary is irrelevant for Anthropic's thinking_blocks.

Adds two regression tests: one parametrized over string + dict shapes (with and without summary), one covering unparseable dict inputs (drops silently, no crash).

* test(anthropic): add non-adaptive model coverage for dict-shape reasoning_effort

Per Greptile feedback on PR #28198: the original regression test only exercised the adaptive (4.6+) path. Add a parametrized test for the non-adaptive branch (claude-sonnet-4-5) verifying that dict-shape reasoning_effort still maps to thinking.type='enabled' + budget_tokens, and that output_config is NOT set on pre-4.6 models.

* test(anthropic): convert unparseable-dict test to @pytest.mark.parametrize

Per @greptile-apps inline review on PR #28201 — matches the parametrize style of the two adjacent dict-shape tests and produces clearer failure messages (test ID per case instead of one collapsing for-loop).

* feat: add pricing entry for openrouter/google/gemini-3.1-flash-lite (#28280)

Squash-merged by litellm-agent from ro31337's PR.

* fix(router): wrap aresponses streaming iterator for mid-stream fallbacks (#28215)

Squash-merged by litellm-agent from cwang-otto's PR.

* fix(router): unblock staging — mypy + coverage for aresponses streaming fallback (#28318)

Squash-merged by litellm-agent from cwang-otto's PR.

* fix(responses): forward timeout on completion transformation path (Anthropic, Bedrock, Vertex) (#28133)

Squash-merged by litellm-agent from cwang-otto's PR.

* feat(ui): add pause/resume Switch to the models table (#28151)

Squash-merged by litellm-agent from Cyberfilo's PR.

* fix(responses): merge sync completion kwargs to avoid duplicate keys

Double-splatting litellm_completion_request and kwargs raised TypeError
when metadata or service_tier were set. Match the async merge pattern.

Co-authored-by: Cursor <[email protected]>

* Use proxy base URL for CLI SSO form action (#28271)

Co-authored-by: shin-berri <[email protected]>
Co-authored-by: yuneng-jiang <[email protected]>

* fix(tests): add mistral/ministral-8b-2512 to cost map and backfill in conftest

Mistral rotated the 'mistral/mistral-tiny' alias to return
'ministral-8b-2512' as the response model, which was missing from the
cost map. This caused test_completion_mistral_api and
test_completion_mistral_api_modified_input to fail in
litellm.completion_cost lookup.

- Add mistral/ministral-8b-2512 entry to both the in-tree
  model_prices_and_context_window.json and the bundled
  litellm/model_prices_and_context_window_backup.json (mirrors the
  existing openrouter/mistralai/ministral-8b-2512 pricing).

- litellm.model_cost is loaded at import time from the URL pinned to
  main, so the new backup entry isn't visible at test runtime until
  it also lands on main. Backfill any entries missing from the
  remote-fetched map into litellm.model_cost in the local_testing
  conftest so cost-calculator lookups succeed on this branch.

* fix(tests): drop unnecessary del of conftest backfill loop vars

* fix(router): harden streaming fallback wrapper for bridge iterators

- FallbackResponsesStreamWrapper now uses getattr fallbacks when copying
  attributes from the source iterator. The bridge path
  (LiteLLMCompletionStreamingIterator used by Anthropic/Bedrock/Vertex)
  does not call super().__init__ and is missing response, logging_obj
  (it uses litellm_logging_obj), responses_api_provider_config,
  start_time, request_data, call_type, and _hidden_params. Previously,
  wrapper construction raised AttributeError for any streaming fallback
  on the bridge path.
- _aresponses_with_streaming_fallbacks now deep-copies the
  litellm_metadata (and metadata) dicts into fallback_kwargs. The
  primary attempt mutates this dict in place via
  _update_kwargs_with_deployment, so a shallow copy of kwargs was
  leaking primary-deployment fields (deployment, model_info, api_base)
  into the mid-stream fallback request.

Co-authored-by: Yassin Kortam <[email protected]>

* fix(router): use safe_deep_copy for fallback metadata snapshot

The ban_copy_deepcopy_kwargs CI check rejects copy.deepcopy() on any
variable whose name contains 'kwargs' (incl. fallback_kwargs). Swap
the two copy.deepcopy(fallback_kwargs[...]) calls for safe_deep_copy,
which handles non-picklable values (OTEL spans, etc.) by per-key
deepcopy with fallback to the original reference.

Co-authored-by: Yassin Kortam <[email protected]>

* test(ci): skip chronically flaky build_and_test integration tests

Both tests have been failing on every recent run of build_and_test
against this PR's HEAD (1686967, 1688402, 1689993, 1690877), and the
same two tests also fail intermittently on unrelated commits and other
branches, independent of any code change in this PR (which only touches
router fallback wrappers, the Anthropic Responses bridge, and unrelated
UI/cost-map files).

- tests.test_spend_logs.test_spend_logs: /spend/logs?request_id=...
  returns 500 even after a 20s wait for the spend log to be written.
  Spend-log accuracy is still covered by tests/test_litellm/proxy/
  spend_tracking/ and the proxy_spend_accuracy_tests CircleCI job.

- tests.test_team_members.test_add_multiple_members: /team/info?team_id=
  ... intermittently returns 404/400 mid-loop after add_team_member
  calls in the same fixture-created team. Single-member coverage in
  test_add_single_member already exercises the same endpoints, and
  team-member CRUD has dedicated unit coverage under
  tests/test_litellm/proxy/management_endpoints/.

Skipping unblocks the build_and_test job until the underlying race in
the dockerized integration setup is root-caused.

* fix: preserve explicit timeout=0 in responses API handler

Use 'timeout if timeout is not None else request_timeout' instead of
'timeout or request_timeout' so an explicit timeout=0/0.0 isn't silently
replaced by the default request_timeout.

Co-authored-by: Yassin Kortam <[email protected]>

* fix(ui): guard model_info access in pause Switch with optional chaining

* fix(ui): guard model_info access in pause Switch onChange handler

Mirror the optional-chaining guard already applied to the isPausing
check so a config-model row with a missing model_info cannot throw
when the toggle's onChange fires.

---------

Co-authored-by: TorvaldUtne <[email protected]>
Co-authored-by: oss-agent-shin <[email protected]>
Co-authored-by: shin-berri <[email protected]>
Co-authored-by: yuneng-jiang <[email protected]>
Co-authored-by: mubashir1osmani <[email protected]>
Co-authored-by: Isha <[email protected]>
Co-authored-by: cwang-otto <[email protected]>
Co-authored-by: Roman Pushkin <[email protected]>
Co-authored-by: Filippo Menghi <[email protected]>
Co-authored-by: Cursor <[email protected]>
Co-authored-by: boarder7395 <[email protected]>
Co-authored-by: mateo-berri <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: Yassin Kortam <[email protected]>
lorenzbaraldi pushed a commit to lorenzbaraldi/litellm that referenced this pull request May 21, 2026