- Update load_local_model_cost_map to use project root fallback for dev
- Keep main's validation, aliases, and source info tracking
- Remove backup JSON (purpose of this PR)
* fix(moonshot): preserve reasoning_content on Pydantic Message objects in multi-turn tool calls
The condition 'reasoning_content not in msg' doesn't work correctly for
Pydantic Message objects because they don't support the 'in' operator
like dicts do. This caused reasoning_content to be stripped from
assistant messages in multi-turn conversation history.
Changed the condition to use msg.get('reasoning_content') instead,
which works correctly for both dicts and Pydantic models.
Fixes#23765
* added newline eof
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* Update tests/test_litellm/llms/moonshot/test_moonshot_chat_transformation.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* Simplify assertions in test_moonshot_chat_transformation
Removed redundant assertions for non-assistant messages.
---------
Co-authored-by: BillionClaw <267901332+BillionClaw@users.noreply.github.com>
Co-authored-by: Aarish Alam <arishalam121@gmail.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
- Set output_cost_per_second to 0.0 (was 0.0001) for whisper-1 and
azure/whisper-1: transcription is billed on input duration only,
not output duration
- Fix cost_per_second() in openai/cost_calculation.py: change elif to if
so input_cost_per_second is evaluated independently of output_cost_per_second,
and remove the erroneous completion_cost = 0.0 assignment that masked
any previously-set output cost
- Add TestCostPerSecondArithmetic unit tests covering both cost fields,
the None-guard, and zero-duration edge case
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Non-streaming paths call _process_hidden_params_and_response_cost; streaming
assembles the full response later and skipped that, so litellm_params.metadata
lacked hidden_params (e.g. response_cost for OTEL/OpenSearch).
- Add _merge_hidden_params_from_response_into_metadata and call it from
success_handler and async_success_handler after cost is set, before
_build_standard_logging_payload.
- Unit tests for merge helper.
Tests: pytest tests/test_litellm/litellm_core_utils/test_litellm_logging.py
Made-with: Cursor
Adds a control plane capability that enables a central admin instance
to manage multiple regional worker proxies from a single UI.
Backend:
- Worker registry loaded from YAML config (worker_id, name, url)
- /.well-known/litellm-ui-config exposes is_control_plane and workers list
- /v3/login + /v3/login/exchange: opaque code exchange for cross-origin
username/password auth (JWT never in URL/logs, single-use 60s TTL)
- SSO cookie handoff with return_to → opaque code → exchange
- _validate_return_to: full origin validation (scheme+hostname+port)
- Startup warning when control_plane_url set without Redis
- Both /v3 endpoints gated behind control_plane_url config
Frontend:
- Worker selector dropdown on login page (gated behind is_control_plane)
- Cross-origin SSO code exchange handling on callback
- switchToWorkerUrl: localStorage-persisted worker URL for API calls
- useWorker hook: shared worker state management
- WorkerDropdown in navbar for switching workers
- Logout/switch clears worker state from localStorage
Tests:
- 7 tests for /v3/login + /v3/login/exchange
- 10 tests for _validate_return_to
- 2 tests for control plane discovery endpoint
- Skip short-circuit for providers that have a BaseAnthropicMessagesConfig
(bedrock, vertex_ai, azure_ai, anthropic) — they use the agentic loop
which includes a follow-up LLM synthesis step. Short-circuiting would
return raw search text instead of an LLM-synthesized answer.
- Add fallback to litellm.get_llm_provider() for custom_llm_provider
derivation when litellm_params is overwritten by kwargs.
- Add test for bedrock guard.
Addresses Greptile review comments #3 and #4.
Bedrock does not surcharge for >200k token context windows.
All *_above_200k_tokens prices should equal their base prices.
Affected models (anthropic., global., us., eu., au. regions):
- anthropic.claude-opus-4-6-v1
- anthropic.claude-sonnet-4-6
Tests were outdated after _get_and_validate_existing_key was refactored
to use prisma_client.db.litellm_verificationtoken.find_unique() and
ProxyException. Also add ProxyException handling in bulk_update_keys
error extractor so error messages aren't empty.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests were outdated after _get_and_validate_existing_key was refactored
to use prisma_client.db.litellm_verificationtoken.find_unique() instead
of prisma_client.get_data(), and to raise ProxyException instead of
HTTPException. Also fix bulk_update_keys error handler to extract
ProxyException.message (str(ProxyException) returns empty string).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace hand-rolled _extract_search_query with existing
get_last_user_message from common_utils
- Use full UUID (str(uuid.uuid4())) to match codebase convention
- Move uuid import to module level per CLAUDE.md