merge main#30740
Merged
Merged
Conversation
…ams (#29310) * fix(key_generate): allow team members to create keys on org-scoped teams When a virtual key is created for a team, enterprise logic inherits the team's organization_id onto the key (add_team_organization_id). Since the VERIA-55 org-IDOR fix, /key/generate then required the caller to be an explicit LiteLLM_OrganizationMembership member of that org, returning 403 "Caller is not a member of organization_id=<uuid>". Admins normally only add users to teams (not orgs), so self-serve key creation regressed for any user on an org-scoped team (regression since v1.84.0-rc.1). Skip the org-membership check when organization_id was inherited from the key's team (organization_id == team_table.organization_id). Team-level authorization already gates this path, so team membership is sufficient. The membership check still runs when a caller assigns an organization_id that did not come from the key's team, preserving the IDOR protection. Adds regression tests covering both the team-inherited (allowed) and foreign-org (still blocked) cases. Co-authored-by: Cursor <cursoragent@cursor.com> * test(key_generate): cover mismatched team org IDOR path on generate Add test_generate_key_foreign_org_with_mismatched_team_still_enforces_membership for the case where a team is present but request organization_id differs from team_table.organization_id. Enterprise inheritance is no-op'd in the test so the guard is exercised directly; membership validation must still run. Addresses Greptile review on #29310. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…h-lite (#29595) * test(pass-through): move Gemini pass-through tests to gemini-3.1-flash-lite gemini-2.5-flash-lite is a generation behind and is slated for discontinuation on Vertex AI no earlier than October 16, 2026, so the pass-through suite was exercising an aging model. Every reference now points at gemini-3.1-flash-lite, which is GA and already priced in the cost map so the spend-logging assertions still compute a real cost test_vertex.test.js also gains jest.retryTimes(3) to match the sibling spend tests. The CI failures were intermittent 429 RESOURCE_EXHAUSTED from Vertex quota pressure, and that file was the only one without a retry, so a single rate-limited request was failing the whole job * test(pass-through): point Vertex tests at the global endpoint for gemini-3.1-flash-lite gemini-3.1-flash-lite is not served on the Vertex us-central1 regional endpoint for the CI project, so the Vertex pass-through tests were returning a deterministic 404 "Publisher Model ... was not found or your project does not have access to it" while the Gemini API tests passed. Move the Vertex clients to the global location, which the pass-through router maps to aiplatform.googleapis.com, where the 3.1 family is served
* Fix incorrect agent API request example payload structure (#29556) * fix(otel): add litellm_metadata fallback in _get_span_context and _end_proxy_span_from_kwargs (#29427) * fix(otel): add litellm_metadata fallback in _get_span_context and _end_proxy_span_from_kwargs On /v1/messages and other LITELLM_METADATA_ROUTES, the parent OTel span is stored in litellm_params['litellm_metadata'] instead of litellm_params['metadata']. When the request body contains a native 'metadata' field (e.g. Anthropic's {"user_id": "..."}), litellm_params['metadata'] gets overwritten and the parent span is lost, producing orphan root spans with a different trace_id. Add fallback checks to litellm_metadata in: - _get_span_context(): so child spans find the correct parent - _end_proxy_span_from_kwargs(): so the proxy span gets closed Fixes: #27934 * test(otel): tighten assertions per Greptile review - test_span_context_metadata_takes_priority: assert litellm_metadata span is never accessed, proving metadata takes priority - test_span_context_no_parent_when_neither_has_span: assert both ctx and detected_span are None --------- Co-authored-by: shin-berri <shin-laptop@berri.ai> Co-authored-by: yuneng-jiang <yuneng@berri.ai> Co-authored-by: Aneesh-Fiddler <aneeshfiddler@gmail.com> Co-authored-by: Sameer Kankute <sameer@berri.ai> * fix: remove premature end-user budget check from get_end_user_object (#29420) * fix(proxy): remove premature end-user budget check from get_end_user_object Problem: - `_check_end_user_budget()` was called inside `get_end_user_object()` - This caused budget checks to run BEFORE `skip_budget_checks` could be evaluated - Zero-cost models (e.g., local vLLM) were incorrectly blocked when end-users exceeded their budget, even though they should bypass budget checks Solution: - Remove `_check_end_user_budget()` calls from `get_end_user_object()` - Budget enforcement now happens exclusively in `common_checks()` where `skip_budget_checks` context is available - `get_end_user_object()` keeps `route` as optional in function parameter for backwards compatibility and future implementation. * refactor(tests): update budget enforcement tests to reflect changes in get_end_user_object - test_get_end_user_object() verifies data fetching - test_check_end_user_budget() verifies enforcement - test_budget_enforcement_blocks_over_budget_users() integrates _check_end_user_budget() - test_resolve_end_user_reraises_budget_exceeded() is now test_resolve_end_user since no budget exceeded is thrown in get_end_user_object() * Gemini /images/generate and /images/edits billing fixes + add support for size and aspect ratio params (#29534) * Fix Gemini image config mapping * Address Gemini image config review * Format Gemini image generation transform * Fix Gemini image token usage logging * Share Gemini image request helpers * Fix Gemini Imagen model routing * Fixes as per self code review * Fixes per internal code review * Stop gating Imagen imageSize forwarding * Document Gemini image size mapping source * chore: retrigger lint * Clarify Gemini candidate count precedence * Add Inception provider (#29522) * add inception as provider (chat, fim) * linting * seperate test suite for chat and fim * fix test coverage * fix: model hub custom pricing model info (#29293) * Opik user auth key metadata extractors (#28397) * fix: enhance Opik metadata extraction to include user API key auth context fixed after refactoring to extractor logic * test: add unit tests for OPik metadata extraction logic * fix: enhance extract_opik_metadata function to prioritize metadata sources for improved accuracy * fix(ci): clarified comments and edited unit tests * test: add unit tests for OPik metadata extraction with auth and requester overrides * fix(ui): replace fixed favicon.ico with current api get /get_favicon (#29532) Signed-off-by: José Luis Di Biase <josx@interorganic.com.ar> * fix(vertex/gemini): keep tool_call reference when a text-only assistant message follows (#29561) `_gemini_convert_messages_with_history` tracks `last_message_with_tool_calls` so a following tool result can be matched back to its tool call. The assignment was inside a branch guarded by `assistant_msg.get("tool_calls", []) is not None`, which is also True for a text-only assistant message (an empty list is not None). As a result, an assistant message with no tool calls that appears between a tool call and its tool result overwrote the reference, and conversion failed with: Exception: Missing corresponding tool call for tool response message. This shape is common: a model emits a short narration/assistant message after a tool call before the tool result is appended. Only update `last_message_with_tool_calls` when the assistant message actually carries tool_calls (or a function_call). Adds a regression test. Co-authored-by: shin-berri <shin-laptop@berri.ai> Co-authored-by: yuneng-jiang <yuneng@berri.ai> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * Add 1-hour cache write pricing for EU/AU/JP Bedrock Anthropic models (#28572) * fix(thinking): handle None thinking param in is_thinking_enabled (#28598) Squash-merged by litellm-agent from Terrajlz's PR. * feat(helm): support tpl rendering in podAnnotations (#28609) Squash-merged by litellm-agent from devauxbr's PR. * Forward custom_llm_provider through the Responses API bridge (Fixes #28505) (#28575) * Forward custom_llm_provider through the Responses API bridge (Fixes #28505) When a Chat Completions request to a GPT-5.4+ model contains both `tools` and `reasoning_effort`, `completion()` auto-routes through `responses_api_bridge`. The bridge handler called `litellm.responses()` / `litellm.aresponses()` without forwarding the already-resolved `custom_llm_provider`, so the downstream call re-invoked `get_llm_provider()` with `custom_llm_provider=None` and stripped a second provider prefix from a `provider/provider/model` deployment string. For a deployment configured as `openai/openai/openai/gpt-5.5`, the bridge flow sent `openai/gpt-5.5` to the upstream API instead of the correct `openai/openai/gpt-5.5`. Upstream APIs that enforce model-name allow-lists rejected this as `key_model_access_denied`. Fix: pass the locally-resolved `custom_llm_provider` into both the sync `responses()` and async `aresponses()` calls so the downstream `_resolve_model_provider_for_responses` sees an explicit provider and skips the second prefix-strip. New regression test `tests/test_litellm/completion_extras/test_responses_bridge_provider_propagation.py` pins both call sites: each must forward `custom_llm_provider`. * fix(28505): set custom_llm_provider on request_data instead of as duplicate kwarg Greptile flagged that the previous patch passed custom_llm_provider as an explicit kwarg to responses()/aresponses() while request_data already carried it via the spread of sanitized_litellm_params, which would raise TypeError: got multiple values for keyword argument on every real bridge call. Switches to assigning request_data['custom_llm_provider'] before the call so the resolved provider wins over whatever sanitized_litellm_params spread in, without duplicating the kwarg. Updates the regression test to seed request_data with a sentinel custom_llm_provider so it actually exercises the overwrite path (the previous test mocked transform_request with a minimal dict and never hit the conflict). * chore: trigger shin-agent re-eval on retargeted staging base * chore: trigger shin-agent re-eval against updated Greptile state * Add 1-hour cache write pricing for EU/AU/JP Bedrock Anthropic models The 1-hour prompt-cache write tier (`cache_creation_input_token_cost_above_1hr`) was added to the us./global. variants of the Claude 4.5/4.6/4.7 family on Bedrock, but the eu./au./jp. cross-region inference profiles were left without it. AWS Bedrock pricing applies the same +10% regional premium across all geo profiles, so eu./au./jp. should carry the same 1-hour rates as us. (1.6x the 5-minute regional rate). Without these fields, cost tracking on EU/AU/JP Bedrock 1-hour-TTL prompt caching falls back to the 5-minute write rate and undercounts spend by ~60% for European, Australian, and Japanese tenants. Adds the 1-hour tier (and Sonnet 4.5's long-context >200K tier where AWS publishes one) to 14 regional Bedrock entries in both `model_prices_and_context_window.json` and the bundled `model_prices_and_context_window_backup.json`: - eu./au. Opus 4.6 ($11.00 / MTok) - eu./au. Opus 4.7 ($11.00 / MTok) - eu./au./jp. Sonnet 4.6 ($6.60 / MTok) - eu./au./jp. Sonnet 4.5 ($6.60 / MTok regular, $13.20 / MTok LC) - eu./au./jp. Haiku 4.5 ($2.20 / MTok) Also extends `tests/test_litellm/test_bedrock_anthropic_1hr_cache_pricing.py` with a `REGIONAL_EXPECTED` parametrized block covering all 13 new entries plus the existing 1.6x ratio invariant. Note: `eu.anthropic.claude-opus-4-5-20251101-v1:0` carries the wrong 5m rate today (base 6.25e-06 instead of regional 6.875e-06), which would break the 1.6x ratio check. It is intentionally left out of this PR so the scope stays "1-hour cache tier addition" — a separate follow-up should correct the EU 5m rates for Opus 4.5. --------- Co-authored-by: Terrajlz <info@jouleselectrictech.com> Co-authored-by: Bruno Devaux <devaux.br@gmail.com> Co-authored-by: Sameer Kankute <sameer@berri.ai> * Add 1-hour cache write pricing tier for Vertex AI Anthropic models (#28569) * fix(thinking): handle None thinking param in is_thinking_enabled (#28598) Squash-merged by litellm-agent from Terrajlz's PR. * feat(helm): support tpl rendering in podAnnotations (#28609) Squash-merged by litellm-agent from devauxbr's PR. * Forward custom_llm_provider through the Responses API bridge (Fixes #28505) (#28575) * Forward custom_llm_provider through the Responses API bridge (Fixes #28505) When a Chat Completions request to a GPT-5.4+ model contains both `tools` and `reasoning_effort`, `completion()` auto-routes through `responses_api_bridge`. The bridge handler called `litellm.responses()` / `litellm.aresponses()` without forwarding the already-resolved `custom_llm_provider`, so the downstream call re-invoked `get_llm_provider()` with `custom_llm_provider=None` and stripped a second provider prefix from a `provider/provider/model` deployment string. For a deployment configured as `openai/openai/openai/gpt-5.5`, the bridge flow sent `openai/gpt-5.5` to the upstream API instead of the correct `openai/openai/gpt-5.5`. Upstream APIs that enforce model-name allow-lists rejected this as `key_model_access_denied`. Fix: pass the locally-resolved `custom_llm_provider` into both the sync `responses()` and async `aresponses()` calls so the downstream `_resolve_model_provider_for_responses` sees an explicit provider and skips the second prefix-strip. New regression test `tests/test_litellm/completion_extras/test_responses_bridge_provider_propagation.py` pins both call sites: each must forward `custom_llm_provider`. * fix(28505): set custom_llm_provider on request_data instead of as duplicate kwarg Greptile flagged that the previous patch passed custom_llm_provider as an explicit kwarg to responses()/aresponses() while request_data already carried it via the spread of sanitized_litellm_params, which would raise TypeError: got multiple values for keyword argument on every real bridge call. Switches to assigning request_data['custom_llm_provider'] before the call so the resolved provider wins over whatever sanitized_litellm_params spread in, without duplicating the kwarg. Updates the regression test to seed request_data with a sentinel custom_llm_provider so it actually exercises the overwrite path (the previous test mocked transform_request with a minimal dict and never hit the conflict). * chore: trigger shin-agent re-eval on retargeted staging base * chore: trigger shin-agent re-eval against updated Greptile state * Add 1-hour cache write pricing tier for Vertex AI Anthropic models GCP Vertex AI publishes a separate 1-hour cache write column for the Claude family (1.6x the 5-minute write rate, matching the documented Bedrock ratio). LiteLLM's Vertex AI Anthropic entries only carry the 5-minute tier, so any request that uses `cache_control: {"ttl": "1h"}` on Vertex AI Claude is undercounted in cost tracking by ~60%. The runtime side already supports the 1-hour tier — `VertexAIAnthropicConfig` extends `AnthropicConfig`, populating `ephemeral_1h_input_tokens`, and `_calculate_cache_creation_cost` reads `cache_creation_input_token_cost_above_1hr`. Only the price registry was missing data. Adds the field to 19 vertex_ai/claude-* entries across both `model_prices_and_context_window.json` and the bundled `model_prices_and_context_window_backup.json`: - Haiku 4.5 ($1.25 -> $2.00 / MTok) - Sonnet 3.7 / 4 / 4.5 / 4.6 ($3.75 -> $6.00 / MTok) - Opus 4.5 / 4.6 / 4.7 ($6.25 -> $10.00 / MTok) - Opus 4 / 4.1 ($18.75 -> $30.00 / MTok) Adds `tests/test_litellm/test_vertex_anthropic_1hr_cache_pricing.py` mirroring the Bedrock equivalent — pins each (5m, 1h) pair per model and asserts the 1.6x ratio across the family. Fixes #27781. --------- Co-authored-by: Terrajlz <info@jouleselectrictech.com> Co-authored-by: Bruno Devaux <devaux.br@gmail.com> Co-authored-by: Sameer Kankute <sameer@berri.ai> * Fix Gemini multimodal function responses (#29325) Co-authored-by: shin-berri <shin-laptop@berri.ai> Co-authored-by: yuneng-jiang <yuneng@berri.ai> * address greptile review: add _transform_image_usage method and model-map supports_image_size flag - Add _transform_image_usage instance method to GoogleImageGenConfig that delegates to transform_gemini_image_usage, fixing the regression test - Replace hardcoded "2.5-flash" string check in supports_gemini_image_size with a get_model_info lookup on supports_image_size (default true) - Add supports_image_size: false to all gemini-2.5-flash model entries in model_prices_and_context_window.json so capability is controlled via the model map rather than embedded in code * fix test failures: schema validation, mypy type, model info plumbing, pricing test - Add supports_image_size to ModelInfoBase TypedDict so get_model_info surfaces it - Pass supports_image_size through _get_model_info_helper constructor call - Fix supports_gemini_image_size to use value is not False (None means unset, defaults to True) - Add supports_image_size to JSON schema in test_aaamodel_prices_and_context_window_json_is_valid - Correct gemini-3.1-flash-lite pricing assertions in test to match JSON values * Add Azure AI Kimi K2.6 metadata (#27052) * Add Azure AI Kimi K2.6 metadata * Scope Kimi metadata test cost map setup * fall back to substring check for models not in model_prices_and_context_window.json Models like gemini-2.5-flash-image-preview are not in the pricing JSON, so get_model_info raises. Fall back to "2.5-flash" not in model when the JSON has no explicit supports_image_size entry for the model. * fix(inception): don't forward global litellm.api_key to Inception FIM Match the Inception chat config: resolve only an Inception-specific key (param, litellm.inception_key, or INCEPTION_API_KEY) for the text-completion FIM path. The global litellm.api_key (often an OpenAI key) was both leaking to api.inceptionlabs.ai and taking precedence over the configured Inception key when set. * fix(auth): enforce end-user budget on custom-auth path that skips common_checks get_end_user_object() no longer raises BudgetExceededError, so custom-auth deployments with custom_auth_run_common_checks unset (which skip the centralized common_checks gate) stopped enforcing the end-user budget, letting an over-budget end user keep making requests. Re-enforce the budget in _run_post_custom_auth_checks on that path. --------- Signed-off-by: José Luis Di Biase <josx@interorganic.com.ar> Co-authored-by: Isha <72744901+IshaMeera@users.noreply.github.com> Co-authored-by: aneeshsangvikar <aneeshsangvikar@fiddler.ai> Co-authored-by: shin-berri <shin-laptop@berri.ai> Co-authored-by: yuneng-jiang <yuneng@berri.ai> Co-authored-by: Aneesh-Fiddler <aneeshfiddler@gmail.com> Co-authored-by: Suleiman Elkhoury <108065141+suleimanelkhoury@users.noreply.github.com> Co-authored-by: Dmitriy Alergant <93501479+DmitriyAlergant@users.noreply.github.com> Co-authored-by: Yanis Miraoui <yanis.miraoui19@imperial.ac.uk> Co-authored-by: Lovro Seder <vrovro@gmail.com> Co-authored-by: Thomas Mildner <12685945+Thomas-Mildner@users.noreply.github.com> Co-authored-by: José Luis Di Biase <josx@interorganic.com.ar> Co-authored-by: Lai Quang Huy <64073540+1qh@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Filippo Menghi <113345637+Cyberfilo@users.noreply.github.com> Co-authored-by: Terrajlz <info@jouleselectrictech.com> Co-authored-by: Bruno Devaux <devaux.br@gmail.com> Co-authored-by: ZHONG Ziwen <67355585+zzw-math@users.noreply.github.com> Co-authored-by: Emerson Gomes <emerson.gomes@thalesgroup.com> Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
* Fix error code and context id injection bug * Add support for all A2A methods * Add logging * address greptile review: relay upstream JSON-RPC errors, move _PASCAL_TO_WIRE to module level, add error path tests * fix(a2a): run pre_call_hook for tasks/resubscribe SSE path to enforce guardrails tasks/resubscribe was returning the raw SSE stream without calling proxy_logging_obj.pre_call_hook, silently bypassing any guardrails configured on the agent. This patch calls pre_call_hook before streaming begins and wires post_call_failure_hook into the SSE generator so errors are logged. Adds a regression test verifying the hook is called. * fix(a2a): use get_async_httpx_client instead of creating httpx clients per request Creating httpx.AsyncClient instances per-request adds ~500ms latency. Switch _forward_jsonrpc and _forward_jsonrpc_sse to use the shared client from get_async_httpx_client(httpxSpecialProvider.A2A). * fix(a2a): forward caller identity headers on task ops; validate push notification URL Two security fixes for task management methods: 1. All task operations (tasks/get, tasks/list, tasks/cancel, tasks/resubscribe, push notification config methods) now forward X-LiteLLM-User-Id and X-LiteLLM-Team-Id headers to the upstream agent, so the agent can scope task access to the authenticated caller. 2. tasks/pushNotificationConfig/set validates the callback URL before forwarding: requires HTTPS and rejects private/loopback/reserved IP ranges and localhost hostnames to prevent SSRF. * Fix A2A task hook and push URL handling * fix(a2a): fix mypy type errors for request_id and header_name dict key types * Fix A2A request id and params forwarding * Forward trace IDs for A2A task calls * fix(a2a): strip client-forwarded X-LiteLLM-* headers before applying authenticated identity A client could send x-a2a-<agent>-x-litellm-user-id in their request and have it forwarded to the upstream agent as an authenticated identity header. Fix: sanitize any X-LiteLLM-* headers from agent_extra_headers before merging, then apply the authenticated identity headers last so they always override client-supplied values. * Fix A2A SSE fallback JSON-RPC error code * Fix A2A SSE error id backfill * fix(a2a): validate both push notification url fields to close SSRF bypass * fix(a2a): widen request_id annotation to match JSON-RPC id call sites * fix(a2a): run post-call streaming hook for tasks/resubscribe so agent guardrails apply tasks/resubscribe returned the raw upstream SSE stream without routing events through the post-call streaming hook, so output guardrails configured on the agent were silently skipped for streaming task subscriptions while every other task method and message/stream applied them. Parse upstream JSON-RPC SSE events and feed them through async_streaming_data_generator, matching message/stream, so guardrails inspect the streamed task content. Adds a regression test that fails when the streamed events bypass the guardrail hook. --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
…y streaming chunks (#29600) * fix(anthropic/adapter): open thinking block for reasoning_content-only streaming chunks The /v1/messages streaming content-block classifier (_translate_streaming_openai_chunk_to_anthropic_content_block) only recognized thinking_blocks. OpenAI-compatible reasoning backends (vLLM/SGLang reasoning parsers: DeepSeek-R1, Qwen3, gpt-oss, ...) populate reasoning_content with thinking_blocks=None, so the classifier fell through to a text block. The delta translator already emits thinking_delta for reasoning_content, so those deltas landed inside a text block and Anthropic streaming clients (Claude Code, SDK .stream()) silently dropped the chain-of-thought. Mirror the reasoning_content fallback already present in the non-stream translator and the streaming delta translator so the classifier opens a thinking block. Adds a focused regression test. * fix(anthropic/adapter): reach reasoning_content branch when thinking_blocks attr is absent Delta deletes the thinking_blocks attribute when unset, so the prior nested check was unreachable for reasoning-only chunks (vLLM/SGLang). Make it a sibling elif so the content block is classified as thinking. * test(proxy): stop component-allowlist test leaking DATABASE_URL into xdist peers The component-allowlist test pins throwaway DATABASE_URL/LITELLM_MASTER_KEY values at import time via os.environ so importing proxy_server doesn't need a live database. Those values persisted for the whole pytest-xdist worker, so a sibling test sharing the worker (test_key_rotation_e2e's DB-backed E2E case) saw the leaked sqlite DATABASE_URL, treated it as an available database instead of skipping, and the Prisma engine rejected the non-postgres URL (P1012 -> httpx.ConnectError). Restore the prior environment after the import so the throwaway values never escape the module. --------- Co-authored-by: Tai An <antai12232931@outlook.com>
* ci: reproduce default-Windows wheel install to guard MAX_PATH The existing using_litellm_on_windows job installs the project with `uv sync`, an editable source install that never copies package files into a deep site-packages path, so it cannot see the 260-char MAX_PATH overflow that breaks `pip install litellm` on default Windows. The content-filter benchmark fixtures have hit that limit three times (#21941, #22039, #29536), each caught only after release. This adds a guard to the same job that builds the wheel and installs it the way an end user would: into a venv whose site-packages prefix is padded to a realistic worst-case Windows length (~100 chars), then asserts the install completes and litellm imports. Any packaged path long enough to bust MAX_PATH at that prefix is reported up front, so the check is deterministic regardless of the runner's long-path setting, while the real install also covers failure modes a length heuristic cannot (half-unpacked packages, reserved names, case collisions). This commit is the guard only; on the current tree it correctly fails because nine fixtures still exceed the limit. The rename that brings them back under it follows on this branch. * fix(packaging): shorten content-filter benchmark fixtures under MAX_PATH The 10 content-filter benchmark result fixtures used the legacy block_{topic}_-_contentfilter_({yaml}).json naming, up to 176 chars inside the wheel, which busts the Windows 260-char MAX_PATH limit once extracted under a realistic site-packages prefix and aborts `pip install litellm` on default Windows. Rename them to the short {topic}_cf.json scheme that _save_confusion_results already emits today (it splits the label on the em-dash and writes f"{topic}_cf"), matching the insults_cf.json and investment_cf.json files fixed earlier. Re-running the eval suite now regenerates these same short names rather than recreating the long ones. This drops the longest packaged path from 176 to 128, so the guard added in the previous commit goes from red to green with a 32-char margin. * test(windows): tidy MAX_PATH guard per review Close the wheel zip via a context manager rather than leaning on refcount collection, and select the wheel under dist/ by newest mtime so a stale artifact from an earlier build cannot be tested instead of the one just produced. Also pin down the venv-depth formula with a short note: the +2 is the separator joining the venv root to "Lib" plus the trailing separator before the entry, which lands the simulated site-packages prefix at exactly 100 chars.
… reject it (Haiku 4.5) (#29585) * fix(vertex): strip output_config.effort for models that reject it Haiku 4.5 on Vertex AI does not support output_config.effort and 400s with "output_config.effort: Extra inputs are not permitted". PR #27074 emptied VERTEX_UNSUPPORTED_OUTPUT_CONFIG_KEYS so effort would forward for Opus/Sonnet 4.6+, but that made the strip unconditional across every Vertex Anthropic model, including ones that don't support it. Claude Code injects effort into its default Messages payload, so `claude --model claude-haiku-4.5` started failing. Make the sanitizer model-aware: drop output_config.effort for models that don't advertise output_config support (or any reasoning effort level) while forwarding it for those that do. The fix covers both the chat-completion and Messages pass-through transformation paths since they share the helper. * chore(vertex): log at debug when dropping unsupported output_config.effort Operators pointing an unregistered Vertex Claude alias that does support effort would otherwise see it stripped with no signal. Debug level keeps it out of normal logs since Claude Code sends effort on every request.
* Add support for websocket via codex * Add model alias and creds support * fix: skip cost tracking for WS session wrapper call types The @client decorator on _aresponses_websocket fires async_success_handler with result=None after the session ends. This triggered cost tracking errors because standard_logging_object is never built for None results. Per-turn costs are correctly tracked by individual litellm.aresponses calls inside the session. The outer session-level logging obj should not attempt cost tracking. Fix: skip _aresponses_websocket and _arealtime call types in deployment_callback_on_success, RouterBudgetLimiting.async_log_success_event, and _PROXY_track_cost_callback. * fix: address Greptile review comments Fix JSON injection: use json.dumps instead of f-string interpolation for model name in WS body. Add 30s timeout for first WS frame to prevent unbounded connection resource tie-up. Restore per-event model override in streaming_iterator; fall back to connection-level model when event omits it. Strengthen regression test: inject alias into kwargs via _update_kwargs_with_deployment mock so the test would fail on un-fixed code. * fix: handle nested response.create format in first-frame model extraction When ?model= is omitted, the first WS frame can carry the model in either flat format (first_event["model"]) or nested format (first_event["response"]["model"]). The flat-only check would silently reject clients using the nested wire format. Mirrors the same two-format logic in _build_base_call_kwargs. * fix: don't force connection-level custom_llm_provider on per-event model overrides If a client sends a different model per response.create turn, litellm needs to re-resolve the provider from that model string. Forcing the connection-level custom_llm_provider would silently route the request to the wrong backend. Only inject custom_llm_provider when the per-event model matches the connection-level model. * refactor: extract WS model extraction into testable function Pull the flat/nested model extraction into _extract_model_from_first_ws_event so tests import and exercise the real function rather than a copy. * fix: compare providers not full model strings in _inject_credentials The model == self.model guard was too strict: same-provider model variants (e.g., vertex_ai/gemini-2.0 -> vertex_ai/gemini-1.5 on one connection) would lose custom_llm_provider, breaking routing when a custom api_base is in use. Compare the provider extracted by get_llm_provider instead, so same-provider variants still inherit the connection-level provider while cross-provider overrides let litellm re-resolve. * style: black formatting * refactor: extract first-frame model resolution to fix PLR0915 (too many statements) * Fix responses WebSocket first-frame validation * fix: classify WS first-frame read errors and clarify cost-skip log Distinguish client disconnects from server errors when reading the responses WebSocket first frame, make the cost-tracking skip log message accurate for session wrappers (which do carry a model), and resolve the connection-level provider once per session instead of on every response.create event. * test: cover WS first-frame read errors and same-provider credential injection Adds regression tests for the still-uncovered responses WebSocket paths: the timeout, invalid-JSON and missing-model branches of _read_ws_model_from_first_frame, plus the provider comparison in ManagedResponsesWebSocketHandler._same_provider and _inject_credentials (same-provider model variants keep the connection provider; cross-provider models re-resolve). * fix(responses-ws): fall back to explicit custom_llm_provider when connection model is unresolvable When a WebSocket session is opened with a custom deployment alias that litellm cannot resolve to a provider, _connection_provider was None, so _same_provider returned False for every resolvable per-event model and the connection-level custom_llm_provider was dropped. Use the explicitly-set custom_llm_provider as the connection provider in that case so same-provider per-event models still inherit it while genuinely cross-provider models continue to re-resolve. --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
…t, passthrough I/O, session/user, multimodal, cache tokens (#28800) * feat(arize): enrich OpenInference attributes for better span rendering Pure rendering enhancements to the Arize / Arize Phoenix integration. No existing attribute keys or values are removed or overwritten; every new emit is independently try/except-wrapped and fires only when its source data is present so existing behavior is preserved. What this adds - Coerce non-dict response objects (e.g. httpx.Response from passthrough routes) via JSON decode so id/model/usage extraction stops crashing with "'Response' object has no attribute 'get'". Dicts and Pydantic objects with .get pass through unchanged. - Set OPENINFERENCE_SPAN_KIND defensively early so a downstream failure can't blank the kind; the original late write (incl. TOOL upgrade) is preserved. - Add "passthrough" keyword to _infer_open_inference_span_kind so allm_passthrough_route / llm_passthrough_route resolve to LLM instead of UNKNOWN. - Emit cache token breakdown: LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_READ / _CACHE_WRITE / _AUDIO. Sources covered: OpenAI prompt_tokens_details and Anthropic / Bedrock cache_{read,creation}_input_tokens. - Render assistant tool_calls on both input and output messages via MESSAGE_TOOL_CALLS.* (Pydantic-aware, handles ModelResponse choices). Tool-result input messages also get MESSAGE_TOOL_CALL_ID and MESSAGE_NAME. - Render multimodal list-shaped content via MESSAGE_CONTENTS.* (OpenAI image_url, Anthropic source.{media_type,data} as data: URI). Legacy MESSAGE_CONTENT write is unchanged. - Emit SESSION_ID (end_user_id / trace_id), USER_ID (only when not already set by optional_params.user or model_params.user), and litellm.{team_id,team_alias,key_alias} from StandardLoggingPayload metadata. - Emit llm.response.cost as float from StandardLoggingPayload.response_cost. - Bedrock / Anthropic passthrough normalization: extract input from additional_args.complete_input_dict and output from the coerced provider response so INPUT_VALUE / OUTPUT_VALUE / LLM_INPUT_MESSAGES / LLM_OUTPUT_MESSAGES are populated. Only runs when call_type contains "passthrough" / "pass_through". Tests - 15 new unit tests covering each addition plus explicit regression guards (USER_ID overwrite protection, passthrough normalizer scope, coerce identity for dicts/.get-bearing objects, no spurious cache emits). - Existing test_arize_set_attributes count bumped from 26 to 27 to account for the additional defensive span.kind write (same value, written twice). - tests/test_litellm/integrations/arize/: 70 passed (55 baseline + 15 new). tests/test_litellm/integrations/test_opentelemetry.py: 221 passed. Co-authored-by: Cursor <cursoragent@cursor.com> * refactor(arize): collapse additive try/except blocks into _safe_emit helper The additive attribute emitters all share the same shape: run a callable, swallow any exception to debug log so it cannot blank the span. Hoisting that pattern into a single _safe_emit(label, fn, *args, **kwargs) helper removes 5 repeated try/except blocks. Behavior unchanged; arize test suite still passes (70/70). Co-authored-by: Cursor <cursoragent@cursor.com> * fix(arize): emit cost under canonical llm.cost.total key Arize's "Total Cost" column reads the OpenInference-standard `llm.cost.total` attribute. The previous custom `llm.response.cost` key never surfaced in the trace list. Now emits both keys (canonical + legacy) so renderers + any existing consumers both work. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(arize): keep span.kind=LLM for tool-using completions + render tool_calls in Output A chat completion that passes `tools=[...]` or returns `tool_calls` is still an LLM call per the OpenInference spec — TOOL is reserved for actual tool execution. The previous override demoted these to TOOL, breaking Arize's LLM-scoped dashboards/evals and skewing token/cost analytics for any tool-using traffic. Additionally, when an assistant response had no text content but did request tool calls, `output.value` was set to the empty string so Arize's "Output" pane rendered blank. Now serializes the tool_calls into a compact JSON summary in `output.value` (the structured `MESSAGE_TOOL_CALLS.*` attributes are still emitted unchanged). Cleanups: - extract `_get_tool_calls` and `_normalize_tool_call` helpers, deduplicating the dict-vs-Pydantic + function-dict logic across `_set_choice_outputs`, `_emit_message_tool_calls`, and the new `_summarize_tool_calls_for_output`. - drop redundant late `OPENINFERENCE_SPAN_KIND` write — the defensive early write is now the single source of truth. - remove a dead local re-import of `MessageAttributes`/`SpanAttributes`. Tests: 73 pass (added regression guard asserting span.kind stays LLM for completions that pass tools AND return tool_calls; existing call_count assertion restored to 26). Co-authored-by: Cursor <cursoragent@cursor.com> * chore(arize): tighten cleanup — fold _get_tool_calls into _safe_get Two tiny cleanups, no behavior change: - collapse `_get_tool_calls` to use `_safe_get`, removing a 7-line hand-rolled dict-vs-attribute fallback that duplicated existing logic. - trim the `_set_choice_outputs` tool-call summary comment from 4 lines to 2 (was over-explaining). Co-authored-by: Cursor <cursoragent@cursor.com> * fix(arize): address Greptile review — drop session_id=trace_id fallback, remove dead code, fix Black Three Greptile-flagged issues + the Black formatting CI failure. 1. SESSION_ID no longer falls back to trace_id. Previously every span without an explicit `user_api_key_end_user_id` would have its session.id set to the per-request trace_id, which creates one distinct "session" per request and breaks Arize's Session-grouping analytics. Now SESSION_ID is emitted only when an explicit end-user identifier exists, and the trace_id is emitted under its own `litellm.trace_id` key so spans remain filterable by trace. 2. Removed dead `ArizeOTELAttributes.set_response_output_messages` override. Confirmed zero callers in the entire repo (the live path is `_set_choice_outputs` via `_set_response_attributes`). The override was preexisting dead code, but the expansion of `_set_choice_outputs` in this PR made the divergence misleading. 3. Removed permanently-dead first branch in cache_write detection. `_safe_get(prompt_token_details, "cache_creation_tokens")` looks for a key that neither OpenAI's `prompt_tokens_details` nor Anthropic's payload ever exposes. Now reads straight off `usage` for `cache_creation_input_tokens`. 4. Reformatted both files under Black 26.3.1 (the version CI uses via `uv sync --frozen`). Local previously used 24.10.0. Tests: 74/74 pass in the arize suite (added `test_arize_does_not_use_trace_id_as_session_id_fallback`). Combined arize + opentelemetry suite: 295/295 pass. End-to-end verified live: tool-call still emits `span.kind=LLM` and JSON tool_calls in `output.value`; `session.id` is now correctly unset when no end_user_id is provided; `litellm.trace_id` is populated; Bedrock passthrough input/output unchanged. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(arize): gate passthrough prompt export on message redaction - Skip the complete_input_dict bridge in _maybe_normalize_passthrough when should_redact_message_logging() is true, so enabling redaction no longer leaks raw passthrough prompts into Arize (Veria security finding). - Split passthrough input/output rendering into helpers to satisfy PLR0915. - Remove dead call_type assignment (F841). Validated live against a Bedrock passthrough proxy exporting to Arize: non-redacted renders the real prompt on litellm_request; global turn_off_message_logging yields input.value=redacted-by-litellm with the raw_gen_ai_request child span suppressed and no SSN/marker leakage. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
* fix duplicate cost callbacks for anthropic streaming pass-through Two bugs caused _PROXY_track_cost_callback to see stream=True + complete_streaming_response=None on every streaming pass-through request, making the dedup guard in dispatch_success_handlers permanently inactive: 1. pass_through_endpoints.py created the Logging object with stream=False for all requests. _is_assembled_stream_success short-circuits on self.stream is not True, so has_dispatched_final_stream_success was never set and any second dispatch went through unchecked. Fix: set logging_obj.stream = True after stream detection. 2. _create_anthropic_response_logging_payload set complete_streaming_response inside the try block after litellm.completion_cost(), so a pricing error caused an early return without setting it on model_call_details. Fix: set complete_streaming_response before the try block. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix stream * add stream to logging obj * test(pass_through): give mock logging object a real model_call_details dict The anthropic passthrough logging payload now records the assembled response on model_call_details before cost calculation, which requires model_call_details to support item assignment. In production it is always a dict; the existing unit test stubbed the logging object with a bare Mock whose attribute is not subscriptable, so the new assignment raised TypeError. Use a real dict to match the production logging object. * test(pass_through): cover streaming logging-obj stream flag The streaming branch of pass_through_request that marks the logging object as streaming (logging_obj.stream and model_call_details["stream"]) had no unit coverage, so the patch coverage gate flagged it. Add a regression test that drives a streaming pass-through request through pass_through_request and asserts the logging object is flagged as a stream before dispatch. * test(pass_through): cover SSE-response stream flag fallback branch The auto-detected streaming branch of pass_through_request (when a request that was not flagged as streaming returns a text/event-stream response) sets logging_obj.stream and model_call_details["stream"] but had no unit coverage, so the codecov patch gate failed at 60%. Drive a non-streaming pass-through request whose upstream response is SSE through pass_through_request and assert the logging object is flagged as a stream before dispatch. * fix(pass_through): gate complete_streaming_response on stream flag perform_redaction only scrubs complete_streaming_response when model_call_details["stream"] is True. Setting it unconditionally for non-streaming Anthropic pass-through responses left the assembled response unredacted in model_call_details, which is handed to logging callbacks as kwargs when message logging is disabled. Only record it for actual streaming responses so redaction always applies. --------- Co-authored-by: mubashir1osmani <mubashir.osmani777@gmail.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
#29608) * fix(ci): keep coverage rename green when a parallel node runs no tests local_testing_part1 and local_testing_part2 run with parallelism 4. When CircleCI reruns only the failed tests, the failed test lands on a single node and the other nodes receive an empty bucket, so pytest never writes coverage.xml or .coverage. The unguarded "mv coverage.xml ..." then exits 1 and turns the whole job red even though the rerun passed; the next persist_to_workspace step would fail the same way on the missing paths. Guard the rename so a node with no coverage emits empty placeholders instead. coverage combine tolerates the empty files, so the downstream upload-coverage job keeps the real nodes' data intact. * fix(ci): pre-create test-results in litellm_router_testing for empty-bucket reruns litellm_router_testing also runs with parallelism 4. On a rerun of only the failed tests, a node can receive no tests, so the test command never creates test-results and the final store_test_results step can fail on the missing path. Pre-create the directory up front, matching what local_testing_part1 and part2 already do and CircleCI's own guidance for parallel reruns. * test(openai): retry wildcard chat completion on transient OpenAI 500 build_and_test reddened on test_openai_wildcard_chat_completion when the real gpt-3.5-turbo-0125 call returned an OpenAI 500 ("The server had an error while processing your request"). The base branch passed the same call concurrently, so the 500 is an intermittent OpenAI server error, not a regression. Add the same pytest-retry marker the sibling real-call tests in this file already use so a transient upstream 500 no longer fails CI.
* Fix remaining VCR live-call leaks * test(vcr): dedupe live-test helpers and drop spurious kwargs Extract the duplicated isVertexQuotaError/runVertexRequestOrSkip Vertex quota-skip helpers into tests/pass_through_tests/vertex_test_helpers.js and the duplicated _skip_live_prompt_caching_test guard into tests/_live_test_helpers.py so each lives in one place. In test_aarun_thread_litellm, build a separate message_data carrying role/content for add_message and a thread_data without them for run_thread/run_thread_stream/get_messages, which no longer receive the spurious message fields. * test(overhead): assert mock transport is exercised in non-streaming and stream tests
…ng for team keys (#29612) Non-admin users creating a team key through the UI were rejected with "max_budget cannot exceed the caller's own max_budget (0.25)". The request is authenticated by a UI/CLI session token whose max_budget is the per-session chat spend cap (max_ui_session_budget, default $0.25), and the delegated-authority budget ceiling (GHSA-q775-qw9r-2r4g) treated that cap as a delegation limit. Skip the ceiling only when a session token creates a team key (data.team_id set); that key's spend is bounded by the team budget at request time. Personal keys and every other non-admin caller keep the ceiling, so a session token cannot mint an arbitrary-budget personal key.
…to 16 (#29626) ESLint 9 defaults to flat config and eslint-config-next was pinned at 15 while Next is on 16, so eslint only ran with ESLINT_USE_FLAT_CONFIG=false and next lint is gone on Next 16. Replace .eslintrc.json with a native flat eslint.config.mjs (config-next 16 ships flat configs, so no FlatCompat shim is needed), bump eslint-config-next to 16.2.6, add @eslint/js and typescript-eslint as explicit devDeps for the recommended rule sets, and point the lint script at eslint directly. This only makes eslint runnable on modern tooling; it does not wire it into CI. The same rules carry over (next/core-web-vitals, eslint and typescript-eslint recommended, prettier, unused-imports)
…aller-supplied team_id (#29641) #29612 exempts UI/CLI session tokens from the key budget ceiling when they create a team key, keyed on data.team_id. That value is read after the default_key_generate_params loop can populate team_id, so on deployments that set default_key_generate_params.team_id a request the caller did not scope to a team is treated as a team key and skips the ceiling. Capture _requested_team_id before defaults run and key the exemption off it, mirroring how _requested_max_budget is already captured. Requests the caller did not scope to a team keep the ceiling.
Streaming responses from the proxy (/chat/completions, /v1/messages, /v1/responses, assistants) all return through create_response() but never sent the headers that tell an intermediary reverse proxy not to buffer the SSE stream. nginx with the default proxy_buffering, k8s ingress-nginx, and Envoy/Istio sidecars therefore hold the whole stream and release it in one batch, which looks like a broken/buffered stream to the client even though litellm is yielding chunks incrementally. Add Cache-Control: no-cache and X-Accel-Buffering: no to every StreamingResponse create_response() returns, matching what the proxy already does for its own usage/policy SSE endpoints. Fixes #28384.
…#27764) * fix(mcp): gate /public/mcp_hub strictly on litellm.public_mcp_servers * fix(mcp): add public_mcp_hub_strict_whitelist flag (default True) for migration
#29633) * ci(ui): add frontend-lint job enforcing prettier and eslint on changed files Lints only the files a PR adds or modifies under ui/litellm-dashboard, so new and touched code must be prettier-clean and eslint-clean while the existing tree is grandfathered. Skips cleanly when a PR touches no lintable UI files. This lets us adopt the formatters incrementally without a repo-wide reformat * ci(ui): write frontend-lint file lists to $RUNNER_TEMP Keep the prettier/eslint changed-file lists out of the checkout dir so they cannot collide with a future source file of the same name * lint(ui): baseline existing eslint findings so only new ones block Capture the current error-level eslint findings (318 across 183 files) in a committed suppressions baseline via eslint --suppress-all. Every rule stays at its error severity, so any newly introduced violation fails the frontend-lint gate, while the existing tree is grandfathered; touching a legacy file never forces fixing its pre-existing issues. CI runs eslint with --pass-on-unpruned-suppressions so that fixing a baselined issue does not fail on a now-stale suppression, and the generated baseline is prettier-ignored since eslint owns its format. Burn the baseline down over time with eslint --prune-suppressions * lint(ui): enforce a count budget for explicit any Make @typescript-eslint/no-explicit-any a warning and cap the total instead of hard-blocking each new one. A frontend-lint step counts the repo-wide explicit any and fails only when it exceeds the committed budget in eslint-any-budget.json. max starts at 2031, ten above the current 2021, so the next ten land as warnings and the build fails once that headroom is gone. Lower max over time toward target to ratchet the count down. New anys still surface as warnings on changed files via the normal eslint step * lint(ui): enable zero-cost rules no-var, no-self-assign, react/no-danger These have no existing violations, so they need no baseline; turning them on purely blocks new instances. react/no-danger guards against new dangerouslySetInnerHTML (XSS), no-var enforces let/const, and no-self-assign catches self-assignment typos. no-debugger is already enforced by the recommended preset * lint(ui): add baselined complexity rules Enable complexity:20, max-depth:4, max-params:4, max-nested-callbacks:4, with thresholds set near the codebase p99 so only genuine outliers are flagged. The 272 existing over-threshold functions are grandfathered in the suppressions baseline; new over-threshold functions block. Lower the thresholds over time to ratchet complexity down. max-lines-per-function is intentionally left off since React components are legitimately long * lint(ui): ban new raw fetch, standardize on React Query Add a no-restricted-syntax rule flagging bare fetch() calls, pointing contributors at React Query (@tanstack/react-query). The rule is not exempted anywhere, including the already-bloated networking.tsx, so all 331 existing fetch calls are grandfathered but no new ones can be added there or elsewhere. New data access goes through React Query, and the networking layer can be migrated out and pruned from the baseline over time * lint(ui): ban new @tremor/react imports Add a no-restricted-imports rule flagging imports from @tremor/react so tremor is phased out rather than spread further. The 232 existing tremor imports are grandfathered in the baseline; new ones block and point at antd. Migrate components off tremor and prune the baseline over time * lint(ui): widen explicit-any budget headroom to 2040 Raise max from 2031 to 2040, giving ~19 of slack over the current 2021 instead of 10 * style(ui): prettier-format eslint.config.mjs The frontend-lint gate flagged its own config file. Format it so the prettier check on this PR's changed files passes * lint(ui): soften complexity and max-depth to warnings These two are smell metrics with arbitrary thresholds where a legit new function can trip them, so make them advisory rather than hard-blocking. They drop out of the baseline (now 963). max-params, max-nested-callbacks, and the react-hooks rules stay strict since those are clear-cut * lint(ui): move complexity and max-depth to the count-budget pattern Generalize the explicit-any budget into a shared lint-budget mechanism: eslint-budgets.json maps a rule to {max, target} and check-lint-budgets.mjs counts each across the repo and fails when a count exceeds its max. complexity (129, max 140) and max-depth (61, max 70) now use the same slack-plus-counter model as explicit-any (2021, max 2040): they warn per-file and the build only fails if the repo-wide total crosses the ceiling. Lower each max toward its target over time * docs(ui): note pruning the eslint suppressions baseline when fixing lint debt
…ema (#29582) * fix(gemini): keep googleSearch with server-side tools and googleMaps JSON schema Wire include_server_side_tool_invocations through completion() so mixed google_search and function tools are not dropped on Gemini 3+. Rewrite generationConfig to responseFormat when googleMaps is used with JSON schema. Fixes #27479 Fixes #29451 Co-authored-by: Cursor <cursoragent@cursor.com> * address greptile review feedback (greploop iteration 1) * style: fix black formatting in main.py for py312 compat * Fix Gemini Google Maps extra_body JSON rewrite --------- Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(proxy): match passthrough registry routes bare-to-bare with SERVER_ROOT_PATH After #28547, get_request_route strips the deployment prefix while registry lookup still re-inflated stored paths via SERVER_ROOT_PATH, causing 404s under paths like /llmproxy/ml. Compare normalized bare routes in both is_registered_pass_through_route and get_registered_pass_through_route. Co-authored-by: Cursor <cursoragent@cursor.com> * test(proxy): patch utils.get_server_root_path in passthrough auth tests After removing get_server_root_path from pass_through_endpoints, route and JWT tests must mock litellm.proxy.utils where normalization reads it. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…ity (#29662) * fix(gemini-realtime): use GA event names for Pipecat 1.3.x compatibility Pipecat v1.3.0 adopted the OpenAI Realtime API GA event naming: response.audio.delta -> response.output_audio.delta response.text.delta -> response.output_text.delta response.audio.done -> response.output_audio.done response.text.done -> response.output_text.done The proxy was still emitting the old beta names; Pipecat's `parse_server_event` raises "Unimplemented server event type" for any unknown type, which killed the receive task handler and broke audio playback and tool-call delivery. Also: - conversation.item.created -> conversation.item.added (already handled) - client audio is buffered until backend setupComplete in deferred mode - call_id fallback UUID when Gemini returns empty id - status_details / token detail fields added to Pydantic-strict events The _GA_TO_BETA_EVENT_TYPES map in RealTimeStreaming already translates GA names back to beta for clients that opt in with the openai-beta header, so legacy clients are unaffected. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(gemini-realtime): address greptile review comments - emit outputTranscription as response.output_audio_transcript.delta instead of suppressing it; GA_TO_BETA map handles translation for legacy clients - cap pre-setup audio buffer at 200 frames to prevent memory exhaustion; log a warning when the limit is hit and additional frames are dropped - log remaining dropped message count on flush error Co-authored-by: Cursor <cursoragent@cursor.com> * fix(gemini-realtime): address veria review comments - remove unused OpenAIRealtimeConversationItemCreated import - fix guardrail bypass: semantic_vad early-return now preserves create_response when set so a guardrail-injected create_response:false is not silently dropped - add per-connection 10 MB byte cap alongside the 200-frame count cap for the pre-setup audio buffer to prevent memory exhaustion Co-authored-by: Cursor <cursoragent@cursor.com> * fix(gemini-realtime): fix mypy arg-type on _finalize_gemini_live_setup setup parameter typed as BidiGenerateContentSetup to match the TypedDict passed at both call sites; was dict which mypy rejected. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(gemini-realtime): widen _finalize_gemini_live_setup to Dict[str, Any] BidiGenerateContentSetup (TypedDict) is a subtype of Dict[str,Any] so both call sites (one passing a plain dict, one passing the TypedDict) satisfy mypy. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(gemini-realtime): cast BidiGenerateContentSetup to Dict at _finalize call site mypy rejects TypedDict as dict[str, Any] argument; cast at the call site where follow_up_setup is BidiGenerateContentSetup to satisfy the checker. Co-authored-by: Cursor <cursoragent@cursor.com> * Fix Gemini realtime beta compatibility * Fix deferred Gemini setup audio ordering * fix: preserve Gemini audio transcript ids * fix(realtime): cap pre-setup client buffer on all append paths Route every append to the deferred-setup pending buffer through the per-connection message/byte caps. Previously only the audio-buffer fast path enforced the caps; once one frame was buffered, a client that withheld session.update could stream arbitrary frames into _pending_messages_until_setup unbounded and exhaust proxy memory. * style(gemini-realtime): apply black formatting to transformation.py * fix(gemini-realtime): log beta-translation fallback and name native-audio marker Surface the previously swallowed exception in _send_event_to_client so a failed GA->beta translation is observable instead of silently forwarding the untranslated event. Extract the native-audio model substring used by _finalize_gemini_live_setup into a named constant documenting why speechConfig is dropped on those setups. --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
* fix(azure): apply api_version fallback chain to image edit URL
`AzureImageEditConfig.get_complete_url` only read `api_version` from
`litellm_params`. When callers configured it via `litellm.api_version`
or `AZURE_API_VERSION`, the constructed URL had no `?api-version=` and
Azure responded `404 Resource not found`.
Apply the same fallback chain the Azure chat path already uses in
`common_utils.py`:
litellm_params > litellm.api_version > AZURE_API_VERSION env >
litellm.AZURE_DEFAULT_API_VERSION
Adds 5 unit tests pinning each layer of the chain plus a regression
guard for `api_base` that already carries `?api-version=`.
* feat(mcp): core sampling and elicitation flow with security hardening
- Add sampling_handler.py: full MCP sampling/createMessage flow with
model selection (hint-based + priority-based), auth enforcement,
budget checks, route restriction gates, and tag policy pre-auth
- Add elicitation_handler.py: MCP elicitation/create relay with
downstream client capability detection
- Wire sampling/elicitation callbacks in mcp_server_manager.py
gated behind allow_sampling/allow_elicitation config flags
- Add allow_sampling/allow_elicitation fields to MCPServer type
- Fix session lock deadlock: skip lock for JSON-RPC response POSTs
(elicitation/sampling replies) with truncated-body heuristic
- Extend client.py with sampling_callback and elicitation_callback
- Security: RouteChecks gate, tag-budget bypass fix, x-forwarded-for
spoofing fix, Latin-1 header encoding guard
- Add 4 new test modules (model access, priority selection, request
builder, tool conversion) + update existing MCP tests
* fix(security): run pre-call guardrails before MCP sampling acompletion
Without this, an upstream MCP server with allow_sampling enabled could
send prompts that bypass every guardrail (content filtering, PII
redaction, prompt-injection detection) configured on /chat/completions.
- Call proxy_logging_obj.pre_call_hook(call_type='acompletion') before
llm_router.acompletion so guardrails fire for sampling sub-calls
- Add HTTPException to the re-raise list so guardrail rejections
propagate correctly instead of being swallowed as generic errors
* feat(bedrock_mantle): add Responses API support (/openai/v1/responses) (#29490)
* feat(bedrock_mantle): add Responses API transformation config
* test(bedrock_mantle): cover trailing-slash api_base normalization
* feat(bedrock_mantle): export BedrockMantleResponsesAPIConfig
* feat(bedrock_mantle): register gpt-5.x Responses config (gpt-oss unchanged)
* feat(bedrock_mantle): add gpt-5.5/gpt-5.4 Responses price-map entries
* refactor(bedrock_mantle): exclude gpt-oss instead of allow-listing gpt-5 for Responses routing
Frontier OpenAI models on Bedrock Mantle are Responses-only on /openai/v1/responses;
gpt-oss is the legacy family that also speaks chat-completions. Gate by excluding
gpt-oss (which keeps its chat-completions emulation) and defaulting everything else
to the native Responses config, so future frontier models (gpt-6, etc.) route
correctly without a code change. Verified against the live us-east-2 Mantle endpoint:
gpt-oss 400s on /openai/v1/responses while gpt-5.5 400s on both standard paths.
* test(bedrock_mantle): cover supports_native_websocket opt-out
Closes the one uncovered line flagged by codecov on the Responses config.
The assertion documents that Mantle Responses has no realtime/websocket
transport, so realtime routing must not attempt a socket it cannot serve.
* fix(bedrock_mantle): route file_search through emulation instead of forwarding to Mantle
BedrockMantleResponsesAPIConfig inherited supports_native_file_search()
-> True from OpenAIResponsesAPIConfig but never overrode it. Mantle has no
OpenAI vector stores, so a forwarded file_search tool is rejected with a
400 (verified upstream: Tool type 'file_search' is not supported). Opting
out, like the existing supports_native_websocket override, routes the tool
through LiteLLM's file_search emulation instead.
* fix(bedrock_mantle): only route openai.gpt frontier models to Responses
The previous gate excluded gpt-oss and routed every other model to the
native Responses config. But on Mantle only the OpenAI gpt frontier models
(gpt-5.x) are served on /openai/v1/responses; gpt-oss and the non-OpenAI
families (nvidia, mistral, google, zai, ...) are chat-completions only and
400 on that path. Allow-list the openai.gpt- family (excluding gpt-oss)
instead, so chat-only models fall through to the chat-completions emulation.
Verified against the live us-east-2 endpoint: nvidia.nemotron-nano-9b-v2
returns 400 on /openai/v1/responses and 200 on /v1/chat/completions.
* feat(custom_llm): allow streaming/astreaming to yield ModelResponseStream (#27580)
* fix(custom_llm): allow streaming/astreaming to yield ModelResponseStream directly
* fix(streaming): enhance ModelResponseStream handling for custom LLM providers
* fix(streaming): strip finish_reason from content chunks and ensure tool_calls are preserved
* fix(streaming): add type ignore for finish_reason assignment in CustomStreamWrapper
* fix(proxy): strip stack trace from HTTP 503 responses (CWE-209) (#28330)
* fix(proxy/cwe-209): strip Python traceback from HTTP 503 error responses
The /cache/ping endpoint included a full Python traceback in its 503 error
response body (inside the ProxyException message), leaking internal file
paths, line numbers, and call stacks to any caller. Two MCP route handlers
in proxy_server.py similarly interpolated str(e) into "Internal server
error" detail strings.
Fix: log the traceback server-side via verbose_proxy_logger.exception()
and omit it from the ProxyException payload / HTTPException detail returned
to clients. Tests updated to assert no "traceback" keyword or frame paths
appear in the 503 body, with a new dedicated regression test.
CWE-209: Generation of Error Message Containing Sensitive Information.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(proxy/cwe-209): apply Greptile P2 fixes and add MCP exception-path tests
Greptile 4/5 review identified two remaining gaps and Codecov reported
0% coverage on the two MCP handler exception branches:
1. caching_routes.py — str(e) in "Service Unhealthy ({str(e)})" could
still leak Redis hostnames/IPs; replaced with static "Service Unhealthy".
HTTPException is now re-raised before the generic handler so the
"cache not initialized" 503 still reaches callers with its detail.
Removed the redundant str(e) arg from verbose_proxy_logger.exception()
(exception() already appends the traceback automatically).
2. tests — two new unit tests cover the exception paths in
dynamic_mcp_route and toolset_mcp_route that were previously at 0%:
- test_dynamic_mcp_route_unexpected_exception_returns_500_without_traceback
- test_toolset_mcp_route_unexpected_exception_returns_500_without_traceback
All 25 tests pass (9 caching + 16 MCP).
CWE-209: Generation of Error Message Containing Sensitive Information.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(caching_routes): restore precise assertion in test_cache_ping_no_cache_initialized
The assertion was weakened to `"Cache not initialized" in str(data)`, which
matches the raw string of the entire response dict and would pass even if the
error moved to an unexpected field or changed structure.
Restore a targeted check on the parsed response: assert the exact string in
the correct field `data["detail"]`, matching FastAPI's HTTPException
serialisation format {"detail": "<message>"}.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(caching_routes): restore precise assertion and add CWE-209 no-cache path test
The assertion in test_cache_ping_no_cache_initialized was weakened to
`"Cache not initialized" in str(data)`, which matched against the raw string
representation of the entire response dict. This would pass silently even if
the error message moved to an unexpected field or the structure changed.
Restore a targeted assertion on the parsed field:
assert data["detail"] == "Cache not initialized. litellm.cache is None"
matching FastAPI's HTTPException serialisation format exactly.
Add test_cache_ping_no_cache_does_not_expose_internals to show the code path
is still working correctly after the CWE-209 fix: verifies that the HTTPException
is re-raised as-is (no traceback, no source paths), and asserts the complete
response structure is exactly {"detail": "Cache not initialized. litellm.cache is None"}.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(caching_routes): restore ProxyException envelope for null-cache 503
The except HTTPException: raise guard (added in the CWE-209 fix) caused
the null-cache HTTPException to escape as FastAPI's {"detail": "..."} shape
instead of the {"error": {...}} ProxyException envelope that callers expect.
Move the null-cache guard before the try block and raise ProxyException
directly so the response structure is consistent with all other /cache/ping
503s, and the except HTTPException: raise guard is only reachable by
unexpected downstream HTTPExceptions.
Update the two no-cache tests to assert the correct ProxyException envelope.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* Update utils.py (#26609)
* feat(pricing): add Snowflake Cortex REST API model pricing (#26612)
* feat(pricing): add Snowflake Cortex REST API model pricing
## Summary
Adds pricing and context window information for 20+ Snowflake Cortex REST API models to `model_prices_and_context_window.json`.
## What's included
- **7 Claude models** (sonnet-4-5, sonnet-4-6, 4-sonnet, 4-opus, haiku-4-5, 3-7-sonnet, 3-5-sonnet) — with prompt caching rates
- **4 OpenAI models** (gpt-4.1, gpt-5, gpt-5-mini, gpt-5-nano) — with prompt caching rates
- **5 Llama models** (3.1-8b, 3.1-70b, 3.1-405b, 3.3-70b, 4-maverick)
- **1 DeepSeek model** (deepseek-r1)
- **1 Mistral model** (mistral-large2)
- **1 Snowflake model** (snowflake-llama-3.3-70b)
- **2 Embedding models** (arctic-embed-l-v2.0, arctic-embed-m-v2.0)
Each entry includes `input_cost_per_token`, `output_cost_per_token`, `cache_read_input_token_cost` (where applicable), `max_input_tokens`, `max_output_tokens`, and capability flags (`supports_function_calling`, `supports_vision`, `supports_prompt_caching`, `supports_reasoning`).
## Pricing source
All prices are in USD per token, sourced from the official [Snowflake Service Consumption Table](https://www.snowflake.com/legal-files/CreditConsumptionTable.pdf) — Tables 6(b) (REST API with Prompt Caching) and 6(c) (REST API).
## Context
The existing `snowflake/` provider has zero model entries in the pricing JSON, which means LiteLLM cannot track costs for Snowflake Cortex calls. This PR fills that gap.
## Related
- Existing provider: `litellm/llms/snowflake/`
- Cortex REST API docs: https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-rest-api
* Update model_prices_and_context_window.json
Fix the JSON parsing error
* Update model_prices_and_context_window.json
Removed the duplicate entry
* fix(utils): copy extra_body before adding unknown params to prevent model config mutation (#29620)
Fixes #29615. In add_provider_specific_params_to_optional_params, the line:
extra_body = passed_params.pop("extra_body", None) or {}
returns the original dict reference when extra_body is non-empty (truthy).
Subsequent writes like extra_body[k] = passed_params[k] then mutate the
shared model config object held by the router, poisoning /model/info and
all subsequent requests for that deployment.
The or {} short-circuit creates a new dict only when extra_body is falsy
(None or {}), which is why the bug does not reproduce with extra_body: {}.
Fix: wrap in dict() so we always work on a fresh shallow copy.
* fix(vertex_ai): Bake tool_choice into Gemini CachedContent body to prevent silent drop (#29097)
* fix(vertex_ai): bake tool_choice into Gemini CachedContent body to prevent silent drop
* address greptile feedback on tool_choice cache test
* adds test that uses ToolConfig(functionCallingConfig=FunctionCallingConfig(mode=ANY)) instead of a dict literal, mirroring what map_tool_choice_values actually produce
* fix(gemini/veo): move image from parameters into instances[0] (#29501)
* fix(gemini/veo): move image from parameters into instances[0]
Veo's predictLongRunning schema puts image (and prompt) on the
instances element; parameters is for aspectRatio/durationSeconds/etc.
The Gemini path was leaving image in params_copy, so it ended up
nested under parameters and the API silently ignored it.
The Vertex path already builds the instance dict explicitly, so this
just aligns the Gemini path with it.
Fixes #29498
* address greptile: unconditional pop + BytesIO test
- Pop `image` from params_copy unconditionally so it never reaches
GeminiVideoGenerationParameters even when None, removing implicit
reliance on Pydantic's extra-field-ignore.
- Add test_transform_video_create_request_image_filelike_goes_to_instance
covering the BytesIO path (_convert_image_to_gemini_format) — round-trips
the base64 to confirm encoding.
- Add test_transform_video_create_request_image_none_is_dropped covering
the new None branch.
* fix(huggingface): handle special token text in embedding usage (#29660)
* fix(guardrails): recompile ToolPermissionGuardrail rules on update_in_memory_litellm_params (#29655)
* fix(guardrails): recompile ToolPermissionGuardrail rules on update_in_memory_litellm_params
ToolPermissionGuardrail builds self.rules and the compiled target/pattern
maps only in __init__. The base update_in_memory_litellm_params re-sets raw
attributes via setattr but never rebuilds those maps, so a guardrail updated
in place (PUT /guardrails, or the immediate in-memory sync) keeps enforcing
the construction-time rules until it is reinitialized (PATCH path, periodic
DB poll, or restart).
Extract the compile step into _load_rules and override
update_in_memory_litellm_params to rebuild from it (dict- and model-safe),
re-normalizing default_action / on_disallowed_action. Mirrors the existing
PresidioGuardrail override of the same method. Adds regression tests.
Fixes #29592.
* fix(guardrails): handle dict params in ToolPermissionGuardrail in-memory update
Delegate to super() only for LitellmParams input (the base setattr loop is
model-only); apply the raw-dict case inline. Fixes the mypy arg-type error
and makes the recompile work when the proxy passes the raw DB dict.
* fix(guardrails): preserve tool-permission rules on a partial in-memory update
A partial update (e.g. a LitellmParams whose rules field is None) ran through
the generic setattr, which set self.rules to None, and the recompile was
skipped, leaving the guardrail with no rules. Snapshot the previous rules and
restore them when the update carries no rules; an explicit empty list still
clears them. Adds a regression test for the rules-absent case.
Addresses the Greptile review note on #29655.
* fix(bedrock): stop base_model label from stripping tools/tool_choice (#29621)
* fix(bedrock): stop base_model label from stripping tools/tool_choice
A Router/proxy Bedrock deployment whose model_info.base_model is a friendly
label (e.g. claude-haiku-4-5) silently lost tools/tool_choice: the outgoing
Converse request was built without toolConfig, so the model behaved as if no
tools were provided. Worked in v1.84.0, regressed in v1.85.0, and with
drop_params=true it failed silently.
Two changes compound into the bug. completion() passed model_info.base_model
as the model argument to get_optional_params, so the real Bedrock model id
never reached supported-param resolution; and get_supported_openai_params
resolved the provider config's params from base_model or model, letting the
label fully replace the real model. For Bedrock the label resolves to no tool
support, so tools/tool_choice were dropped before transformation.
completion() now keeps model as the real deployment model and threads the
resolved base_model (kwarg or model_info) through separately, and
get_supported_openai_params treats base_model as additive: it returns the
union of the params supported by model and by base_model. A hint can only add
capabilities, never strip ones the real model already exposes, which also
preserves the original base_model behavior from #27717 and Azure's base_model
driven model-type detection.
Fixes #29618
* test(main): make base_model param test robust to new parametrize cases
Restore an explicit per-case expected_model_param literal instead of
hardcoding the gemini id, so a future case with a different model can't
produce a misleading assertion failure.
* fix(fireworks_ai): pass response_format json_schema through unchanged (#29606)
FireworksAIConfig.map_openai_params was rewriting the OpenAI strict
`{type: json_schema, json_schema: {name, strict, schema}}` shape into
`{type: json_object, schema: ...}` before sending to Fireworks, dropping
`strict` and `name` and changing the `type`. Per Fireworks' docs json_object
means "force any valid JSON output (no specific schema)", so the schema
constraint was effectively dropped and grammar-guided decoding never ran;
model output silently violated the schema.
The rewrite landed in #7085 (Dec 2024) when Fireworks did not yet accept
native json_schema. Fireworks accepts the OpenAI strict shape natively now,
so the rewrite has become a regression.
Removes the rewrite. Passes response_format through unchanged. Updates the
existing test_map_response_format to assert pass-through. Adds focused
regression tests in tests/test_litellm/ covering preservation of type,
strict, name, and schema body, plus that json_object alone still works.
* fix(types): import Required from typing_extensions in gemini types
* style: reformat sampling_handler.py for py312 black compat
* refactor(mcp-sampling): extract helpers to fix PLR0915 too-many-statements in handle_sampling_create_message
* fix(proxy-server): add explicit ProxyLogging type annotation to proxy_logging_obj to fix mypy inference
* fix(mcp-sampling): suppress mypy assignment error on ImportError fallback for proxy_logging_obj
* fix(test): use .value when comparing LlmProviders enum against string in test_default_api_base
* fix(test): iterate LlmProviders enum in test_default_api_base to avoid str pollution from custom provider registration
litellm.provider_list is a mutable global initialized to list(LlmProviders) but custom_llm_setup() appends plain provider strings to it. When a test_custom_llm.py test runs first in the same xdist worker, provider_list contains a str and calling .value on it raises AttributeError. Iterate the immutable LlmProviders enum instead, which is deterministic and what the check intends.
* fix(mcp): depth-aware JSON-RPC response detection and neutral speed-priority fallback
Replace the flat substring check in the truncated-body routing path with a
top-level-key scan so a JSON-RPC response whose result payload nests a
"method" field is still detected as a response and skips the session lock,
removing a deadlock against the in-flight tool call awaiting it.
Drop the inverse max_output_tokens speed proxy when no model exposes
output_tokens_per_second; context-window size does not track latency, so a
neutral score avoids biasing speedPriority toward the smallest-context model.
* fix(guardrails): make ToolPermission rule reload atomic on invalid regex
_load_rules appended each rule to self.rules before compiling its regex, so an
invalid pattern raised mid-loop after the bad rule was already live but without
a _compiled_rule_targets entry. _matches_regex reads a missing compiled target
as a None pattern and returns True, turning the bad rule into a match-all that
silently applies its decision to every tool. Via update_in_memory_litellm_params
(PUT /guardrails) this corrupted the live guardrail.
Build the parsed rules and compiled maps into locals and swap them in only after
every regex compiles, and restore the previous ruleset if a live update is
rejected, so an invalid regex now fails the update without leaving the guardrail
enforcing a broken policy.
* test(mcp): cover sampling conversion, model resolution, and elicitation relay paths
The MCP sampling and elicitation handlers shipped with partial test
coverage, leaving the response-to-MCP conversion, the model resolution
fallback chain, completion-kwargs assembly, guardrail routing, and the
entire elicitation relay untested. That pulled the PR's diff (patch)
coverage below the codecov threshold even though overall project
coverage rose.
Add focused unit tests for _convert_openai_response_to_mcp_result,
_convert_mcp_tools_to_openai, _convert_mcp_tool_choice_to_openai, image
and audio content conversion, the hint-matching and fallback branches of
_resolve_model_from_preferences, _build_completion_kwargs, the router and
guardrail-rejection paths of _run_guardrails_and_call_llm, the
handle_sampling_create_message success and error-propagation flows, the
marker-hoisting fallback for tool content on unexpected roles, and the
elicitation form/url/generic relay together with its decline paths
---------
Co-authored-by: shin-berri <shin-laptop@berri.ai>
Co-authored-by: yuneng-jiang <yuneng@berri.ai>
Co-authored-by: lengkejun <lengkejun@xd.com>
Co-authored-by: Yug <yugborana000@gmail.com>
Co-authored-by: Kent <72616338+kingdoooo@users.noreply.github.com>
Co-authored-by: tanmay958 <53569547+tanmay958@users.noreply.github.com>
Co-authored-by: DrishnaTrivedi <142084770+DrishnaTrivedi@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Navnit Shukla <Navnit.shukla25@gmail.com>
Co-authored-by: PRABHU KIRAN VANDRANKI <72809214+VANDRANKI@users.noreply.github.com>
Co-authored-by: Adrian Lopez <109683617+adriangomez24@users.noreply.github.com>
Co-authored-by: hcl <chenglunhu@gmail.com>
Co-authored-by: JooHo Lee <96564470+BWAAEEEK@users.noreply.github.com>
Co-authored-by: Dinesh Girbide <85330597+Dinesh-Girbide@users.noreply.github.com>
Co-authored-by: cloudwiz <22098246+andrey-dubnik@users.noreply.github.com>
Co-authored-by: Ahmad Khan <ahmadkhan2508@gmail.com>
Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
Formatting-only pass; no logic changes. Brings the UI into compliance with .prettierrc so the new format-check CI job passes
Add the squash-merged SHA of #29622 (style(ui): run prettier --write across the dashboard) to .git-blame-ignore-revs so the bulk reformat stops masking the real authors of those lines in git blame and the GitHub blame UI
…9605) * change deployment configs to include a litellm.cache for litellm-backend pod mirroring litellm-gateway pod * omit backend annotations block when config and podAnnotations are both empty * reuse gateway config/configmap for backend instead of separate backend config --------- Co-authored-by: shin-berri <shin-laptop@berri.ai> Co-authored-by: yuneng-jiang <yuneng@berri.ai> Co-authored-by: Tin Chi Lo <tin@Tins-MBP.localdomain> Co-authored-by: Tin Chi Lo <tin@Tins-MacBook-Pro.local>
…_table (#29684) In Pydantic v2, Optional[T] without a default is a required field. Any row with budget_id=null triggered a validation error and returned 401. Co-authored-by: Florent Chenebault <florent.chenebault@lifen.fr>
test_custom_tokenizer_bug.py loaded Xenova/llama-3-tokenizer from HuggingFace Hub at test time, so it flaked on shared CI runners whenever HF returned 429 Too Many Requests; the surfaced LocalEntryNotFoundError made it look like a connectivity bug. Rewrite the suite to mock the one network boundary (litellm.utils.Tokenizer.from_pretrained) while running the proxy's real extraction-and-selection path. The regression test now asserts the configured identifier from model_info.custom_tokenizer actually reaches from_pretrained and that the response reports the huggingface tokenizer, which the previous llama-3-named test could not distinguish from the default path. A control test pins the no-custom-tokenizer case to the OpenAI tokenizer with from_pretrained asserted unused. Verified by reintroducing the original bug (model_info left unpopulated from the deployment): the regression test fails (from_pretrained called 0 times) while the control stays green.
…29700) * test(proxy): stop running real-DB tests in GitHub Actions unit jobs GitHub Actions unit jobs were spinning up a Postgres service container, but the only active tests that touched it either used the DB incidentally (a cargo-culted prisma_client.connect()) or were genuine integration tests mislabeled as unit. Mock the incidental ones so the proxy-db job needs no container, and move the tests that genuinely need a database (proxy management behavior, master-key-not-persisted, schema-migration sync) to CircleCI, which is already the real-infrastructure lane. * test(proxy): restore no-unexpected-startup-writes canary in master-key test Greptile noted the hash-match assertion no longer catches other unexpected startup writes (a default key, a rotation artifact). The CircleCI job gives each run a fresh DB, so a clean startup must leave the table empty; add that canary back alongside the precise master-key assertion.
* fix(ui): only flag bare fetch() outside React Query queryFn/mutationFn The frontend lint rule banned every fetch() call by static AST name match, so a fetch wrapped in a React Query queryFn/mutationFn tripped it just like a loose fetch in a component. esquery (no-restricted-syntax) can't express "has ancestor", so this replaces that selector with a small custom rule (local/no-bare-fetch) that exempts a fetch lexically inside a queryFn or mutationFn and reports everything else. Re-baselined eslint-suppressions.json under the new rule id (same 44 files / 331 violations) so existing code keeps its grandfathered suppressions. Adds a RuleTester suite covering wrapped (valid) vs unwrapped, the standalone *Api.ts function pattern, queryKey, and computed-key cases. * chore(ui): remove the bare-fetch lint rule Drop the fetch lint gate (and its 331 grandfathered suppressions) ahead of the networking refactor. The plan is to centralize all fetching in a single shared http client and enforce that with a location-based rule, so keeping a fetch rule in place now would only block CI while functions are routed through the new client. Removing it unblocks that work; the location-based rule lands with the client in a follow-up.
* feat(ui): gate "Default Credentials" hint on /ui/login behind env flag (#30234)
Adds LITELLM_HIDE_DEFAULT_CREDENTIALS_HINT (and an equivalent
general_settings.hide_default_credentials_hint) that suppresses the
"By default, Username is admin and Password is your set LiteLLM Proxy
MASTER_KEY" info card rendered on /ui/login and /fallback/login.
Motivation: in production deployments operators set UI_USERNAME /
UI_PASSWORD (or SSO), and the hardcoded hint becomes factually
incorrect and is flagged by security scanners (Tenable WAS plugin
114625) as information disclosure. There is currently no way to
suppress it without forking the dashboard.
Behaviour:
- Default is unchanged (hint shown), so existing deployments are
unaffected.
- New field hide_default_credentials_hint on the well-known UI config
endpoint, populated from the env var or general_settings.
- LoginPage.tsx conditionally renders the Alert based on the flag.
Refs: BerriAI/litellm#30232
* fix(router): clean pattern_router state on upsert/delete (#29601)
* fix(router): clean pattern_router state on upsert/delete
PatternMatchRouter.add_pattern was append-only, and neither Router.upsert_deployment nor Router.delete_deployment removed the existing entry. Rotated-out api_keys stayed in the routing rotation for wildcard deployments (model_name with `*`) until proxy restart, silently defeating key rotation as an admin operation. The same leak applied to provider_default_deployment_ids and per-team pattern routers, and the patterns list grew unboundedly on every edit
* test(router): direct unit tests for _remove_deployment_from_wildcard_state
router_code_coverage.py greps test files for AST Call nodes and flagged
the helper as untested because the existing coverage only exercised it
transitively through upsert/delete. Adds two direct tests that pin the
helper's contract (cleans across global pattern router, per-team
routers with empty-router pop, and provider_default_deployment_ids;
noop on falsy model_id)
* fix(router): address Greptile review on pattern_router cleanup
Widen PatternMatchRouter.remove_deployment annotation to Optional[str];
the implementation already handles None via the falsy guard and the
unit test exercises it directly.
Move _remove_deployment_from_wildcard_state up one level in
upsert_deployment so it runs whenever the prior deployment is on the
router, not only when the model_id is present in the fast-mapping
index. The scenario is currently unreachable (get_deployment shares
the same index), but the cleanup is idempotent so this is defensive
against any future divergence between those code paths.
* fix(router): widen _remove_deployment_from_wildcard_state to Optional[str]
Moving the call out of the inner `deployment_id in deployment_fast_mapping`
block in the previous commit lost mypy's narrowing of `deployment_id`
from Optional[str] to str, tripping the lint CI. The helper already
handles None via its falsy guard, so widening the annotation matches
the actual contract.
* fix(router): make delete_deployment wildcard cleanup symmetric with upsert
After the previous commit moved _remove_deployment_from_wildcard_state out
of the inner index-map guard in upsert_deployment, delete_deployment was
still calling it only inside `if deployment_idx is not None`. Greptile
flagged the asymmetry: under a desynced index_map, delete would silently
leave the stale wildcard credential in pattern_router.
Moves the cleanup call to the top of the try block, mirroring the upsert
path. Cleanup is idempotent so the change is a no-op on the happy path.
Adds a regression test that simulates the desync by removing the entry
from model_id_to_deployment_index_map and asserts delete still clears
pattern_router.
* fix(pricing): add 1h cache-write cost for Anthropic Sonnet 4.5/4.6 (#30474)
The native anthropic claude-sonnet-4-5/4-6 price-map entries were missing
cache_creation_input_token_cost_above_1hr (and the >200K long-context
sub-tier for 4.5), so 1-hour-TTL cache writes were costed at the 5-minute
rate. Adds 6e-06 regular (and 1.2e-05 long-context) = 2x base input,
matching the vertex_ai/azure_ai/bedrock siblings and the older
claude-sonnet-4-20250514 entry. Adds a regression test.
* fix(proxy): cancel upstream gemini request and release httpx connection on client disconnect (#30075)
* fix(proxy): cancel upstream gemini request and release httpx connection on client disconnect
- add _check_request_disconnection to common_request_processing; wrap llm_call
as asyncio.Task so it can be cancelled; catch CancelledError and raise
HTTPException(499) when client disconnects before LLM responds (non-streaming path)
- pass raw httpx.Response into ModelResponseIterator in make_call/make_sync_call
so the iterator holds a reference to the underlying connection
- implement ModelResponseIterator.aclose() and .close(): close the line iterator
then explicitly call response.aclose()/response.close() to release the httpx
connection when the client drops mid-stream; errors are debug-logged, not raised
- add tests for _check_request_disconnection (cancels task, graceful on exception,
does not cancel when client stays connected) and base_process_llm_request 499
behavior; add TestModelResponseIteratorCleanup verifying aclose/close propagation
through CustomStreamWrapper
* fix(proxy): record 499 on streaming disconnect and cancel orphaned gather tasks
Wire streaming generator cleanup to log client_disconnected with error_code 499
in spend logs, cancel pending during_call_hook tasks when the LLM call is
cancelled on disconnect, and align the 600s poll limit comment with proxy_server.
* fix: extract client disconnect logging helper to satisfy PLR0915
* fix: resolve mypy and code-quality CI failures for client disconnect logging
Cast client disconnect error_information for mypy, only await pending gather tasks to avoid masking LLM errors, and add tests for the new logging helper and gather cleanup.
* fix(proxy): harden gather cleanup so finally cannot mask LLM errors
* fix(proxy): shield streaming disconnect logging and strip spoofable metadata
Move streaming disconnect recording into a shielded cancel scope, add gather cleanup regression coverage for guardrail-converted cancels, and strip client_disconnected/error_information from user metadata at the proxy boundary.
* fix(proxy): only map CancelledError to 499 for client disconnect
Track when the disconnect poller cancels the LLM task and re-raise other CancelledError paths so graceful shutdown is not reported as HTTP 499.
* fix(proxy): remove dead _check_request_disconnection helper
Non-streaming client disconnect is handled by staging's cancel_on_disconnect path via _await_llm_call_cancelling_on_disconnect. Drop the unused is_disconnected poller and its unit tests; rename the remaining integration tests to TestDisconnectGatherCleanup.
* feat(mistral): add mistral-medium-3-5 to model_prices_and_context_wind.. (#29303)
* feat(mistral): add mistral-medium-3-5 to
model_prices_and_context_window.json
Mistral's docs page lists mistral-medium-3-5 as a new model offering.
Pricing/specs sourced from Mistral's published model metadata:
- input: $1.50 / 1M tokens
- output: $7.50 / 1M tokens
- context: 262,144 tokens
- capabilities: vision, function calling, structured outputs, assistant
prefill
Adds entry: `mistral/mistral-medium-3-5`, mirroring the pattern used for
the rest of the Mistral family.
test(mistral): add model_info test for mistral-medium-3-5 + sync backup
cost map
- Mirror mistral/mistral-medium-3-5 entries into
litellm/model_prices_and_context_window_backup.json so the bundled
model cost map matches the canonical
model_prices_and_context_window.json.
- Add tests/test_litellm/test_mistral_medium_3_5_model_metadata.py
covering pricing tiers, capability flags, context window, provider
routing, and parity between the main and backup cost maps.
- Point 'source' at the live Mistral models documentation page.
* fix(ui): three small UI fixes — Gemini api_base + credential form reset + Mode badge (#30419)
* fix(ui): three small UI fixes — Gemini api_base field + credential form reset + Mode badge
Three independent fixes; bundled because they all touch the
credential-form / logging-callbacks area.
1. expose api_base field on Google AI Studio credential form
The runtime gemini provider supports custom api_base via
`vertex_llm_base._check_custom_proxy`; the UI just needs to expose
the field. Adds api_base to the Google_AI_Studio credential form
ordered before api_key (matching OpenAI/Anthropic conventions).
Default value matches the canonical Google AI Studio endpoint that
LiteLLM's gemini provider talks to when api_base is unset, so
leaving the default in the form behaves identically to leaving it
blank.
2. reset credential form state when switching providers
Switching the Provider select in AddCredentialModal / EditCredentialModal
left the previous provider's field values populated. The form then
submitted a mixed payload (e.g. Azure deployment fields under an
OpenAI credential), producing confusing failures.
Extract `getProviderFieldDefaults` helper and reset the form to it
on provider change. Unit-tested via the extracted helper because
Antd Select's portal/dropdown behaviour is unreliable in jsdom.
3. logging callbacks table reads backend `type` for Mode badge (#35)
The `/get_callbacks` proxy endpoint returns each callback as
`{name, type, variables}` where `type` is `"success"` or
`"failure"`. The same callback name can appear twice (one per event
class) and the two entries fire on disjoint events.
`LoggingCallbacksTable` ignored `type` and read `record.mode`
(always undefined), so every row fell back to the "Success" badge.
A `generic_api` callback registered for both classes showed up as
two identical "Success" rows + React duplicate-key warning.
Read `record.type` first (fall back to `record.mode` for newly-
added not-yet-server-acknowledged rows). Composite rowKey
`${name}-${type ?? mode ?? 'success'}`. Removed leftover debug
`console.log`.
* fix(ui): drop api_base default_value to preserve Gemini v1alpha auto-routing
Greptile P2 (PR #30419, threads on lines 1255-1256 of
provider_create_fields.json): the api_base field's `default_value` was
hard-coded to "https://generativelanguage.googleapis.com/v1beta". This:
1. Bakes v1beta into every credential record saved through the form,
even when the user never touched the field. If LiteLLM's internal
gemini default URL ever changes, those persisted credentials keep
hitting the stale path.
2. Bypasses `_get_gemini_url`'s automatic version routing for Gemini 3+
models. That helper picks v1alpha for Gemini 3+ and v1beta for older
models when api_base is unset. With the default pre-filled (and
`_check_custom_proxy` then taking over because api_base is non-empty),
Gemini 3+ requests get pinned to v1beta and may fail or behave
unexpectedly — purely because the user accepted the visible default.
Fix: set `default_value` to `null` and move the canonical URL guidance
into the `placeholder` (visible to the user, never persisted) and an
expanded tooltip. UX is unchanged — the URL is still shown in the
greyed-out input — but the auto-version-routing path stays default.
Updated test_google_ai_studio_provider_fields_expose_api_base to assert
the new contract (`default_value is None`, `placeholder` carries the
canonical URL), with a comment pointing at the Greptile threads as the
rationale so future contributors don't accidentally re-introduce the
default.
26/26 tests in the file pass. JSON validates (`json.load` clean).
* feat(azure_ai): add gpt-5.5 to model cost map (#30428)
* feat(azure_ai): add gpt-5.5 to model cost map
Adds azure_ai/gpt-5.5 and its dated snapshot azure_ai/gpt-5.5-2026-04-23 to
both the canonical and bundled cost maps. gpt-5.5 is generally available on
Azure AI Foundry; pricing mirrors the openai gpt-5.5 entry, matching the
established azure_ai convention (verified identical for gpt-5.4), in the
azure tier structure (base / above-272k / priority). supports_minimal_
reasoning_effort is false, the capability that changed from gpt-5.4.
Fixes #30306
* Update tests/test_litellm/test_gpt_5_5_model_metadata.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* fix: guard check_and_fix_namespace against None key (#30435)
* fix: guard check_and_fix_namespace against None key
When user_id is None, the cache key can be None, causing
AttributeError: 'NoneType' object has no attribute 'startswith'
in check_and_fix_namespace.
Add an early return for None key to prevent the error and the
ERROR-level log noise it produces on every unauthenticated request.
Fixes #30424
* fix: update type annotations for check_and_fix_namespace
- key: str -> Optional[str] (now handles None input)
- return: str -> Optional[str] (returns None when input is None)
Addresses Greptile review concern about type signature mismatch.
* fix: revert check_and_fix_namespace type signature to str to fix MyPy downstream errors
* fix: update type annotations for check_and_fix_namespace
- Change signature from str -> str to Optional[str] -> Optional[str]
- Remove type: ignore comment on None return
- Add None guard in async_set_cache_sadd before passing to helper
Addresses review feedback from Sameerlite on type mismatch.
* Revert "fix: update type annotations for check_and_fix_namespace"
This reverts commit 5272920fa0daab676f5ad46dcadd8cd537cfc96f.
---------
Co-authored-by: michaelxer <michaelxer@users.noreply.github.com>
* fix(cost): apply service_tier suffix to above-threshold cache rates and expose priority+threshold keys in ModelInfo (#30450)
* fix(cost): apply service_tier suffix to above-threshold cache rates and expose priority+threshold keys in ModelInfo
Models that publish both a service_tier (e.g. priority) rate and an above-threshold tier (e.g. _above_200k_tokens) currently bill cached tokens at the standard above-threshold rate rather than the priority above-threshold rate. Affected entries in the live pricing JSON include gemini-3-pro-preview, gemini-3.1-pro-preview and their vertex_ai/ and gemini/ variants, plus azure/gpt-5.4 and azure_ai/gpt-5.4. For a 250K-token priority request with 200K cached tokens against gemini-3-pro-preview, the leak is about 44 percent of the prompt cost.
Two stacked defects caused this. First, ModelInfoBase (and the ModelInfo pydantic class) and the get_model_info construction in litellm/utils.py omit the priority+above-threshold cost keys, so even if the calculator asked for them they would never reach it. Second, in _get_token_base_cost the cache_creation/cache_read tiered keys never get wrapped with _get_service_tier_cost_key, while the input/output tiered keys above and below do. The change here surfaces six new keys (input, output and cache_read at both 200k and 272k priority variants) and wraps the three cache tiered keys in _get_token_base_cost the same way input/output already are. _get_cost_per_unit's existing service_tier-to-base fallback covers models that ship the standard above-threshold rate without a priority variant.
Adds one regression test in tests/test_litellm/litellm_core_utils/llm_cost_calc/test_llm_cost_calc_utils.py that drives the actual generic_cost_per_token path for gemini-3-pro-preview at 200K cached + 50K text under priority and asserts the priority above_200k rates are picked. Verified the test fails on litellm_internal_staging without these changes and passes with them.
* fix(cost): drop guard on cache tiered keys so service_tier fallback can reach standard above-threshold rate
Addresses Greptile P1 on PR 30450. The previous commit wrapped cache_creation_tiered_key, cache_creation_1hr_tiered_key, and cache_read_tiered_key with _get_service_tier_cost_key (matching how the sibling input and output tiered keys are wrapped) but kept the surrounding 'if key in model_info' guards. For models that publish a standard above-threshold cache rate but no priority variant (gpt-5.4-pro, gpt-5.5-pro and their dated siblings, plus vertex_ai/claude-sonnet-4-5 for cache_creation), the guard short-circuits before _get_cost_per_unit's existing service_tier-to-base fallback can strip _priority and find the standard above-threshold key. The result on priority requests over the threshold was that those models silently dropped from the above-threshold rate back to the priority-base rate. Dropping the guard and calling _get_cost_per_unit unconditionally (mirroring how tiered_input_key and tiered_output_key are already handled) restores correct billing for that class of models while keeping the new priority+above-threshold behaviour for gemini-3-pro-preview and friends.
Adds a second regression test that pins generic_cost_per_token for vertex_ai/claude-sonnet-4-5 priority + above_200k with cached and cache_creation tokens to the expected standard above-threshold rates, so the guard cannot be silently reintroduced for either the cache_read or cache_creation path.
* fix(presidio): skip pre-call masking when guardrail is logging_only (#30461)
The Presidio pre-call hook masked the live request unconditionally, ignoring
the configured event hook. With mode: logging_only the masked request reached
the model, so its response echoed anonymization tokens (e.g. <PERSON>) instead
of the real output. Gate async_pre_call_hook on should_run_guardrail, matching
every other guardrail; logging_only masking still happens via async_logging_hook.
* fix(router): resolve list unhashable crash on model alias (#30464)
* fix(router): resolve list unhashable crash on model alias
Fixes the fallback parsing logic that mistakenly categorized standard array fallback definitions as override dictionaries when a deployment alias matches the literal string 'model'.
Closes https://github.com/BerriAI/litellm/issues/30459
* fix(router): address greptile review for fallback parsing edge cases
- Resolves ambiguity in standard vs override fallback dictionaries by iterating over all items and validating that no mapped litellm param resolves to a non-list type.
- Adds regression tests in test_router_order_fallback.py to prevent unhashable type crash from silently re-entering the codebase.
* chore(router): format code with black to pass CI
* fix(hosted_vllm): remove thinking_blocks and convert list content to strings (#30475)
* fix: hosted_vllm remove thinking_blocks and convert list content to strings
vLLM endpoints reject assistant messages with thinking_blocks converted
to content list blocks. This change removes thinking_blocks entirely
and converts any list content back to strings.
This fixes BadRequestError when using Claude Code with hosted_vllm
models that pass thinking_blocks in messages.
* fix(hosted_vllm): address Greptile review feedback
- Join multiple text blocks with newline instead of empty string
- Always set content to string (never None) to avoid vLLM validation errors
* fix(hosted_vllm): update chat transformation to clean assistant messages
* fix: re-raise exception instead of silently dropping MCP team permissions (#30477)
* fix: re-raise exception instead of silently
dropping MCP team permissions
When MCPRequestHandler.get_allowed_mcp_servers raises, the
broad
except was swallowing the error and returning only
allow_all_server_ids,
silently discarding all team-level object_permission grants.
Fixes #30476
* fix: log full traceback when MCP permission lookup fails
Uses verbose_logger.exception() instead of warning() so operators
can see the full traceback when team-level object_permission grants
are dropped due to an internal error in get_allowed_mcp_servers.
Fixes #30476
* fix: remove timezone date expansion in daily-activity aggregation (#29569)
* fix: remove timezone date expansion in daily-activity aggregation
Single-day spend queries from non-UTC timezones over-counted by ~2x
because the previous implementation widened the SQL date range by a
full UTC day on whichever side the offset pointed. Spend is bucketed
in whole-UTC-day rows in LiteLLM_DailyUserSpend, so the expansion
pulled an extra 24h of unrelated bucket data per boundary.
Concretely on IST (UTC+5:30, offset -330): a single-day query for
2026-05-29 was rewritten to date >= 2026-05-28 AND date <= 2026-05-29
and returned spend across both UTC days. Sums of single-day queries
across a 5-day window then exceeded the equivalent multi-day aggregate
by ~50%, which is mathematically impossible.
Treat the local date range as the UTC date range. The aggregation
table has no hour-level granularity, so any conversion using only
date arithmetic must round to whole UTC days; the previous fix turned
that boundary slop into systematic over-counting. Pass-through trades
a small one-time slop at each end of the range for correct, monotonic,
additive results across single-day and multi-day queries.
Repro from production: bedrock/global.anthropic.claude-opus-4-8 over
2026-05-29 to 2026-06-02, IST timezone:
- 5-day aggregate: $701.39 / 1,831 reqs
- Sum of 5 single-day queries: $1,070.94 / 2,755 reqs
- Excess (was 1.527x): now matches within boundary slop
Adds regression tests in TestAdjustDatesForTimezone and
TestBuildAggregatedSqlQuery that pin the pass-through behavior and
the additivity invariant for any future implementation.
* ci: rerun checks on litellm_oss_branch base
---------
Co-authored-by: Sameer Kankute <sameer@berri.ai>
* fix: buffer native gemini sse frames (#30225)
* fix: buffer native gemini sse frames
* fix: scope native gemini sse buffering
* fix: check raw sse residual buffer size
* feat: updated openrouter provider to map max level to xhigh (#28881)
* feat(proxy): allow use_redis_transaction_buffer without redis cache (#28764)
* feat(proxy): allow use_redis_transaction_buffer without redis cache
* fix(proxy): require host or url for standalone buffer redis
* fix(mcp): fail closed when scope filter resolves to no servers (#30353)
`_get_allowed_mcp_servers_from_mcp_server_names` returned the caller's full
allowed-server set when the requested `mcp_servers` list (path- or
header-derived) resolved to nothing. URL/header namespacing therefore
appeared to work even when the requested name was unknown or the caller had
no grant — `/mcp/<typo>/` silently exposed every server the key could reach.
Fail closed instead: when `mcp_servers` is explicitly provided but nothing
resolves, return an empty list. The `mcp_servers=None` path (no scope
requested) keeps its existing behavior.
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* fix(token-counter): handle Anthropic tool_reference blocks to stop dropped spend logs (#30302)
* fix(token-counter): handle Anthropic tool_reference blocks to stop dropped spend logs
`token_counter` did not know about Anthropic tool-search `tool_reference`
content blocks, a lightweight pointer to a deferred tool that shows up as
`{"type": "tool_reference", "tool_name": ...}`. When such a block appeared in
message content, `_count_content_list` fell through to its catch-all branch and
raised `Invalid content item type: tool_reference`.
On the streaming `anthropic_messages` proxy path that exception nulls
`response_cost`, which makes the proxy drop the entire SpendLogs row. The result
is a silent cost undercount on any tool-search traffic; the request succeeds for
the caller but the spend is never recorded.
This adds a `tool_reference` branch that counts the referenced `tool_name` (the
full tool definition is already counted via the `tools` param, so only the name
is added here) and handles an empty/missing name gracefully. The catch-all error
message is updated to list `tool_reference` among the expected types.
A regression test asserts that a message containing a `tool_reference` block no
longer raises and returns a positive token count, and that an empty `tool_name`
is handled without error.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(token-counter): collapse explicit None tool_name to empty string
In _count_content_list, c.get("tool_name", "") returns None when the
key is present with an explicit None value, and str(None) == "None"
which is truthy, causing a spurious token to be counted. Use
c.get("tool_name") or "" so both a missing key and an explicit None
collapse to an empty string and are skipped.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(token-counter): cover catch-all for unknown content block type
Adds a regression test that calls `_count_content_list` with an unrecognized
content block type and asserts it raises `ValueError` whose message names the
offending type and lists `tool_reference` among the supported types. This
exercises the previously uncovered catch-all branch (codecov patch gap) and
pins the error contract.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(token-counter): cover tool_reference on the spend/cost and streaming paths
Adds end-to-end regression tests that exercise the real public entry points
(`completion_cost` and `stream_chunk_builder`), not just the private
`_count_content_list` helper, for Anthropic tool-search `tool_reference`
content blocks.
These pin the actual bug the fix addresses: before the fix the `tool_reference`
block raised out of `completion_cost` -> the proxy logging layer nulled
`response_cost` and the spend callback dropped the SpendLogs row (silent cost
undercount on all tool-search traffic); and `stream_chunk_builder` swallowed the
same raise and collapsed prompt_tokens to 0. With the fix, cost is positive and
prompt_tokens are counted. Verified: 3 fail without the fix, 3 pass with it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(cost): add cost mapping for deepseek-v4-flash and deepseek-v4-pro (#27056)
* feat(cost): add cost mapping for deepseek-v4-flash and deepseek-v4-pro
Adds pricing entries for the two new DeepSeek V4 models released on
2026-04-24, for both bare model names and the deepseek/ provider prefix.
Prices sourced from https://api-docs.deepseek.com/quick_start/pricing:
- deepseek-v4-flash: $0.14/M input, $0.28/M output
- deepseek-v4-pro: $1.74/M input, $3.48/M output
Cache hit price set to 1/10 of input (per DeepSeek docs).
Context window: 1M tokens for both models.
Closes #26709
* fix(cost): update backup registry for deepseek-v4
* style: remove print statement from deepseek-v4 test
* feat(cost): add cost mapping for deepseek-v4-flash and deepseek-v4-pro
Adds pricing entries for the two new DeepSeek V4 models released on
2026-04-24, for both bare model names and the deepseek/ provider prefix.
Prices sourced from https://api-docs.deepseek.com/quick_start/pricing:
- deepseek-v4-flash: $0.14/M input, $0.28/M output
- deepseek-v4-pro: $1.74/M input, $3.48/M output
Cache hit price set to 1/10 of input (per DeepSeek docs).
Context window: 1M tokens for both models.
Closes #26709
* fix: update deepseek-v4 prices to active discounted rates
* test: update deepseek-v4 prices in tests to match active discounted rates
* fix(deepseek): remove duplicate entries and update backup registry to active discounted rates
* fix: update max_output_tokens to 384K for deepseek-v4
* fix: correctly restore upstream models accidentally dropped during merge
* fix(tests): resolve failing claude-fable-5 and reasoning tests by safely updating cost map
- Pulled the latest cost map from upstream staging
- Safely appended deepseek-v4 mapping without deleting duplicate keys or formatting via json.dump
* fix(tests): correct deepseek model cache prices and update JSON schema
- Appended both prefixed and bare deepseek-v4 models to satisfy test assertions
- Corrected deepseek-v4-pro expected cache hit and token prices based on latest review updates
- Added missing realtime endpoint to test_utils.py INTENDED_SCHEMA
* fix: remove accidental azure/gpt-realtime-whisper addition
---------
Co-authored-by: Dushyant Acharya <dushyantacharya@Dushyants-MacBook-Pro.local>
* feat(key/info): expose per-model budget usage in /key/info response (#30394)
* feat(key/info): expose per-model budget usage in /key/info response
Add model_max_budget_usage to /key/info and /v2/key/info responses.
For each model in model_max_budget, reads current-period spend from
the same DualCache used by the budget enforcer and returns it alongside
the limit and time period so callers can see how much of each model
budget has been consumed in the active window.
* test(key/info): add coverage for model_max_budget_usage in v1 and v2 endpoints
Add tests for the model_max_budget_usage enrichment in both info_key_fn
and info_key_fn_v2, covering the budget-present path, the empty-budget
path, and the v2 batch endpoint.
* fix(key/info): source model_max_budget current_spend from SpendLogs instead of DualCache
The DualCache used for enforcement is ephemeral and only populated when budget metadata
is present at request time. Fall back to a direct LiteLLM_SpendLogs DB aggregation
using the budget period window (budget_reset_at - budget_duration) for accurate reporting.
Also fall back to litellm_budget_table.model_max_budget when the key's top-level field
is empty, and round current_spend to 4 decimal places.
* test(key/info): cover remaining branches in model_max_budget_usage helpers
Add unit tests for: prisma_client=None early return, DB query exception swallowing,
invalid budget_duration handled by _compute_budget_period_start, budget_reset_at
received as a datetime object (Prisma native type), max_seconds=0 early return, and
skipping models that lack a budget_duration. Also remove an unreachable except branch
where fromisoformat would fail after _compute_budget_period_start already validated the
same value.
* test(key/info): cover except path for unparseable per-model budget_duration
* fix(key/info): compute per-model rolling windows in model_max_budget_usage
Each model in model_max_budget now gets its own time window derived from
its own budget_duration, rather than sharing a single window computed as
the max (or the budget table's reset_at). This matches what the DualCache
enforcer actually tracks and prevents current_spend from being inflated
for models with shorter windows.
_query_model_spend_for_period is refactored to accept a model filter
(handling provider-prefix variants in SQL) and return a float directly.
_compute_budget_period_start and the budget_table window path are removed
as they are no longer needed.
* refactor(model_max_budget_limiter): remove dead get_current_period_spend method
* refactor(key/info): strip synthetic formatter noise from PR diff
Restore key_management_endpoints.py and test_key_management_endpoints.py
to origin/litellm_internal_staging, then re-apply only the intentional
additions: _query_model_spend_for_period, _build_model_max_budget_usage,
the two endpoint patches (info_key_fn / info_key_fn_v2), and the new
test suite. The previous commits had reformatted ~300 pre-existing lines
across both files, making the functional diff unreadable.
* test(key/info): cover empty-rows path in _query_model_spend_for_period
* fix(model_max_budget_limiter): guard BudgetConfig construction inside try/except
A malformed model entry in the DB (e.g. non-numeric max_budget from a
manually edited or migrated row) caused BudgetConfig(**budget_info) to
raise a Pydantic ValidationError outside any exception guard, surfacing
as a 500 for the entire /key/info or /v2/key/info call. Merging both
try/except blocks into one ensures bad entries are silently skipped,
consistent with the existing duration_in_seconds guard.
* fix: don't stack provider prefix on wildcard models with a custom prefix (#30360)
* fix: don't stack provider prefix on wildcard models with a custom prefix
get_known_models_from_wildcard expanded provider-prefixed model ids (e.g.
"ollama/gemma3:1b" from get_provider_models) by prepending the wildcard's
prefix whenever the id did not already start with it. With a custom wildcard
prefix such as "ollama_server1/*" (used to distinguish multiple Ollama
instances), this produced "ollama_server1/ollama/gemma3:1b", which is
uncallable and breaks /v1/models.
When the expanded id already carries a provider prefix, replace it with the
wildcard's prefix instead of stacking both. Matching-prefix and bare-model
cases are unchanged.
Fixes #30358
* fix: only strip a known provider prefix when expanding custom wildcard prefixes
The wildcard expansion replaced the leading slash segment of every expanded id with the wildcard prefix whenever the id did not already start with it. For ids whose first segment is an org rather than a litellm provider (for example a provider returning "meta-llama/Llama-3-8B" with no outer provider prefix), that dropped the org and produced an uncallable id
Only strip the leading segment when it is a recognized provider (membership in LlmProviders); otherwise keep it and just prepend the wildcard prefix. Provider-prefixed ids like "ollama/gemma3:1b" still have their prefix replaced, so the original fix is unchanged for known providers
* address greptile review feedback: log dropped non-text vLLM assistant content blocks (greploop iteration 1)
* fix(ci): format credential_form_helpers test + regenerate dashboard schema.d.ts
* fix(proxy): raise litellm.BadRequestError for missing model param
When no model is passed, route_request now raises a litellm.BadRequestError
('Missing model parameter') instead of falling through to ProxyModelNotFoundError.
This keeps the missing-param error clear and independent of router wildcard
state. Unknown (non-empty) model names still raise ProxyModelNotFoundError.
* Revert "fix(proxy): raise litellm.BadRequestError for missing model param"
This reverts commit 9240da403c0432a80473d6c4677ddb7e2bad7420.
* Revert "fix(router): clean pattern_router state on upsert/delete (#29601)"
This reverts commit ad4e6e2395620ea6d2fe38089a54cde160720de2.
* fix: correct streaming and key budget usage reporting
* fix(hosted_vllm): type assistant tool_calls to satisfy mypy
* feat: aws secret manager cross region replication (#30368)
* feat(aws-secret-manager): add replica_regions cross-region replication after CreateSecret
When store_virtual_keys is enabled, async_write_secret() only wrote secrets
to the primary AWS region. Multi-region proxy deployments had no built-in
way to synchronize virtual key secrets across regions through LiteLLM,
requiring external replication mechanisms.
Add replica_regions support to AWSSecretsManagerV2:
- New replica_regions field in KeyManagementSettings (types/secret_managers/main.py)
- New async_replicate_secret() method that calls ReplicateSecretToRegions API
- async_write_secret() calls replication after successful CreateSecret
- Replication failure is logged as a warning but does NOT fail key creation
- load_aws_secret_manager() forwards replica_regions from key_management_settings
Configuration example:
key_management_settings:
store_virtual_keys: true
replica_regions:
- us-west-2
- eu-west-1
When replica_regions is omitted or empty, behavior is unchanged.
* test(aws-secret-manager): restore litellm.secret_manager_client after test to prevent state pollution
* test(aws-secret-manager): add coverage for HTTP error and replication exception paths
* fix: restore litellm.secret_manager_client global state in test; add replication log proof
- Global state in test_load_aws_secret_manager_passes_replica_regions was
already guarded with try/finally (committed in previous pass); no further
change needed for Fix 1.
- Fix 2: add verbose_logger.info("ReplicateSecretToRegions called …") inside
async_replicate_secret so callers get an observable INFO log line whenever
replication fires.
- Add test_replication_fires_on_create: calls async_replicate_secret directly
with caplog.at_level(INFO, logger="LiteLLM") and asserts "ReplicateSecretToRegions"
appears in the captured log output, proving the code path executes.
* fix: pass request to streaming generators
* fix(hosted-vllm): preserve assistant structured content
* fix(hosted_vllm): satisfy mypy on preserved structured content assignment
* chore: resolve litellm_internal_staging merge conflicts for #30527 (#30554)
* chore(codecov): add Batches, Videos, and Realtime components (#30517)
* chore(codecov): add Batches, Videos, and Realtime components
Define per-feature Codecov components so PR comments track coverage
for batch API, video generation, and realtime streaming paths.
Co-authored-by: Cursor <cursoragent@cursor.com>
* chore(codecov): use wildcard path for Batches proxy component
Align batches_endpoints glob with Videos, Realtime, and Proxy_Authentication.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
* test(batches): move orphan tests into tests/test_litellm for CI coverage (#30510)
Four batch-related tests lived under tests/litellm/ and were never picked
up by GitHub Actions. Relocate them and fix gemini multimodal e2e to use
the batchEmbedContents path expected for gemini/ provider.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(guardrails): run pre_call hook once for model-level guardrails (#30543)
* fix(guardrails): run pre_call hook once for model-level guardrails
A CustomGuardrail attached to a deployment via litellm_params.guardrails
gets its async_pre_call_hook invoked twice per request: once by the proxy
pre-call loop and again by async_pre_call_deployment_hook after the router
spreads the model-level guardrails into the top-level request kwargs.
Record in request metadata that the proxy pre-call loop already ran a given
guardrail, and have the deployment hook skip it when the marker is present.
Direct-SDK usage never runs the proxy loop, so the deployment hook stays the
sole invocation there and still fires exactly once.
The marker key is stripped from untrusted caller metadata so a request body
cannot suppress a model-only guardrail by pre-seeding it.
* fix(guardrails): mark pre_call dedup on the post-hook request data
Record the exactly-once marker after async_pre_call_hook runs, on the data
object that flows downstream, rather than before it. A guardrail whose hook
returns a brand-new request dict (instead of mutating or spreading the one it
received) would otherwise discard the marker, letting the deployment hook
re-run the guardrail a second time.
* fix(guardrails): stop re-initializing DB guardrails on every poll (#30542)
* fix(guardrails): stop re-initializing DB guardrails on every poll
InMemoryGuardrailHandler._has_guardrail_params_changed compared the
in-memory LitellmParams against the raw dict loaded from the DB. The
in-memory side carries every field default and coerces enums via
model_dump(), while the DB side only holds the keys originally stored,
so the two shapes never compared equal and the guardrail was rebuilt on
every poll cycle.
Each rebuild created a fresh instance, but delete_in_memory_guardrail
only removed the old callback from litellm.callbacks. Request handling
promotes guardrail callbacks into the success/failure/async lists, so
the previous instance stayed referenced there and instances accumulated.
Normalize both sides through LitellmParams(...).model_dump() before
diffing, and purge the callback from every callback list on delete.
* refactor(guardrails): narrow params-normalization fallback to ValidationError
The comparison normalizer caught a bare Exception and silently fell back
to the raw dict, which hid the cause and quietly degraded the affected
guardrail back to re-initializing on every poll. Catch only the
ValidationError that LitellmParams construction can raise, log a warning
so the offending row is diagnosable, and let any other error surface
instead of being swallowed.
* refactor(callbacks): add remove_callback_from_all_lists helper to manager
Move the knowledge of which callback lists a callback can be promoted
into out of the guardrail registry and into LoggingCallbackManager, where
the rest of the callback-list bookkeeping already lives. delete_in_memory_guardrail
now delegates to the new helper instead of iterating the lists itself.
* chore(oss): litellm oss staging 150626 (#30463)
* fix(pricing): add GitHub Copilot MAI Code Flash pricing (#30415)
* fix(pricing): add GitHub Copilot MAI Code Flash pricing
Add GitHub Copilot pricing entries for MAI-Code-1-Flash and the internal Copilot CLI model name so cost calculation can price input, cached input, and output tokens.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* test(pricing): cover GitHub Copilot MAI Code Flash pricing
Add regression coverage for both GitHub Copilot MAI-Code-1-Flash model names, including cached input pricing, chat endpoint metadata, and cost_per_token arithmetic.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(router/proxy): propagate completed_response through FallbackResponsesStreamWrapper for streaming /v1/responses container ownership (#30210) (#30213)
* fix(router/proxy): propagate completed_response through FallbackResponsesStreamWrapper for streaming /v1/responses container ownership (#30210)
#28990 added ownership recording for streaming /v1/responses via
_wrap_responses_stream_for_container_ownership, which reads
`getattr(stream_response, 'completed_response', None)` to extract the
ResponsesAPIResponse. The unit test bypassed the Router, so it never
exercised the production wrapping path.
Through the Router (every proxy deployment), the stream is wrapped by
FallbackResponsesStreamWrapper (router.py:2527). Its __init__ set
`self.completed_response = None` and __anext__ only forwarded chunks
— the inner source iterator's terminal event never bubbled up to the
attribute the ownership hook reads, so the hook silently recorded
nothing and every follow-up /v1/containers/<id>/files call returned
403 for non-admin keys.
This commit:
- router.py: pre-resolves the responses-API terminal event tuple
(response.completed / .incomplete / .failed) once per
_aresponses_streaming_iterator call, and has the wrapper's __anext__
sniff each forwarded chunk's .type. First terminal event hit gets
stored on the wrapper's completed_response. Iterator-agnostic — works
for source_iterator AND any future wrapper.
- common_request_processing.py: when _extract_completed_responses_response
returns None we now warn instead of silently skipping. Reporter on
#30210 lost a day to this exact silent skip; the warning surfaces
future regressions of the same shape directly in operator logs.
Fixes #30210
* fix(router): type-ignore wrapper getattr-defaults; broaden ownership-skip warning
CI lint (mypy) flagged the three pre-existing getattr(..., None) assignments
in FallbackResponsesStreamWrapper.__init__:
router.py:2564 self.response = getattr(source_iterator, 'response', None)
router.py:2565 self.model = getattr(source_iterator, 'model', None)
router.py:2566 self.logging_obj = getattr(..., None)
Those lines also exist on litellm_internal_staging and pass mypy there.
Adding the typed terminal-event tuple above the class made the function
body more narrowable, which surfaced the pre-existing mismatch — base
class declares non-Optional types but the bridge path
(LiteLLMCompletionStreamingIterator) legitimately omits these. Keep
the None fallback and silence with type: ignore[assignment].
Greptile 4/5 note: the ownership-skip warning hard-named code_interpreter
which misleads operators when a non-code_interpreter stream aborts.
Generalize to 'any tool container (e.g. code_interpreter)'.
* fix(register_model): drop synthesized zero costs to preserve sparse entries (#30198) (#30201)
* fix(register_model): drop synthesized zero costs to preserve sparse entries (#30198)
get_model_info synthesizes input_cost_per_token / output_cost_per_token = 0
when they are absent from the raw entry (the price-unknown and free cases
share the same representation). register_model then merges that result back
into litellm.model_cost, which flips a sparse entry from 'no cost keys'
(priced via model name) to 'cost keys = 0' (free).
That defeats _is_cost_explicitly_configured (#24949) on re-registration:
_is_model_cost_zero returns True, common_checks skips every tag / key /
team / user / org budget check for the group, and over-budget traffic
keeps returning 200. Spend keeps recording because cost calc still resolves
by model name, so the symptom is silent and only triggers on the second
register_model pass (router rebuild, /model/update, config sync).
Mirror the existing litellm_provider-None guard one block above and pop
the cost fields from the synthesized result when they are absent from the
raw entry and not in the caller's value. Caller-provided zeros (genuinely
free models, BYOK overrides) are preserved.
Fixes #30198
* fix(register_model): switch _raw_entry to is-None checks + drop dead test assertion
Greptile #30201 review notes:
- the `or`-chain in the raw-entry lookup treated an empty dict (a key
with no fields) as falsy and fell through to the second arm — replace
with explicit `is None` checks so a present-but-empty entry is still
taken at face value.
- the first assertion in `test_router_double_init_keeps_db_model_entry_sparse`
used `in (None, 0)` which passes under the bug condition (cost = 0
matches the tuple); the strong follow-up assertion already covers
every shape, so drop the dead branch.
* fix(bedrock mantle): use unique function-call id for responses->chat tool calls (#30426)
* fix(bedrock mantle): use unique function-call id for responses->chat tool calls
...
* fix(bedrock mantle): scope unique tool-call id fallback to degenerate call_id
The previous revision preferred the Responses item id for every tool call, which broke providers (and existing tests) where call_id is a unique, canonical correlation key. Restrict the fallback to the degenerate index-based call_id that Bedrock Mantle returns (call_0, call_1, ... resetting per response) and keep call_id otherwise. Revert the change to the OUTPUT_ITEM_DONE streaming handler, whose tool_call_chunk is never emitted (dead code, per review). Extend the regression tests to assert a normal call_id is preserved.
* fix(router): preserve azure_ad_token through CredentialLiteLLMParams for /v1/files + batches (#30235) (#30241)
* fix(router): preserve azure_ad_token through CredentialLiteLLMParams for /v1/files + batches (#30235)
Router.get_deployment_credentials_with_provider re-validates a
deployment's litellm_params through CredentialLiteLLMParams before
handing them to file/batch/passthrough callers:
return CredentialLiteLLMParams(
**deployment.litellm_params.model_dump(exclude_none=True)
).model_dump(exclude_none=True)
Any field NOT declared on CredentialLiteLLMParams gets silently dropped
on the way through. azure_ad_token was undeclared, so Azure deployments
using OAuth/M2M (azure_ad_token instead of a static api_key) silently
lost their token at the files endpoint and the proxy returned:
Missing credentials. Please pass one of api_key, azure_ad_token,
azure_ad_token_provider, ...
Declare azure_ad_token on CredentialLiteLLMParams alongside api_key /
api_base / api_version so it rides through the round-trip. Static-key
deployments stay unaffected (Optional, default None, dropped by
exclude_none=True). Provider-callable (azure_ad_token_provider) is a
separate concern and out of scope here.
Fixes #30235
* fix(ui-types): regenerate schema.d.ts for new azure_ad_token field
CI's 'Verify schema.d.ts matches the proxy OpenAPI spec' check
auto-detected the new field and emitted the exact diff to apply.
Two schemas had `aws_secret_access_key` from CredentialLiteLLMParams,
both get the new azure_ad_token marker next to it.
* fix(proxy): org_admin with own user_id now sees all org teams on /v2/team/list (#30247)
When the UI sends the callers own user_id (as it does for non-Admin
global roles), _enforce_list_team_v2_access now nulls it out for org
admins so _build_team_list_where_conditions scopes by organization_id
only -- matching the legacy /team/list behavior and the documented intent.
Fixes #30215
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* test(vertex_ai): multi-region regression coverage for cachedContents host (#29571) (#29707)
litellm_internal_staging already routes the cachedContents URL through
get_vertex_base_url, fixing the multi-region 404 reported in #29571 —
but carries no test coverage for the actual regression scenario (eu/us
must resolve to the REP host aiplatform.{geo}.rep.googleapis.com).
Add TestContextCachingMultiRegionUrls: parametrized eu/us REP-host
assertions (including absence of the old broken {geo}-aiplatform host),
plus regional (us-central1) and global no-regression checks.
* fix(proxy): close upstream LLM stream when client disconnects mid-stream (#30245)
* fix(proxy): close upstream LLM stream when client disconnects mid-stream
When a streaming client disconnects, Starlette abandons the response
body iterator without calling aclose(), so the proxy's connection to
the upstream backend stays open until garbage collection, which may
never come. The backend (e.g. vLLM) keeps generating into a dead pipe:
small responses drain invisibly into TCP buffers while large ones block
the backend on a full send buffer indefinitely (observed via lsof as an
ESTABLISHED proxy->backend connection minutes after the client left)
create_response now returns a StreamingResponse subclass that closes
both its body iterator and the wrapped upstream-facing generator in a
shielded finally. The upstream generator is closed directly rather than
through a cascade because aclose() on a never-started generator skips
its body, which would make the cascade a no-op when the client
disconnects before the first chunk is sent.
async_streaming_data_generator also gains the same shielded
finally-aclose that async_data_generator in proxy_server.py already
had, covering the Anthropic and Google SSE paths
With this, killing a streaming client causes the backend to observe the
abort within about a second and free its slot, while completed streams
are unaffected. No flag is needed, unlike the non-streaming opt-in
cancel in #30223: this only releases resources after the client is
already gone and does not change any response a client can observe
Fixes #30244
* fix(proxy): close upstream even when body iterator aclose raises BaseException
Addresses the Greptile finding on #30245: the cleanup loop caught only
Exception while the generator-level cleanup catches BaseException, so a
CancelledError or GeneratorExit escaping body_iterator.aclose() would
skip closing the upstream generator. Both sites now use the same scope
and a regression test pins that the upstream is closed even when the
body iterator explodes with a BaseException
* fix(llms): expose aclose on BaseModelResponseIterator so stream close reaches the provider connection
The response-level close added for #30244 only worked for SDK-based
providers (e.g. openai), whose streams expose aclose all the way down.
Providers served by base_llm_http_handler (hosted_vllm and most modern
transformation-based providers) wrap a bare response.aiter_lines()
generator in BaseModelResponseIterator, which had no aclose or close at
all, and nothing retained the httpx response object; so
CustomStreamWrapper.aclose() silently did nothing and the upstream
connection stayed open. Verified with a vLLM-style mock: with
hosted_vllm/ the backend streamed all 100 chunks to completion after
the client disconnected, while openai/ aborted at chunk 6
BaseModelResponseIterator now carries an optional http_response and an
aclose() that closes it; make_async_call_stream_helper attaches the
response after building the iterator. With this, hosted_vllm aborts the
backend within ~1.6s of the client dropping, and completed streams are
unaffected
---------
Co-authored-by: kursad <kursad.lacin@brado.net>
* feat(anthropic): surface compaction usage iterations data (#27065)
* feat(anthropic): surface compaction usage iterations data
* style: apply black formatting to fix lint checks
* fix(usage): correct calculate usage with cached tokens when use ChatCompletionUsageBlock (#30422)
* fix(usage): correct calculate usage with cached tokens when use ChatCompletionUsageBlock
* fix(usage): optimize test imports
* feat: add fastCRW search provider (#30434)
* feat(provider): add LibertAI as a JSON-configured OpenAI-compatible provider (#30203)
* feat(provider): add LibertAI as a JSON-configured OpenAI-compatible provider
* libertai: update served endpoints backup + add mode/matrix tests
Addresses review feedback:
- Add libertai to litellm/provider_endpoints_support_backup.json, the file
actually served by GET /public/supported_endpoints (the root
provider_endpoints_support.json already had it).
- Add tests asserting bge-m3 normalizes to mode='embedding' and that the
served matrix lists libertai. embeddings stays false: the JSON-configured
provider path only wires chat routing (OpenAILike embedding handler is
reached only for literal openai_like/llamafile/lm_studio), matching the
llamagate precedent; bge-m3 remains in the cost map for metadata.
---------
Co-authored-by: Moshe Malawach <moshemalawach@users.noreply.github.com>
* feat(provider): add ModelScope as an OpenAI-compatible provider (#28460)
* add ModelScope API support
* add modelscope api support
* update modelscope model list
* add image-genetation support
* update test and multimodal
* fix: address PR review feedback for modelscope provider
* update README
* fix(customer_endpoints): restrict /customer/daily/activity to admin-only (#28849)
* fix(customer_endpoints): restrict /customer/daily/activity to admin-only
* fix(customer_endpoints): check role before prisma_client guard
* fix(custom_guardrail): key disable_global_guardrails takes precedence over team guardrail list (#28563)
* fix(fallbacks): preserve fallback model in SDK fallback responses (#28260)
* fix(fallbacks): preserve fallback model in response when using SDK-level fallbacks
* fix(fallbacks): gate x-litellm-* passthrough to trusted callers only
The previous patch unconditionally let `x-litellm-*` keys bypass the
`llm_provider-` prefix in `process_response_headers`. That function is
also called on raw upstream-provider response headers (e.g. from
`llm_http_handler.py`), so a malicious provider could return
`x-litellm-attempted-fallbacks` and spoof a LiteLLM-internal marker,
bypassing the proxy model-override guard.
Add a `preserve_litellm_internal_headers` flag (default False). Only
`response_metadata.py`, which re-processes the already-built
`_hidden_params["additional_headers"]` dict (LiteLLM-owned), passes
True. Raw provider header callsites keep the default False, so upstream
`x-litellm-*` still gets the `llm_provider-` prefix.
Adds a regression test for the spoofing case and renames the existing
preserve test to make the trusted-path semantics explicit.
* fix(fallbacks): ignore preserve_litellm_internal_headers for raw httpx.Headers inputs
* style(core_helpers): apply black formatting
* fix(lint): remove banned typing.List/Dict/Any imports and suppress PLR0913 on interface overrides
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(lint): apply black formatting to modelscope chat transformation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(lint): replace noqa with proper fixes — use **kwargs and Awaitable instead of Any/List
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(lint): remove unused AllMessageValues import
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* revert: restore base_model_iterator.py to original PR state
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(lint): restore full method signatures for MyPy compatibility; bump PLR0913 budget for new provider files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(lint): use @override to suppress PLR0913 on inherited signatures instead of bumping budget
The overrides keep their full base-class signatures for MyPy compatibility, but those signatures carry more than five parameters, which tripped PLR0913 on each subclass redeclaration. Since the arity is dictated by the base class and cannot be reduced, decorate the overrides with typing_extensions.override; ruff treats that as the intended signal that the parameter count is not under the author's control and skips PLR0913. This restores the PLR0913 baseline to 1813.
* fix(lint): add @override to modelscope image generation overrides
Apply the same typing_extensions.override treatment to the image generation config so its inherited-signature overrides do not count against PLR0913.
---------
Co-authored-by: Joel Tony <github@jaytau.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: hcl <chenglunhu@gmail.com>
Co-authored-by: ztko <96878659+koztkozt@users.noreply.github.com>
Co-authored-by: Nahrin <nahrin@nahrinoda.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Humphrey <a739376838@gmail.com>
Co-authored-by: kursadlacin <kursadlacin@gmail.com>
Co-authored-by: kursad <kursad.lacin@brado.net>
Co-authored-by: Dushyant Acharya <dushyantacharya873@gmail.com>
Co-authored-by: Yuriy <yuriy.shuyskiy@gmail.com>
Co-authored-by: Recep S <22618852+us@users.noreply.github.com>
Co-authored-by: Moshe Malawach <moshe.malawach@protonmail.com>
Co-authored-by: Moshe Malawach <moshemalawach@users.noreply.github.com>
Co-authored-by: Rongkun Yan <2493404415@qq.com>
Co-authored-by: Varshith <kvarshithgowda@gmail.com>
Co-authored-by: Mateo Wang <277851410+mateo-berri@users.noreply.github.com>
* ci(lint): add blanket-noqa, dataclass-default, and unused-noqa Ruff rules (#30516)
* ci(lint): enforce blanket-noqa, dataclass-default, and unused-noqa rules
Enable PGH004 (blanket-noqa), RUF008 (mutable-dataclass-default),
RUF009 (function-call-in-dataclass-default-argument), and RUF100
(unused-noqa) in ruff.toml, and clean up every resulting violation.
RUF008/RUF009 were already clean. PGH004/RUF100 surfaced ~335 stale or
blanket noqas: blanket `# noqa` are now scoped to the rule they actually
suppress (mostly T201), dead directives are removed, and inapplicable
codes are trimmed (e.g. F401 dropped from `import *`).
lint.external lists rules enforced outside this config (the strict-rule
gate via ruff-strict.toml and upstream litellm's own ruff config) so
RUF100 keeps the noqa directives that protect them instead of stripping
coverage this config can't see.
* ci(lint): trim RUF100 external list to load-bearing codes only
Drop the 9 precautionary strict-gate codes (ANN001/002/003/401, B006,
PLR0913, PLW0603, RUF012, TID251) that have zero `# noqa` references in
the gated source. Keep only the 11 codes with live suppressions so
RUF100 doesn't flag them as unused. Future strict-gate suppressions can
re-add codes here (or fix the underlying issue) as needed.
* ci: ratchet lint and type-check gates (ruff preview, ANN, mypy, basedpyright) (#30379)
* ci: enable ruff preview rules under the budgeted strict gate
Turn on ruff preview in the strict-budget lane (ruff-strict.toml) only,
leaving the clean gate (ruff.toml) untouched so make lint-ruff stays at
zero. Enumerate the 118 firing codes explicitly with
explicit-preview-rules so the gate is deterministic and stable across
ruff upgrades rather than depending on preview auto-selecting the broad
catalog.
Grandfather the existing 58438 violations into ruff-strict-budget.json
as per-rule baselines with headroom, so only net-new violations fail CI.
The existing ten rules keep their hand-tuned slack; the new rules get
slack 10 when the baseline is 50 or more and 3 otherwise.
* ci: add ANN return-type rules to the budgeted strict gate
Add ANN201/202/204/205/206 (missing return annotations) to the strict
lane and grandfather the existing counts into ruff-strict-budget.json so
the codebase ratchets toward explicit return types without breaking CI.
* ci: add mypy (disallow_untyped_defs) and basedpyright strict gates with baselines
Add two type-check gates, each grandfathering the current tree so only
net-new violations fail CI, matching the ruff strict-budget ratchet.
mypy gains disallow_untyped_defs in litellm/mypy.ini (the config the CI
invocation actually reads; the root [tool.mypy] is not picked up from the
litellm/ working dir). The 4885 existing missing-annotation errors are
captured in litellm/.mypy-baseline.txt and the run is piped through
mypy-baseline filter so new untyped defs are rejected.
basedpyright runs in strict mode over litellm/, with
enableTypeIgnoreComments disabled so it only honors '# pyright: ignore'
and never polices mypy's '# type: ignore'. The existing strict diagnostics
are grandfathered into .basedpyright/baseline.json.
Both tools are pinned in the dev group and uv.lock; the lint workflow and
Makefile run them filtered through their baselines, with
lint-mypy-baseline-update and lint-basedpyright-baseline-update to ratchet.
* ci: raise lint job timeout to 15m for the basedpyright strict pass
* ci: pin pythonVersion 3.12 and regenerate baselines against merged base
Merge litellm_internal_staging so the baselines cover code the CI merge
includes (e.g. the cisco_ai_defense guardrail), which otherwise tripped
the mypy gate with 3 ungrandfathered no-untyped-def errors. Pin
pythonVersion 3.12 in pyrightconfig so basedpyright's strict analysis is
reproducible across interpreter versions (CI runs 3.12).
* ci: regenerate basedpyright baseline against the frozen lint env
The previous baseline was generated with optional provider deps (azure,
google, anthropic, mcp, numpydoc, google-genai) installed locally, so CI's
dev-only env surfaced ~3500 reportUnknown*/reportMissingTypeStubs errors
not in the baseline. Regenerate after uv sync --frozen so the baseline
reflects the same dependency set the lint job sees.
* ci: regenerate basedpyright baseline on python 3.12 frozen env
The prior baseline still carried proxy-dev packages (e.g. prisma) that the
lint job's dev-only, python 3.12 env lacks, leaving 2 unresolved-import
errors ungrandfathered. Regenerate in a python 3.12 venv synced to the
frozen lock with default groups only, so the baseline matches exactly what
CI sees.
* ci: replace type-check baselines with per-file count budgets
The mypy and basedpyright baselines were position-sensitive (and the
basedpyright one was a 27MB file), so ordinary line shifts churned them.
Replace both with a per-file count gate: scripts/type_check_gate.py reduces
each tool's output to errors-per-file and checks it against a committed
{file: max} budget, ignoring line and column numbers. A file fails only
when it gains more errors than its ceiling; debt can't be shuffled between
files because each file has its own cap and new files default to zero.
Budgets (mypy-file-budget.json 48K, basedpyright-file-budget.json 96K) are
generated in the python 3.12 frozen lint env so they match CI. Drops the
mypy-baseline dependency; basedpyright runs without its native baseline.
ratchet via make lint-mypy-budget-update / lint-basedpyright-budget-update.
* ci: add a small per-file slack to the type-check gate
Allow each file to drift PER_FILE_SLACK (5) errors past its recorded count
before failing, so a basedpyright inference ripple in an unrelated file
doesn't break the build over a couple of errors. Budgets still record exact
counts; the tolerance is applied at check time.
* ci: move type-check slack into the budget json and trim lint timeout
Make slack declarative: the budget is now {"slack": N, "files": {path: count}}
so the tolerance is tuned in JSON without editing the script, mirroring how
ruff-strict-budget.json carries its slack. --update preserves the existing
slack. Also drop the lint job timeout from 15m to 10m; the mypy and
basedpyright passes add ~2m, leaving the job around 4-5m, so 10m is a
comfortable margin.
* ci: collapse fully-adopted ruff categories and drop inert preview flag
ANN (all nine non-removed rules) and BLE (its only rule) were spelled out
code-by-code; replace each with its category selector, which is exactly
equivalent in 0.15.3 (the removed ANN101/ANN102 are skipped by a category
selector and error when named explicitly). explicit-preview-rules was inert:
every selected rule is stable and nothing is selected by category, so the flag
had nothing to gate. Verified the strict-rule counts are identical before and
after (62379 each, zero per-rule drift), so no budget change.
* ci: drop redundant pyright dev dependency
Nothing invokes bare pyright in the Makefile, the linting workflow, or
scripts; the basedpyright gate added on this branch is the only type
checker that runs. based…
* fix(guardrails): return 400 not 500 when AIM blocks a request AIM guardrail blocks raised a bare HTTPException whose type and param serialized as the literal string "None", which broke OpenAI-SDK error parsing for downstream consumers. Switching AIM to raise a ProxyException surfaced a second bug: the shared error funnel re-derived the HTTP status from a nonexistent status_code attribute and downgraded the 400 to a 500. The funnel now honors an already-normalized ProxyException rather than rebuilding it, and ProxyException is excluded from llm_exceptions alerting so a content-policy block no longer pages on-call as an LLM API failure Resolves LIT-3751 * fix(guardrails): route all AIM rejection paths through ProxyException The block-action fix left two AIM rejection paths raising a bare HTTPException: the multimodal anonymize rejection and the output-side block. Both serialized type and param as the literal string "None", the same malformed shape the block fix removed. Funnel all three through a shared _rejection helper so they return a conformant OpenAI error body. The output block carries content_policy_violation; the multimodal rejection stays a plain invalid_request_error because it is a usage error, not a policy violation Resolves LIT-3751 * fix(guardrails): record AIM ProxyException blocks in failure logs Switching AIM blocks from HTTPException to ProxyException made _is_proxy_only_llm_api_error return False for them, so _handle_logging_proxy_only_error was skipped and the blocked prompt was dropped from the configured failure loggers. Classify ProxyException as a proxy-only error alongside HTTPException so guardrail blocks are recorded again, matching the prior behavior. The llm_exceptions alert suppression is a separate check and stays in place Resolves LIT-3751 * style(guardrails): use str | None over Optional[str] in AIM _rejection * style(guardrails): collapse AIM _rejection signature per black
…50% headroom) (#30582) * ci(lint): grandfather any-discipline with a per-file ratchet budget (50% headroom) The any-discipline gate previously failed on any Any-typed value touched on a changed line, which tripped on merely editing a legacy `X | Any` line. Switch it to a per-file budget: `any-discipline-budget.json` records each file's current Any count and a changed file fails only when its count exceeds `baseline + slack` (50% headroom, rounded up). New/unbudgeted files have baseline 0, so they stay airtight, while editing legacy files no longer forces cleaning pre-existing debt. Only changed files are re-type-checked (per-PR cost unchanged); the whole-tree scan to recapture the budget runs under `--update` (`make lint-any-budget-update`). The budget is a one-way ratchet guarded by `budget_ratchet_check.py`, matching the ruff/mypy/basedpyright budgets, and folds into `make lint-budget-update`. Also fixes a RecursionError in `contains_any` (recursive type aliases yield fresh objects per unfold, defeating the id() cycle guard) by walking iteratively with a depth cap, exposed by the whole-tree scan. * chore: make CLAUDE.md more concise * chore: rearrange Makefile * ci(lint): make any-budget --update git-failure-safe; clarify over-budget message all_litellm_py_files now returns None when git is unavailable (mirroring changed_line_map) instead of letting CalledProcessError/FileNotFoundError escape as a raw traceback, and update_budget reports a clean setup error (exit 2) for that case. The list-files dependency is injected so the path is unit-testable without monkeypatching. The over-budget diagnostic now reads "N value(s) total, over budget" so the count isn't misread as the excess over the ceiling. * ci(lint): exempt the file-keyed any-discipline budget from the ratchet's dropped-entry rule budget_ratchet_check treats a vanished budget entry as a loosening (an untracked rule whose ceiling is now unbounded). That holds for the rule-keyed budgets, but the any-discipline budget is keyed by file and its gate treats an absent file as ceiling 0 (the file must be Any-free). Cleaning a file to zero drops its entry on the next --update, so the generic rule flagged that as a regression: a false- positive red on exactly the cleanup the ratchet exists to encourage. Exempt the file-keyed budget from the dropped-entry rule while still catching a raised ceiling.
…#30599) * fix(audio): don't override explicit response_format with verbose_json * fix(audio): handle plain-text response body for response_format=text * fix(audio): only swallow non-JSON transcription body when not declared JSON Guard the plain-text fallback in transform_audio_transcription_response with the response Content-Type: a body that fails json() but is labelled application/json is a genuine upstream error and is re-raised, while text/plain bodies (response_format=text) are still returned as-is. Prevents a malformed JSON 2xx from silently becoming a transcription of garbled bytes. * fix: normalize content-type header case in whisper transcription fallback * test(audio): lock in case-insensitive content-type guard for transcription fallback Adds a regression test that a mixed-case 'Application/JSON' content-type still re-raises a malformed JSON body, covering the case-insensitivity fix in 72982e4 (removing the .lower() normalization fails this test). --------- Co-authored-by: cohml <62400541+cohml@users.noreply.github.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* fix(proxy): optionally surface public team model name in /v1/models
Behind general_settings.use_team_public_model_name (default False). When
enabled, /v1/models and /models surface the public team_public_model_name
for team-scoped (BYOK) models instead of the internal routing key
model_name_{team_id}_{uuid} -- consistent with /v1/model/info and
OpenAI-compatible. Off by default so the listing's model ids stay
backward-compatible for callers that scripted against the internal name;
routing by the internal name is unchanged regardless of the flag.
Presentation-layer only: access-group, auth, and routing semantics are
unchanged; non-team models are pass-through.
* fix(proxy): default team model listings to public names
* test(proxy): cover team model listing metadata
* test(proxy): cover empty team listing deployments
* refactor(proxy): simplify team model listing translation
* fix(proxy): resolve public team model name on GET /v1/models/{id}
The listing endpoints advertise team_public_model_name, but the retrieve
endpoint validated and looked up by the raw id, so a public name 404'd.
Resolve the public name back to the internal routing key (scoped to the
caller's accessible models so colliding names never cross teams), look up
by it, and echo the public name back as the response id.
* test(proxy): cover public-name resolution on model retrieve
* refactor(proxy): extract team model-name translation into TeamModelNameTranslator
Move the team-scoped (BYOK) listing/retrieve name translation out of
proxy_server.py into a dedicated common_utils module. Static methods with
general_settings injected so the logic is unit-testable without globals and
proxy_server.py stays thin.
* refactor(proxy): use TeamModelNameTranslator in model_list and model_info
* test(proxy): target TeamModelNameTranslator for model-name translation
* fix(proxy): type create_model_info_response return as dict[str, object]
* fix(proxy): keep internal routing key for team model listing metadata lookup
Add listing_entries returning (public response id, internal lookup id) so
include_metadata=true resolves fallbacks against the routing key the router
indexes by, instead of the translated public name (which never matches).
* fix(proxy): build /v1/models metadata from internal key, show public id
* test(proxy): cover team listing fallback metadata via internal key
* fix(proxy): use builtin dict generics in create_model_info_response (UP006)
---------
Co-authored-by: Tushar More <tusharmore8408@gmail.com>
Co-authored-by: Ishaan Jaffer <ishaanjaffer0324@gmail.com>
…0648) * ci: drop redundant mypy type-check gate, standardize on basedpyright Type checking ran both mypy (via the pydantic.mypy plugin) and basedpyright. pydantic v2 emits dataclass_transform, so basedpyright understands models natively with no plugin, and its gated rules already cover what the mypy pass caught (no-untyped-def, no-any-return, valid-type, import-not-found all map to basedpyright equivalents). Running both meant two checkers, two budgets, and a plugin only mypy could load. This removes the mypy type-check gate: the lint-mypy/lint-mypy-budget-update Makefile targets, the CI MyPy step, mypy-code-budget.json, the budget-ratchet entry, and the vestigial [tool.mypy] pydantic plugin block (the gating pass used litellm/mypy.ini, which never loaded the plugin). type_check_gate.py is specialized to basedpyright since the mypy parsing path is now unused. mypy stays a dev dependency because the Any-discipline gate (scripts/check_any_discipline.py) imports it as a library to detect Any-typed values; it is no longer run as a type checker. * ci: remove the Any-discipline gate, rely on basedpyright's reportAny The Any-discipline gate (scripts/check_any_discipline.py) was the last consumer of mypy: it imported mypy as a library to detect values whose inferred type contains Any, gated per-file against any-discipline-budget.json. basedpyright already reports the same class of finding through reportAny/reportExplicitAny, which are gated tree-wide in basedpyright-code-budget.json, so the separate gate (and the mypy dependency behind it) is redundant. Removes the gate end to end: check_any_discipline.py and its test, the any-discipline CI job, the lint-any/lint-any-budget-update Makefile targets, any-discipline-budget.json, litellm/mypy.ini, the .mypy_cache_any references, and mypy from the dev dependencies. budget_ratchet_check.py drops the any-discipline entry and the now-unused zero-floor mechanism (rewritten as a comprehension). check_type_discipline.py drops the any-ok suppression token, since # any-ok suppressed only the deleted gate; the 134 now-orphaned # any-ok comments across 14 files are stripped (they never affected basedpyright, which uses # pyright: ignore). uv.lock is intentionally left untouched: uv still considers it consistent with the mypy-removed pyproject (uv lock --check and uv sync --frozen both pass), and a relock bumps 30+ unrelated packages because of the moving exclude-newer window. A future intentional relock will prune the now-unreferenced mypy entry. * build: relock to drop mypy from uv.lock CI's uv 0.10.9 honors the repo's exclude-newer window and correctly flags the lockfile as out of sync once mypy leaves pyproject; my earlier local uv 0.8.17 could not parse exclude-newer and silently passed --check. Relocking with the pinned CI version removes only mypy and its transitive librt, with no other version changes.
…uardrail traces (#30659) The OpenAI moderation guardrail (and the ai-platform-moderation guardrail built on it) stamped the whole moderation model response into the guardrail trace as guardrail_response. That blob carries the full category_scores map plus categories and category_applied_input_types, which on OTEL backends that index span attributes (for example ELK, which caps indexed attribute values at 1024 chars) overflows the limit and gets truncated, so the violated categories cannot be reliably searched. Extract the flagged category names from the moderation response and pass them through tracing_detail to add_standard_logging_guardrail_information_to_request_data, mirroring the Bedrock hook. Both the legacy and v2 OTEL integrations already read violation_categories off the standard logging guardrail information and emit it as a short, queryable guardrail_violation_categories attribute, so dashboards can group and filter by violation category without parsing the large guardrail_response blob. Resolves LIT-3801
…#30495) * fix(proxy): resolve list files credentials from team BYOK deployments GET /v1/files without target_model_names now prefers the team's own deployment (model_info.team_id) over shared global provider keys, so JWT team auth lists files against the correct upstream account. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(proxy): scope list files credential lookup to team allowlist Remove the unrestricted deployment scan that could leak global provider keys to teams without access, normalize all-proxy-models to the team-scoped model list, and fix TID251 violations by using dict instead of Dict/Any. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…er restarts (#30601) Setting --max_requests_before_restart alone recycles every worker at almost the same time once they have served a similar number of requests, which under sustained load can drop a whole pod's capacity at once roughly every 7-10 days. This exposes a jitter knob that adds a random amount in [0, jitter] to the restart threshold per worker so restarts are staggered. It maps to uvicorn's limit_max_requests_jitter and gunicorn's max_requests_jitter. uvicorn only gained limit_max_requests_jitter in 0.41.0 while litellm still allows uvicorn>=0.33.0, so the uvicorn path feature-detects the parameter via the Config signature and warns instead of crashing on older versions. The flag has no effect without --max_requests_before_restart, so the kwarg is not forwarded in that case and a warning is printed on both the uvicorn and gunicorn paths. Resolves LIT-3774
* fix(health): correct bedrock embedding health checks
Health checks for Bedrock embedding deployments failed in two ways. A
deployment configured without an explicit model_info.mode was probed as
chat, so max_tokens was injected and Bedrock embeddings rejected it with
400 "extraneous key [max_tokens]". Separately, stripping the bedrock/
routing prefix dropped the provider, so a cross-region inference-profile
id like us.cohere.embed-v4:0 failed downstream with "LLM Provider NOT
provided".
Resolve the deployment mode from the model cost map (which understands
the bedrock/ and us./eu./apac. prefixes) before deciding whether to
inject max_tokens, and pin custom_llm_provider to bedrock when stripping
the prefix so the bare model id still resolves. ahealth_check now accepts
any string mode so the resolved embedding mode routes the probe to the
embedding handler.
* fix(health): preserve explicit custom_llm_provider on bedrock probe
The bedrock prefix-strip pinned custom_llm_provider to bedrock
unconditionally, so a deployment that set custom_llm_provider:
bedrock_converse had it overwritten at health-check time and the probe
hit the Invoke endpoint instead of Converse, a different request format
that can report a spurious failure. Only fill in bedrock when the
deployment left the provider blank, which still resolves bare
cross-region ids like us.cohere.embed-v4:0 while leaving an explicit
provider untouched.
* test(health): assert resolved mode reaches the ahealth_check probe
The existing tests check _resolve_health_check_mode and the params builder
in isolation, but nothing verified that _run_model_health_check actually
threads the resolved mode into litellm.ahealth_check. Without that, a
refactor that probed with model_info.get("mode") again would reintroduce
the chat fallback for embedding deployments while every test stayed green.
This drives _run_model_health_check with a bedrock embedding deployment and
asserts the probe is called with mode=embedding and the embedding params.
* fix(health): resolve probe mode once for reasoning_effort and audio_speech
The reasoning_effort and audio_speech branches read model_info.mode
directly, so an embedding deployment declared without an explicit mode (the
case this PR targets) was still treated as chat-like: a configured
health_check_reasoning_effort got injected into the embedding probe, which
embeddings reject as an unknown field, and an auto-detected audio_speech
deployment never had its voice set. Resolve the effective mode once from the
cost map and reuse it for the max_tokens, reasoning_effort, and audio_speech
decisions so they all agree with the mode threaded into ahealth_check.
…ruby assistants timeout) (#30685) * test(proxy): poll for image-gen spend instead of a fixed 5s sleep test_key_info_spend_values_image_generation failed once on litellm_internal_staging (pipeline 82282) with "spend did not increase on an identical repeat image call" (assert 0.24966 > 0.24966). The test made the second image call, slept 5s, then read the key's spend once. Response caching is commented out in proxy_server_config.yaml and no sibling test enables it, so the likely cause is async/batched spend logging not having flushed the repeat call's cost within 5s, which the build_and_test job aggravates by running every tests/test_*.py against one shared proxy under pytest -n 4. Poll the key's spend for up to 60s and break as soon as it grows. This removes the timing flake while preserving the canary: if the repeat were genuinely unbilled (for example the proxy response cache being on), spend never grows, the poll times out, and the assertion still fails. * test(pass_through): raise ruby assistants client request_timeout to 600s The streaming assistants example in openai_assistants_passthrough_spec.rb hit Net::ReadTimeout on litellm_internal_staging (pipeline 82280), failing at roughly 125s which is ruby-openai's default request_timeout of 120s. An assistants run with the code_interpreter tool can occasionally take longer than that to stream its first content back through the pass-through. Raise the client's request_timeout to 600s, matching the 600s timeout the Python pass-through e2e tests already use, so a slow-but-healthy streaming run no longer trips the default read timeout.
…ty reads (#30683) test_basic_vertex_ai_pass_through_with_spendlog failed intermittently on litellm_internal_staging (pipelines 82155, 82196, 82209, 82230) with "Spend should be greater than before after 120s". Spend logging is async and batched, so the pass-through call's cost sometimes had not landed within the 120s poll window; one run ended on spend_after 0.0 because the final /global/spend/logs read returned nothing and "or 0.0" recorded that as zero spend. Widen the poll window to 240s and skip a transient empty read instead of treating it as 0.0, so a momentary endpoint hiccup on the last poll no longer fails an otherwise-billed call. The spend_after > spend_before assertion is unchanged, so a genuinely unbilled call still fails the test
…racking (#30690) completion_cost read service_tier straight from the request optional_params and called service_tier.lower() on it, so a non-string value (dict/int/list, reachable via allowed_openai_params/drop_params) raised AttributeError. _response_cost_calculator swallowed that and returned response_cost=None, so the request's cost was silently lost. The isinstance guard alone is not enough: a surviving dict would crash again downstream in _get_service_tier_cost_key, which also calls .lower(). A request-level service_tier is only meaningful for pricing when it is a concrete billable tier string, so coerce any non-string value to None and defer to the tier the provider reports on the response usage, the same way "auto" already does. Adds a regression test driving a dict service_tier through completion_cost; it raises AttributeError before the fix and prices at the served tier after.
…orcement (#30665) When general_settings.custom_auth is configured but custom_auth_run_common_checks is not set, project/team/org enforcement (budgets, model-level rate limits, and model-access lists) silently does nothing for custom-auth requests, since the centralized common_checks gate returns early for custom auth. Emit a startup warning pointing operators at the flag so the misconfiguration is visible instead of failing silently.
…oding (#30600) acquire_lock stores the pod_id through async_set_cache, which JSON-encodes the value, so Redis holds the quoted string "<pod_id>". release_lock's Lua compare-and-delete compared the raw pod_id, so the equality check never matched and the lock was never deleted; it only cleared on TTL expiry. That stalled the spend-update drain whenever the leader pod restarted, letting the litellm_daily_*_spend_update_buffer lists grow unbounded in Redis. Compare against json.dumps(self.pod_id) so the release matches the stored value. The GET+DEL fallback already round-trips through async_get_cache and is unaffected. Co-authored-by: Claude <noreply@anthropic.com>
…ck (#30695) Several CI jobs run the proxy against a model whose api_base is a shared "fake OpenAI endpoint" hosted on Railway (exampleopenaiendpoint-production.up.railway.app) so the E2E runs return canned responses without paying for or depending on a live provider. When that single deployment is down, every one of those jobs fails with "404 Application not found" even though nothing in the PR is broken; the whole repo is coupled to the uptime of one free external service. This adds tests/_fake_openai_endpoint_server.py, a small canned-response OpenAI-shaped server (chat, text, embeddings, streaming with usage, and the "429" rate-limit special case), and a reusable start_fake_openai_endpoint CircleCI command that runs it on host port 8190 and waits until healthy. The affected jobs now inject FAKE_OPENAI_API_BASE pointing at the local server, and the example configs they mount resolve api_base from that env var. The intentionally bad fallback URL in proxy_server_config.yaml is left untouched so the fallback test still exercises a failing upstream. Wired into build_and_test, litellm_router_testing, db_migration_disable_update_check, proxy_logging_guardrails_model_info_tests, proxy_spend_accuracy_tests, proxy_multi_instance_tests, proxy_store_model_in_db_tests, and proxy_build_from_pip_tests.
* feat(ui): migrate models page to App Router path route
Cut the Models + Endpoints page over from the legacy ?page=models switch
in (dashboard)/page.tsx to a path route at (dashboard)/models-and-endpoints.
Adding the MIGRATED_PAGES entry repoints the sidebar link and redirects old
?page=models bookmarks to /ui/models-and-endpoints.
ModelsAndEndpointsView already sourced identity from useAuthorized() and its
own data via useModelsInfo(), so the token/keys/modelData/setModelData props
were dead; drop them from ModelDashboardProps (and the parent's now-unused
setModelData state) to sever the last of the shared-state coupling.
* test(ui): scope migration smoke's shell probe to the exact sidebar link
The migration smoke used a loose `locator("a", { hasText: "Virtual Keys" })`
to assert the dashboard shell rendered. The Models + Endpoints page content
itself links to the "Virtual Keys page", so on that route the substring filter
matched two anchors and tripped Playwright strict mode. Match the sidebar link
by its exact accessible name instead, which resolves to just the nav item.
The `page == "pass-through-settings"` arm in (dashboard)/page.tsx is unreachable: it isn't a sidebar item and nothing in the app sets ?page=pass-through-settings. The Pass-Through Endpoints UI lives as a tab inside the Models + Endpoints view (ModelsAndEndpointsView renders PassThroughSettings), so the standalone switch arm is dead code. Remove it, its now-unused import, and the matching enum member in the e2e pages fixture.
…racking (#30706) completion_cost extracted service_tier from the response object and the usage object without an isinstance guard, so a non-string value (e.g. a dict) flowed straight into _get_service_tier_cost_key and raised AttributeError on service_tier.lower(). completion_cost re-raises, so the request's cost was lost. PR #30690 fixed only the request-level optional_params path. This extends the same guard to the response and usage paths by normalizing each extracted value: a non-string tier (and the routing-only "auto" sentinel) is not billable, so it coerces to None and pricing defers to the next concrete tier the provider served, falling back to standard pricing when none is present. Adds two regression tests driving a dict service_tier through completion_cost, one on the response object (defers to the served usage tier) and one on the usage object (prices at standard); both raise AttributeError before the fix.
…and review-gate label lifecycle (#30433) * feat(triage): auto-close stale PRs with Greptile score <4/5 Adds .github/scripts/close_low_quality_prs.py and a daily workflow that closes PRs which: - are open for at least 7 days, and - carry a most-recent greptile-apps review with Confidence Score <4/5, - and are not drafts or opt-out-labeled ('do not close', 'wip', etc.). Each closure posts an explanatory comment telling the contributor how to bring the PR back (rebase, re-request greptile, reopen at 4+/5). The 4/5 bar is already documented in the PR template (.github/pull_request_template.md), so this just enforces it. Tested with a dry run against the live BerriAI/litellm backlog of 1000 open PRs: 100 candidates identified, 598 PRs pass the bar (4+/5), 186 are too young, 97 are drafts, 19 lack any Greptile review and are left alone. Workflow defaults to closing 25 PRs/run as a safety net and supports workflow_dispatch with overrides (close=false for a dry run, custom min_age_days/min_score/limit). 18 unit tests cover score extraction (HTML/markdown/plain text, login variants, multi-review picks latest) and per-PR evaluation (drafts, opt-out labels, age, missing/passing/failing scores). Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com> * docs(templates): require expected/actual + QA proof for external contributions PR template: - Make the rubric explicit at the top: link an issue, OR provide a clear problem description + expected vs. actual + visual QA proof. - Add dedicated sections for each piece so the bot has a deterministic shape to read. - Keep the existing 'Linear ticket' section for internal contributors (they're exempt from the auto-triage rubric). Bug report template: - Split 'What happened?' into 'Actual behavior' + 'Expected behavior'. - Make logs/screenshot a required textarea. - Warning banner at the top tells external contributors that incomplete reports will be auto-closed (with re-evaluation on reopen). Feature request template: - Require a concrete use case + example in the motivation field, not just a one-liner pitch. - Same auto-triage warning banner. Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com> * feat(triage): Agent Shin LLM-as-judge for external PRs and issues Adds a new triage flow that evaluates external pull requests and issues against the project's contribution rubric and, when configured to do so, auto-closes non-conforming ones with an explanatory comment. Contributors can update + reopen to be re-evaluated. Scope: - Internal BerriAI contributors (author_association OWNER/MEMBER/COLLABORATOR) and bot accounts are skipped entirely. - 'Fixes #1234' / 'Resolves https://github.com/.../issues/N' in the PR body short-circuits to PASS without burning LLM tokens. - LLM judge returns structured JSON (verdict, missing[], explanation); parser tolerates markdown fences and embedded JSON. - LLM errors NEVER close PRs/issues — failure surfaces as 'skip-llm-error'. Safety: - pull_request_target / issues triggers are FORCED dry-run in the workflow; only manual workflow_dispatch with close=true (and AGENT_SHIN_ENABLED=true) takes destructive action. - Default mode writes verdicts to GITHUB_STEP_SUMMARY only — no public comments until the team flips the AGENT_SHIN_ENABLED repo variable. - LLM uses an OpenAI-compatible endpoint (model and base URL configurable via repo variables; key via OPENAI_API_KEY secret). Files: - .github/scripts/triage_with_llm.py - judge orchestrator + CLI - .github/workflows/triage_pr_with_llm.yml - .github/workflows/triage_issue_with_llm.yml - tests/test_litellm/test_github_triage_with_llm.py - 33 unit tests End-to-end validated against four real PRs (#28117 internal collaborator, #28108 bot, #28129 'Fixes #28128', #28116 no linked issue) and issue #28132 with a stubbed LLM judge: each path produces the expected action. Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com> * feat(triage): scope Greptile auto-closer to external contributors + dry-run by default - close_low_quality_prs.py now filters by GitHub author_association via the REST API: PRs from OWNER / MEMBER / COLLABORATOR (and bot accounts) are skipped with a new 'skip-internal' summary bucket. - close_low_quality_prs.yml now defaults workflow_dispatch close=false, and ignores 'close=true' unless the new repo variable AGENT_SHIN_ENABLED is set to 'true'. Scheduled runs are dry-run only until the team flips that switch. - Updated unit tests: one new test asserting internal authors are skipped, and an autouse fixture treats unspecified test PRs as external so the rest of the suite still exercises the close path. Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com> * fix(workflows): scheduled cron closes PRs; safe --close strip in triage Co-authored-by: Yassin Kortam <yassin@berri.ai> * fix(triage): scheduled cron stays dry-run; dedent prompts before interpolation - close_low_quality_prs.yml: only workflow_dispatch with close=true (and AGENT_SHIN_ENABLED=true) actually closes PRs. Scheduled runs are always dry-run, matching the safety invariant documented for triage_pr/issue. - triage_with_llm.py: textwrap.dedent on an f-string with multi-line interpolated bodies fails because the body's 2nd+ lines start at column 0, making the common-indent zero. Dedent the static template first, then .format() the title/body in. Co-authored-by: Yassin Kortam <yassin@berri.ai> * Fix bugs in auto-close PR triage scripts - close_low_quality_prs.py: Treat author_association API lookup failures as internal (fail-safe) so transient errors don't cause internal contributors' PRs to be auto-closed. - triage_with_llm.py: Update summary heading from 'Would post comment:' to 'Posted comment:' since this branch only runs after the comment has already been posted. Co-authored-by: Yassin Kortam <yassin@berri.ai> * feat(triage): default Agent Shin to gpt-5.4-mini with reasoning_effort=none - Bump DEFAULT_MODEL from gpt-4o-mini to gpt-5.4-mini (more modern; 4M total context window per OpenAI catalog, JSON-schema response format, function calling all supported). - For gpt-5.x family models, pass reasoning_effort="none" via extra_body. gpt-5.x rejects temperature != 1 unless reasoning_effort is explicitly "none"; setting it lets us keep temperature=0 for deterministic JSON rubric judgments. extra_body works across openai SDK versions regardless of whether they natively type the kwarg. - For non-gpt5 overrides (TRIAGE_MODEL=gpt-4o-mini etc.), reasoning_effort is not sent. - 4 new unit tests cover: gpt-5.4-mini -> reasoning_effort=none, capitalized/dated gpt-5 variants -> reasoning_effort=none, gpt-4o-mini -> no extra_body, base_url passthrough. Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com> * fix(triage): bugbot — drop dead gh_json and fix --optout-label append-with-default - Removed the unused gh_json helper (bugbot low-severity dead code). - Replaced argparse `action="append", default=[...]` with default=None + DEFAULT_OPTOUT_LABELS fallback. The mutable-default + append combo silently APPENDS to the canonical defaults instead of replacing them, so --optout-label could not actually scope the opt-out list. - Added tests covering both the canonical default and the flag-replaces-defaults behavior. Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com> * fix(triage): bugbot — tighten linked-issue regex, fail-safe author_association, fix empty TRIAGE_MODEL Three independent bugbot findings against triage_with_llm.py: 1. LINKED_ISSUE_PATTERN included weak keywords (`see`, `ref`, `addresses`) so casual mentions like "See #1234 for context" were short-circuited to pass-linked-issue without ever calling the LLM — contradicting the prompt's own "a bare issue number without a closing keyword counts only if it's clearly the related issue (not a passing mention)" rubric. Limit the regex to GitHub's documented PR-closing keywords (fixes/fix/fixed/closes/close/closed/resolves/resolve/resolved). 2. is_internal_contributor() treated an empty/missing author_association as external (eligible for the destructive close path), while the sibling is_external_pr_author() in close_low_quality_prs.py fail-safes the same case as internal. Align the two so a partial/unknown GitHub response can never make a PR eligible for auto-close. 3. argparse `default=os.environ.get("TRIAGE_MODEL", DEFAULT_MODEL)` returns the empty string when GitHub Actions exposes an unset repo variable as an empty-string env var (the optional vars.TRIAGE_MODEL case in the workflow). Use `os.environ.get(...) or DEFAULT_MODEL` so empty -> default, matching the existing OPENAI_BASE_URL pattern. Tests: - Casual mentions now must fall through to the LLM (parametrized); added an orchestration test ensuring "See #1234" reaches the judge. - Empty/missing author_association now fails safe (parametrized). - Empty TRIAGE_MODEL env var falls back to DEFAULT_MODEL; explicit TRIAGE_MODEL is still honored. Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com> * fix(workflows): bugbot — gate Agent Shin --close on '= true' not '!= false' The PR and issue Agent Shin workflows gated the destructive --close flag with [ "${DISPATCH_CLOSE:-false}" != "false" ]. That pattern treats anything other than the literal string "false" as enabling closure — "True", "yes", "1", typos, accidental whitespace, etc. The workflow_dispatch input UI is a 'true'/'false' choice dropdown so the form is constrained, but the API (`gh workflow run -f close=...`) accepts any string, and a CI cron / external invoker passing a non-canonical truthy value would have silently enabled real contributor PR closures. Mirror the sibling Greptile closer's [ "${CLOSE_FLAG}" = "true" ] pattern: only the EXACT string "true" enables --close; every other value (including the unset/empty default) resolves to dry-run. This is the fail-safe philosophy applied everywhere else in this PR. Added tests/test_litellm/test_github_triage_workflows.py with two parametrized invariants: 1. The destructive gate uses '= "true"' for its env-var comparison (either bare '${ENV}' or '${ENV:-false}' form accepted), and never the fail-open '!= "false"' pattern. 2. Every destructive gate is also gated on AGENT_SHIN_ENABLED being "true" — either by entering the close branch on '=' or by bailing out early on '!=' — so flipping the repo variable off is a true kill switch regardless of per-run inputs. Manually verified the test fails on the buggy '!= "false"' pattern and passes on the fix, so it would have caught the regression at PR time. Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com> * feat(triage): close any PR (incl. drafts, any age); add @agent-shin reconsider flow Follow-up to PR #28117. Three behavior changes + one new workflow, addressing the team's concerns on the original review: 1) Apply auto-close to ALL open PRs, not just those over a week old. - close_low_quality_prs.py: --min-age-days default flipped from 7 to 0. The flag is preserved as an opt-in safety net for one-off backfill runs that want to spare very-young PRs, but the daily scheduled sweep now closes external-author PRs as soon as Greptile scores them <4/5. - close_low_quality_prs.yml: workflow_dispatch input default also flipped to 0; doc comments updated. 2) Apply auto-close to draft PRs too. - close_low_quality_prs.py: removed the skip-draft branch in evaluate_pr. Drafts are NOT a free pass — the team's intent is 'open PR count == PRs internal collaborators need to action on', so a draft Greptile scored 2/5 still belongs in the closed bucket. Authors who genuinely need a long-lived draft can attach the 'wip' opt-out label, which is unchanged. - The 'skip-draft' action is gone; the 'wip' label still skips. 3) Address the 'OSS contributors cannot reopen a bot-closed PR' wrinkle. GitHub does NOT let an external (non-write-access) contributor reopen a PR that was closed by a bot or maintainer (long-standing limitation). The original PR's close-comments told contributors to 'Reopen the PR — I'll re-evaluate automatically', which is broken for the very audience this triage targets. Two changes: a) Reword every close-comment (Greptile sweep + Agent Shin PR close + Agent Shin issue close + PR template) to recommend: - Open a new PR with the updated branch (primary path). - Or comment '@agent-shin reconsider' on the closed PR for a re-evaluation that, on pass, reopens the PR via the bot's GH_TOKEN write access. b) Add the @agent-shin reconsider workflow: - .github/workflows/triage_reconsider.yml: new 'issue_comment'-triggered workflow. Authorizes only the PR/issue author or an internal collaborator (OWNER/MEMBER/COLLABORATOR), gated via a step output so unauthorized commenters never reach the destructive steps. Globally gated on AGENT_SHIN_ENABLED='true' (positive form, matching the test_github_triage_workflows guardrail patterns). - triage_with_llm.py: --reconsider mode. On a closed PR/issue, re-runs the LLM judge (or linked-issue regex short-circuit) and: - on pass: reopens via reopen_pr/reopen_issue + posts a 'Re-evaluated and reopened' comment. - on fail: leaves closed and posts a 'still missing X' comment so the contributor can iterate again. Reconsider-on-open is a no-op ('skip-not-closed'). Internal-author + bot-account skips still take priority over reconsider. 4) Greptile-on-closed-PRs question: the team asked whether Greptile can re-review a closed PR. Greptile's docs don't address this and we shouldn't promise behavior we can't verify, so the new close-comment wording does NOT instruct contributors to 're-request greptile on the closed PR'. Instead it points them at the new-PR path (which Greptile definitely reviews) or the @agent-shin reconsider trigger (which re-runs the LiteLLM-side rubric judge, not Greptile). Tests: 93 passing (was 59). - test_github_close_low_quality_prs.py: replaced 'skip drafts' test with 'closes drafts when score is low' + 'closes brand-new PR when min_age=0' + 'no skip when min_age=0'. The 'skip too young' assertion is preserved as opt-in. - test_github_triage_with_llm.py: 6 new TestTriageOrchestration cases for reconsider mode (skip-not-closed on open, reopen on pass, still-failing comment on fail, linked-issue short-circuit reopen, skip internal author in reconsider, reopen-issue on pass) + a new TestCloseCommentText class that pins the user-facing 'open a new PR' + '@agent-shin reconsider' wording. - test_github_triage_workflows.py: added triage_reconsider.yml to the destructive-gate guardrail table; AGENT_SHIN_ENABLED is its own destructive gate (no separate per-run flag needed). Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com> * test(triage): pin safe behavior for curly braces in PR/issue title+body Adds regression tests covering the bugbot high-severity finding that str.format() would crash on user-supplied content containing { or }. Empirically str.format() does NOT re-parse interpolated values — only the template literal is scanned for replacement fields — so the bug does not exist in the current code, but pinning the safe behavior prevents a future templating change from silently reintroducing it. Also pins the dedented prompt shape (no leading 8-space indentation on template lines) so a future change to the build_*_prompt functions can't silently regress the LLM judge prompt format on multi-line bodies. Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com> * fix(triage): bugbot — reconsider dry-run + bot-closed guard + rate limit Address three Greptile/veria-ai concerns on the @agent-shin reconsider flow: 1. **Reconsider had no dry-run path.** The previous reconsider mode ignored `--close` and always posted comments + reopened on a pass. A local operator running `python triage_with_llm.py --reconsider --pr N` would silently take destructive GitHub actions with no way to preview. Reconsider now honors `close=False` the same way regular triage does and returns `would-reopen` / `would-reconsider-still-failing` for step-summary rendering. 2. **Reconsider could reopen maintainer-closed PRs/issues** (Medium security finding from veria-ai). The workflow only checked that the commenter was authorized — it did NOT check that the most recent close was performed by Agent Shin. A contributor could comment `@agent-shin reconsider` on a PR a maintainer closed for non-rubric reasons (duplicate, security report, design rejection) and have the bot reopen it. Add `was_closed_by_agent_shin()` which inspects the issue events API for the most recent `closed` actor and only permits reopen when that actor matches the configured bot login (default `github-actions[bot]`, overridable via env). Fail-closed on missing events. 3. **No rate-limiting on the reconsider trigger.** Every `@agent-shin reconsider` comment burns CI minutes + an OpenAI API call. Add a 10-minute cooldown via `seconds_since_last_reconsider_verdict()` which greps the issue's comment list for the bot's own verdict marker (`<!-- agent-shin:reconsider-verdict -->`). Inside the window the triage returns `skip-rate-limited` and the LLM never runs. Workflow update: - `triage_reconsider.yml` now passes `--close` only when `AGENT_SHIN_ENABLED=true`, matching the pattern of `triage_pr_with_llm.yml`. The script runs in both states so the verdict still appears in the step summary for QA. Tests: - Add 5 reconsider safety tests: dry-run for pass / fail / linked-issue short-circuit, bot-closed-guard refusal on maintainer close, rate-limit refusal inside the cooldown window, and cooldown-elapsed acceptance. - Add unit tests for `was_closed_by_agent_shin` (bot / maintainer / missing actor / env-override) and `seconds_since_last_reconsider_verdict` (no marker / multiple markers / non-bot comment with marker / bot comment without marker). - Pin the `<!-- agent-shin:reconsider-verdict -->` marker in both reopen and still-failing comments — dropping it would silently break the cooldown. Existing reconsider tests updated to pass `close=True` (the production path now) + stub the new guards via `_stub_reconsider_guards`. 112 tests pass (was 93). Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com> * feat(triage): 1-day grace period before close + SwiftWinds immediate-close bypass - Add a 24-hour grace window between the first low-quality detection and the actual auto-close. The first detection posts a warning comment that explicitly says "You have 1 day to address this before this PR is auto-closed" and points the contributor at: * `@agent-shin reconsider` to request another look (and re-open) * `@greptileai` to request a fresh Greptile review — works even after the PR is closed - Both `triage_with_llm.py` (LLM judge) and `close_low_quality_prs.py` (Greptile-score closer) share the same `<!-- agent-shin:grace-warning -->` HTML marker so a warning posted by either path is recognized by both. - Add IMMEDIATE_CLOSE_LOGINS = {swiftwinds} to bypass BOTH the grace period AND the dry-run / AGENT_SHIN_ENABLED gating. SwiftWinds is the user's personal account (no push permissions to litellm) used to dogfood the bot; user explicitly asked: "For SwiftWinds, just close immediately. Faster iteration that way." - Update the standard close comments to mention that `@greptileai` works even after the PR is closed. - Add 23 new tests covering: warn-grace on first detection, skip during grace window, close after grace expires, SwiftWinds bypass (case insensitive, with close=False, no random-login false positives), the grace-warning text invariants, and the SwiftWinds entry in the IMMEDIATE_CLOSE_LOGINS constant. Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com> * fix: skip grace-period text in close comment for IMMEDIATE_CLOSE_LOGINS For PRs from IMMEDIATE_CLOSE_LOGINS (e.g. swiftwinds), evaluate_pr returns 'close' immediately without ever posting a grace warning, so the close comment should not reference a 1-day grace period. Make close_pr take a grace_period_elapsed flag, default True, and pass False from the main loop when the close path was the immediate-close branch. Co-authored-by: Yassin Kortam <yassin@berri.ai> * fix(close-low-quality-prs): report actual closes in dry-run summary IMMEDIATE_CLOSE_LOGINS PRs are closed even when the global --close flag is not set, but the summary used the global dry-run flag to choose between 'would close' and 'closed'. Split the count so operators can see both actual closures and dry-run would-be closures. Co-authored-by: Yassin Kortam <yassin@berri.ai> * chore(triage): vendor Agent Shin (#28117) onto demo branch Brings the Agent Shin OSS-triage scripts, workflows, issue/PR templates, and tests from PR #28117 onto this branch so the new review-gate feature and its end-to-end demo are self-contained and runnable in CI. https://claude.ai/code/session_01XyyWa8t2VYmoGd6mKMEqkZ * feat(triage): add "ready for review" label lifecycle to Agent Shin Adds review_gate(), a state machine that keeps a `ready for review` label in sync with whether an external PR clears BOTH gates — the LLM rubric and Greptile's most recent confidence score: - pass (untagged) -> add label + "ready for review" / "all clear" comment - pass (already tagged) -> no-op (idempotent across re-runs) - regress (Greptile < 4/5 or QA proof removed) -> remove label + "what's missing" comment, PR stays open - recover after a regression -> "all clear again" comment + re-add the label - fail & untagged, < 24h old -> one-time "what's missing" notice (grace window) - fail & untagged, > 24h old -> close + comment (reopen via @agent-shin reconsider) The label itself is the persisted state, so comments fire only on transitions (never on every scheduled run). All side effects are gated behind --close, so the dry-run contract matches the existing triage flow. Lifecycle comments use hidden HTML markers and deliberately avoid the auto-close marker so they never trip the reconsider provenance check. Relocates the shared Greptile helpers (extract_greptile_score, SCORE_PATTERN, GREPTILE_BOT_LOGINS, parse_iso8601) into triage_with_llm.py so the daily sweep and the review gate read the score through one implementation, and adds the review_gate.yml workflow (dry-run unless AGENT_SHIN_ENABLED=true) plus 18 unit tests covering every branch and a full pass->regress->recover cycle. https://claude.ai/code/session_01XyyWa8t2VYmoGd6mKMEqkZ * Port review-gate feature from #28758 onto #28147 triage scripts Adds the "ready for review" label lifecycle (originally PR #28758) on top of #28147's refactored triage_with_llm.py. The original commit was authored against an older snapshot of #28117 and could not be applied cleanly, so the additions were re-applied surgically: - New constants: READY_FOR_REVIEW_LABEL, DEFAULT_GRACE_DAYS, DEFAULT_MIN_GREPTILE_SCORE, READY/REGRESSED/WITHIN_GRACE markers, GREPTILE_BOT_LOGINS, SCORE_PATTERN, AGENT_SHIN_AUTO_CLOSE_MARKER. - New helpers: add_label, remove_label, extract_greptile_score, parse_iso8601 (the latter two mirrored from close_low_quality_prs.py so the daily sweep and the review gate read the score through the same logic). - New comment formatters: format_ready_for_review_comment, format_all_clear_comment, format_regression_comment, format_within_grace_comment. - New entry point: review_gate() implementing the pass/regress/recover state machine, with the label itself acting as persisted state so transition comments fire only on actual transitions. - main() learns --review-gate, --grace-days, --min-greptile-score and dispatches to review_gate() when the flag is set. Verified via tests/test_litellm/test_github_review_gate.py (18 tests) and the existing triage suites (144 more) — all 162 pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * agent_shin: extract shared constants/helpers; cover review_gate.yml in guardrail tests Bug 1: `triage_with_llm.py` and `close_low_quality_prs.py` each defined their own copies of `extract_greptile_score`, `parse_iso8601`, `GREPTILE_BOT_LOGINS`, `SCORE_PATTERN`, `GRACE_COMMENT_MARKER`, `GRACE_PERIOD_SECONDS`, `IMMEDIATE_CLOSE_LOGINS`, and `AGENT_SHIN_DEFAULT_BOT_LOGIN`. The comments explicitly said the two copies had to stay in sync, but nothing enforced it. A future change to one (e.g. extending `SCORE_PATTERN` for a new Greptile output format) would silently diverge from the other and the daily sweep and the LLM judge would disagree on which PRs have low scores. Extract these to `.github/scripts/agent_shin_shared.py` and re-export them from each script so the existing test attribute access (`triage_module.GRACE_COMMENT_MARKER`, etc.) keeps working without any test changes. Bug 2: `review_gate.yml` is a destructive workflow (close PRs, add/remove labels, post comments) with the same gating philosophy as the others (`AGENT_SHIN_ENABLED = "true"` + a per-run `CLOSE_FLAG = "true"`), but it was missing from `DESTRUCTIVE_GATE_ENV` in the guardrail tests. Add it so a future regression (e.g. flipping to `!= "false"`) is caught by the same parameterized invariants as every other workflow. Co-authored-by: Yassin Kortam <yassin@berri.ai> * agent_shin: fix bug bundle (gated LLM key, author-filtered marker dedup, dedup gh/grace helpers) Co-authored-by: Yassin Kortam <yassin@berri.ai> * agent_shin: fix review_gate close-after-regression and case-insensitive label match Co-authored-by: Yassin Kortam <yassin@berri.ai> * feat(triage): add one-shot 7-day heads-up sweep for Agent Shin rollout Adds a rollout-day workflow that comments on every open external PR/issue that the new triage bot WOULD auto-close, giving contributors 7 days to fix their description before any destructive action runs. Why now: merging this PR enables Agent Shin in dry-run. The follow-up "enact" PR (next Monday) flips the destructive paths on. Without this heads-up, contributors would get a close-comment on day 8 with no prior warning. The heads-up names the cutoff date, lists the rubric, calls out each PR/issue's specific missing pieces, and explains the recovery paths (@agent-shin reconsider for PRs, edit + reopen for issues). Files - .github/scripts/_agent_shin_actions.py — thin maybe_post_comment / maybe_close_* / maybe_add_label / etc. wrappers. Each is a single `if dry_run: log; return; else: call_through()` so a dry-run preview differs from the real run in exactly one call site per mutation. The call-through goes via `triage_with_llm.<name>` (module-qualified) so monkeypatching the underlying function in tests is reflected here. - .github/scripts/triage_rollout_heads_up.py — the sweep. Iterates every open PR + issue via `gh pr list` / `gh issue list`, runs the future rubric (review_gate for PRs, triage(kind="issue") for issues), and posts the heads-up on any item that would be auto-closed. Idempotent via a `<!-- agent-shin:rollout-heads-up -->` marker. Defaults to dry- run; --close opts in to real posts. --close-on overrides the cutoff date (defaults to today + 7 days). - .github/workflows/triage_rollout_heads_up.yml — one-shot workflow. Triggers on push to litellm_internal_staging filtered to the script path (fires on rollout merge) plus workflow_dispatch with a dry_run input that defaults to "true" for safe manual re-runs. - tests/test_litellm/test_triage_rollout_heads_up.py — 28 unit tests covering: the dry-run wrappers (each maybe_* gates correctly), the _would_be_closed predicate for PR vs. issue results, the comment formatter (cutoff/rubric/marker/recovery wording), per-item dispatch (skip-not-open, skip-internal-author, skip-already-notified, skip-passing, would-post/posted), and the sweep loop end-to-end. Local preview (no GitHub mutations): python3 .github/scripts/triage_rollout_heads_up.py --repo BerriAI/litellm Real run (what the workflow does): python3 .github/scripts/triage_rollout_heads_up.py --repo BerriAI/litellm --close TODO: replace the placeholder ROLLOUT_BLOG_URL with the canonical docs URL once the litellm-docs PR ships. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix: gate reconsider workflow OPENAI_API_KEY + remove dead actions wrappers - Mirror sibling Agent Shin workflows by only exposing OPENAI_API_KEY in triage_reconsider.yml when vars.AGENT_SHIN_ENABLED == 'true'. Previously the secret was unconditionally exposed, so any PR/issue author could trigger paid LLM calls by commenting '@agent-shin reconsider' even while the bot was supposed to be in dry-run. - Remove the six unused dry-run wrappers (maybe_close_pr, maybe_close_issue, maybe_reopen_pr, maybe_reopen_issue, maybe_add_label, maybe_remove_label) from _agent_shin_actions.py — only maybe_post_comment is used by rollout scripts. Drop the associated tests that exercised the now-removed functions. Co-authored-by: Yassin Kortam <yassin@berri.ai> * fix: address triage script edge cases - triage_rollout_heads_up.py: replace %-d strftime specifier (GNU-only) with portable day formatting so the script doesn't crash on Windows. - close_low_quality_prs.py: skip malformed JSON lines in fetch_pr_comments instead of letting one bad line abort the daily sweep, matching the pattern in triage_with_llm._iter_paginated_json. - triage_with_llm.py: move has_linked_issue short-circuit before build_pr_prompt to avoid unnecessary prompt construction on PRs that link an issue. Co-authored-by: Yassin Kortam <yassin@berri.ai> * fix(scripts): per-PR error isolation and limit grace warnings in close_low_quality_prs - Wrap per-PR processing in try/except so a transient GitHub API failure on one PR no longer aborts the entire daily sweep (mirrors the pattern already used in triage_rollout_heads_up.py). - Have --limit bound *all* destructive write actions (closures and grace warnings combined), not just closures. Prevents a backlog of newly failing PRs from flooding contributors with comments in a single run. Co-authored-by: Yassin Kortam <yassin@berri.ai> * fix(agent-shin): remove 1000-PR cap on bulk sweeps; sweep entire backlog Both bulk-sweep scripts hardcoded `gh {pr,issue} list --limit 1000`, and gh lists newest-first — so the OLDEST ~900 PRs and ~380 issues were silently dropped. That's exactly the stale backlog the daily closer and one-shot rollout heads-up exist to catch. Extract a single `list_open_items(kind, *, repo, fields)` helper into `agent_shin_shared.py` with `GH_LIST_ALL_LIMIT = 100_000` — a ceiling far above any realistic open backlog so gh paginates until the queue is exhausted. `fetch_open_prs` and `_list_open_numbers` both delegate to it, so the limit lives in exactly one place going forward. Verified live against BerriAI/litellm: - `fetch_open_prs` -> 1981 PRs (was 1000) - `_list_open_numbers(issue)` -> 1382 issues (was 1000) - `_list_open_numbers(pr)` -> 1981 PRs (was 1000) Adds 7 regression tests asserting the new limit is passed, the dedicated `gh {pr,issue} list` command + fields are used per kind, bad kind raises ValueError, and both callers delegate to the shared helper. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(agent-shin): require non-mocked end-to-end QA proof for PR pass The PR rubric previously passed any PR with a linked issue, regardless of whether it showed the fix actually working. Sample spot-check found 21/25 recent external PRs passing, including ones that linked an issue but provided zero QA evidence. Tighten the rubric so a pass now requires BOTH: (1) CONTEXT — a linked issue OR a clear problem description with expected-vs-actual behavior. (2) END-TO-END QA PROOF — at least one of: (a) screenshot(s) of the fix working, (b) screen recording / video, (c) specific commands actually run, paired with their real output, against the real system. Mocked unit tests, generic 'I tested it' claims, 'all tests pass' without output, and the linked issue itself are explicitly excluded from QA proof. Also add 'qa_proof_type' to the JSON schema so the per-PR report surfaces which kind of proof (or 'none') the judge saw. Re-sample on the same 25 recent external PRs shifts the verdict distribution from 21 pass / 4 fail to 4 pass / 21 fail, with zero prior-fails now passing — the stricter rule catches PRs that ship only with unit-test claims and no real integration evidence. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(agent-shin): link blog explainer from every action-required bot comment Adds "What's this and why am I getting it?" links to docs.litellm.ai/blog/ agent-shin-triage from the four comments contributors actually read when something went wrong: PR close, PR grace warning, issue close, issue grace warning. PR comments also link the rubric section directly from the QA-proof bullet so contributors can self-serve "what counts as proof" without pinging a maintainer. Pins the new guarantees in tests: blog link must appear in all four comments, and the PR close comment must continue to flag mocked-dependency unit tests as insufficient proof. The linked blog post is in BerriAI/litellm-docs PR #240; the URL will 404 until that lands. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(review_gate): raise sweep limit from 1000 to 100000 to match GH_LIST_ALL_LIMIT gh lists newest-first, so capping at 1000 silently drops the oldest open PRs — exactly the stale ones the daily sweep is meant to reconcile. Use the same ceiling as agent_shin_shared.GH_LIST_ALL_LIMIT so the workflow sees the entire backlog. Co-authored-by: Yassin Kortam <yassin@berri.ai> * Fix three Agent Shin triage edge cases - review_gate: expire the regression-marker short-circuit after grace_days so PRs that were regressed and then abandoned can eventually be closed. - review_gate: when the rubric short-circuits to pass via the linked-issue regex but Greptile drags the PR below the bar, replace the synthetic 'LLM was not called' explanation with the real Greptile shortfall so regression / close comments are not misleading. - triage_rollout_heads_up._comments_have_marker: drop the unused 'kind' parameter and filter by bot author so a contributor quoting the heads-up via 'Quote reply' cannot trick the idempotency check, matching the pattern in triage_with_llm._has_marker. Co-authored-by: Yassin Kortam <yassin@berri.ai> * fix: pass min_greptile_score through to ready-for-review comment text Co-authored-by: Yassin Kortam <yassin@berri.ai> * feat(agent-shin): warmer triage comments — bullet-train emoji, 'what you got right' section, softer 'park this for later' framing User feedback on the auto-triage comments contributors will see: 1. Tone — the previous 'You have 1 day to address this before this PR is auto-closed' framing reads as an ultimatum. Replace with: 'If the description isn't updated in the next 1 day, I'll auto-close this PR. That's not us saying we don't care about the change — we want the open-PR list to mirror what a maintainer can act on right now, so contributors don't get lost in a backlog. A closed PR is a soft "park this for later," not a rejection. Take your time.' 2. Positive feedback — the previous comments only listed what was missing. Now every close + grace-warning comment opens with a 'What you got right:' section rendered from the judge's per-field flags. Contributors see a checkmark for everything they got right (linked issue, problem description, expected/actual, QA proof for PRs; runnable repro, screenshot/log, expected/actual, motivation+example for issues) before the gaps. The block is omitted entirely when nothing is present so we never render 'What you got right: (nothing).' 3. Reconsider trigger — the previous grace warning told contributors to comment '@agent-shin reconsider' during the grace window. They don't need to — the bot re-checks on every sweep. The new copy says 'just update the description, no need to ping me' for the grace path, and reserves '@agent-shin reconsider' for the post-close recovery path. 4. Bullet-train emoji — replace 👋 with 🚄 (Shinkansen, the symbol of Agent Shin) across every action-required comment: PR close, PR grace warning, issue close, issue grace warning, within-grace, Greptile- closer grace warning, rollout heads-up. Pinned in tests so a future refactor can't silently revert. 5. Greptile-post-close — the @greptileai bullet now explicitly says 'a low Greptile score isn't a blocker either,' since the previous copy buried the fact that @greptileai works after auto-close. Comment templates updated: format_pr_close_comment, format_issue_close_comment, format_grace_warning_pr_comment, format_grace_warning_issue_comment, format_within_grace_comment (triage_with_llm.py); format_grace_warning_comment (close_low_quality_prs.py); format_heads_up_comment header (triage_rollout_heads_up.py). New helpers: _format_present_for_pr / _format_present_for_issue / _format_present_block, driven off the existing per-field flags the LLM judge already emits — no prompt change needed. New tests pin: bullet-train emoji in every action-required comment; 'What you got right' appears with ✅ bullets when fields are present; the block is omitted when no fields are present; 'park this for later' / 'not a rejection' softer framing; grace warnings tell the contributor 'no need to ping' during the grace window (reconsider is the post-close path only). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(agent-shin): gate triage on a dogfood allowlist Add ALLOWLIST_LOGINS to agent_shin_shared so Agent Shin only acts on the named accounts while the set is non-empty. mateo-berri and SwiftWinds are allowlisted for the dogfood rollout; everyone else is skipped with skip-not-allowlisted across all four entrypoints (triage, review gate, the daily low-quality sweep, and the rollout heads-up). For an allowlisted author the usual internal/external classification is bypassed, so a maintainer's own org account still gets triaged during testing. Emptying the set lifts the restriction and restores full triage for the public rollout. The gate is dependency-injected via an `allowlist` parameter defaulting to the constant, so the internal/external-skip paths stay testable. * feat(agent-shin): tighten QA-proof and issue rubrics, ack reconsider with reactions Reorder the end-to-end QA proof options to video, then screenshots, then exact commands with their real output across the PR template, the LLM judge prompts, and every contributor-facing comment, and spell out that mocked or stubbed runs (including pytest on the repo's own unit tests, which mock the provider, DB, and network) never count as proof. QA proof is now required of all contributors, not just external ones. Tighten the issue bug-report rubric to require end-to-end evidence of the bug (the "before" half: a video, screenshot, or command paired with real output) plus expected vs. actual behavior, drop the bias toward PASS, and collapse the separate has_repro/has_proof flags into a single has_repro signal. Standardize the bullet-train emoji and strip em dashes from the bot's public-facing messages, and route issue recovery through @agent-shin reconsider since GitHub doesn't let OSS authors reopen an issue a bot closed. Acknowledge an @agent-shin reconsider the moment it's accepted with an eyes reaction and a thumbs-up once the run finishes, both gated on AGENT_SHIN_ENABLED so dry-run leaves no trace. * fix(agent-shin): shorten auto-close grace to 2 hours and drop the instant-close bypass Two dogfooding changes to the Agent Shin grace window. First, the warn-then-close grace (GRACE_PERIOD_SECONDS) drops from a day to 2 hours so the "fix it before it closes" loop can be exercised in one sitting; the constant carries a note to bump it back up for the public rollout. Second, remove IMMEDIATE_CLOSE_LOGINS entirely. SwiftWinds (the external dogfood account) used to skip the grace window and close on first detection, which also meant closing real PRs even during a scheduled dry run because the per-PR override flipped dry_run off. It now follows the same warn-then-close path as every other author, so a low-quality PR is warned first and only closed once the 2-hour window elapses. This also closes the Greptile finding that the sweep could mutate real PRs while AGENT_SHIN_ENABLED was still off. The review gate's separate age-based grace (DEFAULT_GRACE_DAYS) is left unchanged. Regression tests pin that SwiftWinds now warns-grace instead of closing instantly, and that a dry-run sweep over a closeable PR reports "would close" without making any GitHub mutation. * fix(agent-shin): gate reconsider reopen on an Agent Shin close marker was_closed_by_agent_shin only checked that the most recent close actor was the bot identity. That identity defaults to github-actions[bot], which is shared by every workflow in the repo (stale/duplicate sweeps included), so a contributor could @agent-shin reconsider an item another workflow closed and, if the description passed the rubric, get it reopened even though Agent Shin was never the closer. Require a second, Agent-Shin-specific signal alongside the actor check: an auto-close comment stamped with a hidden AGENT_SHIN_CLOSE_MARKER. Both close paths (the grace-period close and the review-gate close) flow through format_pr_close_comment / format_issue_close_comment, so stamping the marker there covers every real close while leaving the grace warnings unmarked. The guard stays fail-closed: no marker, no reopen. This also replaces the unused AGENT_SHIN_AUTO_CLOSE_MARKER constant (a visible phrase the guard never consulted) with the hidden marker the guard now relies on. * fix(agent-shin): stamp close marker on sweep closes and disclose regression deadline The daily Greptile sweep's close comment advertised `@agent-shin reconsider` but never stamped AGENT_SHIN_CLOSE_MARKER, so the reconsider reopen guard (was_closed_by_agent_shin), which now also requires that marker, silently rejected every sweep-closed PR with `skip-not-bot-closed`. Move the marker into agent_shin_shared so both close paths share one source of truth, extract format_close_comment so the sweep close comment is unit-testable, and stamp the marker there. Also disclose the grace_days deadline in the review-gate regression comment; it promised "the PR stays open" without mentioning that a still-failing PR is auto-closed grace_days after the notice, which would surprise contributors with a close they were never warned about. * fix(triage): tighten Agent Shin reconsider reopen guards The bot-closed guard accepted any historical Agent Shin marker comment on the thread as proof that Agent Shin owned the latest close, so a post-reopen close by another workflow under the shared `github-actions[bot]` identity could still satisfy the gate and let `@agent-shin reconsider` reopen a PR that Agent Shin did not close this cycle. `fetch_last_close_event` now also returns the latest `closed` event timestamp, and `was_closed_by_agent_shin` requires the most recent Agent Shin marker comment to sit at (or just before) that timestamp, with a small skew window for clock drift between the events and comments APIs. In the same path the LLM verdict check used `decision != "fail"` to choose the reopen branch, which treated a missing, empty, or typo verdict as a pass. Reopen is destructive, so the check now requires an explicit `decision == "pass"` and ambiguous verdicts fall through to the "still failing" branch instead. * style(agent-shin): black-format reconsider guard hardening * docs(agent-shin): scope dry-run wrapper docstring to the single existing helper The module docstring claimed it wrapped every Agent Shin mutation and referenced post_comment/close_pr/etc., but only maybe_post_comment exists. Describe the single helper accurately while keeping the dry-run pattern guidance for any future wrapper. * chore(agent-shin): defer issue/PR template changes to the rollout PR The triage and review-gate automation is gated to the allowlisted authors (mateo-berri, SwiftWinds) and AGENT_SHIN_ENABLED, so during this rollout it only acts on internal PRs/issues. The issue and PR templates have no such gate; they change for every contributor on merge and advertise that an LLM bot auto-closes external submissions, which won't happen while the allowlist is the sole author gate. Revert bug_report.yml, feature_request.yml, and pull_request_template.md to base so the public-facing messaging lands with the rollout flip instead of ahead of it. The scripts embed their own rubric and never read these files, so triage behavior is unchanged. * ci(agent-shin): hash-pin the openai install in privileged triage workflows The triage workflows install the OpenAI client with `pip install "openai>=1.40.0"`, a floating lower bound that resolves openai and its whole transitive tree to whatever PyPI serves at run time. These jobs run under pull_request_target with a write-scoped GITHUB_TOKEN, and the install plus the triage run happen on every PR open regardless of the AGENT_SHIN_ENABLED dry-run gate (that gate only withholds the LLM key and the destructive --close path), so a compromised release would execute during install or import while the token is in scope. Install instead from a new .github/scripts/triage-requirements.txt that pins openai==2.33.0 and every transitive dependency to an exact version with sha256 hashes, via pip --require-hashes. The workflows already sparse-checkout .github/scripts from the base repo (never fork code), so the pinned file is trusted. Add static guardrails to test_github_triage_workflows.py that fail if any installer workflow reverts to a floating openai install or if the requirements file loses its exact pins or hashes. * ci(agent-shin): gate rollout heads-up real run behind manual dispatch The rollout heads-up workflow fired its real `--close` sweep on every push to litellm_internal_staging that touched the script, and exposed OPENAI_API_KEY unconditionally, unlike every sibling triage workflow which only exposes the key on an enabled or dispatched run. That made merging the script post real heads-up comments (bounded only by the dogfood allowlist), which contradicts the inert-by-default safety invariant; once the allowlist is cleared for the public rollout, any later edit to the file would sweep the whole open backlog with real writes. The heads-up cannot be gated on AGENT_SHIN_ENABLED: its whole job is to warn contributors before that flag flips on, so it has to run while the flag is still off. Instead the automatic push trigger now stays dry-run, and the real one-shot sweep is a deliberate manual workflow_dispatch with dry_run=false, the sole path that adds `--close`. OPENAI_API_KEY is exposed only on that dispatch, matching the sibling workflows. Add static guardrails that fail if the push path regains a `--close`, if the dispatch gate stops fail-closing on the exact string "false", or if the key is exposed unconditionally again. --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com> Co-authored-by: Yassin Kortam <yassin@berri.ai> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Mateo <mateo@Mateos-MacBook-Pro.local>
* fix(proxy): allow non-admin virtual keys to call GA Realtime WebRTC HTTP routes (#30089) * fix(proxy): allow non-admin virtual keys to call GA Realtime WebRTC HTTP routes Add the realtime WebRTC HTTP sub-routes (/realtime/client_secrets, /realtime/calls and their /v1 + /openai/v1 variants) to LiteLLMRoutes.openai_routes so is_llm_api_route() classifies them as LLM API routes. Without this, non-admin virtual keys received 401 'Only proxy admin can be used to generate, delete, update info for new keys/users/teams' when calling these endpoints. Fixes #29923 * fix(proxy): validate session.model for realtime routes in model-access check The GA Realtime WebRTC HTTP routes resolve the effective model from the nested session.model (falling back to the top-level model), but the auth layer's get_model_from_request() only extracted the top-level model. A model-restricted virtual key could therefore place a disallowed model in session.model, leave the top-level model unset, and skip can_key_call_model() entirely - obtaining an ephemeral token for a model it is not allowed to use. Extract session.model for the realtime client_secrets/calls routes so the model-access check runs against the model the request will actually use. Legitimate callers are unaffected; their permitted model still validates. Relates to #29923 * fix(proxy): classify realtime transcription_sessions routes as LLM API routes Add the GA Realtime WebRTC transcription_sessions HTTP routes to openai_routes so is_llm_api_route() returns True for them, matching the client_secrets and calls routes already fixed. These endpoints are registered with user_api_key_auth in realtime_endpoints/endpoints.py, so without this a non-admin virtual key calling POST /v1/realtime/transcription_sessions would hit the admin-only 401 branch. Extends the regression test parametrization accordingly. --------- Co-authored-by: habonlaci <4699494+habonlaci@users.noreply.github.com> * feat(proxy): surface max_input_tokens/max_output_tokens on /v1/models (#30272) * feat(proxy): surface max_input_tokens/max_output_tokens on /v1/models * fix(proxy): degrade /v1/models gracefully when model-group lookup fails --------- Co-authored-by: Sameer Kankute <sameer@berri.ai> * fix: sort tiered token-cost thresholds numerically (#30375) * fix: sort tiered token-cost thresholds numerically _get_token_base_cost iterated input_cost_per_token_above_<N>_tokens keys with a lexicographic sort, so for tiers whose thresholds have different digit lengths (e.g. 90k vs 128k) a request crossing both was billed at the lower tier that sorted first. Sort by the parsed numeric threshold instead, so the highest tier the request actually crosses is applied. * refactor: reuse _parse_above_token_threshold for inline threshold parse --------- Co-authored-by: Eric (GabiDevFamily) <271972409+santino18727-debug@users.noreply.github.com> * fix(openai): preserve cache_control for openai-compatible custom endpoints (#30387) * fix(openai): preserve cache_control for openai-compatible custom endpoints * fix(openai): use parsed hostname to detect real OpenAI for cache_control preservation * fix(proxy): drain all daily-spend batches per flush cycle (#30281) (#30505) * fix(types): prevent internal parallel_request_limiter fields from leaking to upstream providers (#30545) * fix(types): add internal parallel_request_limiter fields to all_litellm_params to prevent forwarding to upstream providers * test(types): add regression test for internal rate-limit fields in all_litellm_params * fix(init): add bool type annotation to suppress_debug_info (#30531) Module-level `suppress_debug_info = False` had no annotation, so strict type checkers (e.g. ty) infer it as `Literal[False]`. Reassigning it to `True` (as done in proxy_server.py and router.py) then fails with an invalid-assignment error. Annotate it as `bool` to match every other flag in this module. * fix: coalesce null aggregates in update_metrics for no-spend keys (#29945) * feat(team_endpoints): add query parameter `key_limit` to `/team/info` endpoint (#30006) * feat(team_endpoints): Add query parameter key_limit to /team/info * feat(team_endpoints): update schema.d.ts to include the new query parameter * feat(team_endpoints): add tests for limitting key count in /team/info response * feat(team_endpoints): Apply suggestions from greptile * Set greater-than constraint on key-limit * Fix type * fix(router): release aiohttp connection when stream iteration ends abnormally (#30271) * fix(router): release aiohttp connection when stream iteration ends abnormally A streaming response that terminates with a mid-stream read timeout, a task cancellation (client disconnect), or GeneratorExit never closed the underlying aiohttp ClientResponse. aiohttp only auto-releases the connector slot at body EOF, so each abnormally terminated stream permanently leaked one slot from the shared TCPConnector pool. During a backend traffic spike the pool drains; once exhausted every subsequent request to that host waits for a slot, times out and surfaces as a 408, indefinitely, even after the backend recovers. Only a proxy restart cleared the in-memory sessions, which matched the reported symptom of a router stuck returning 408 for a healthy vLLM backend. Close the response in a finally clause when iteration ends. On a fully read response the connection was already released at EOF and close() is a no-op, so keep-alive reuse for normal requests is unchanged. Fixes #30192 * test(aiohttp): cover GeneratorExit path with a mock instead of a live socket The previous slot-release test started a real aiohttp TCP server, which can flake in offline CI and does not exercise this fix's code path directly. Replace it with a dependency-injected mock that closes the stream generator (GeneratorExit) and asserts the response is closed, covering the third abnormal-exit path the finally block handles * feat(proxy): serve Anthropic-native /v1/models for Claude Code gateway discovery (#30273) * feat(proxy): serve Anthropic-native /v1/models for Claude Code gateway discovery * refactor(proxy): move Anthropic model-list formatter into llms/anthropic/common_utils * fix(proxy): make model_list request param optional for direct callers * feat(dashscope): add Responses API support (#30286) * feat(dashscope): add Responses API support DashScope's OpenAI-compatible endpoint serves /responses, so register a DashScopeResponsesAPIConfig that routes dashscope/* responses calls to {api_base}/responses without rewriting the upstream model id, instead of falling back to the chat-completions -> responses emulation pipeline. Closes #29780 * feat(dashscope): mark responses API as not supporting native websocket Matches the hosted_vllm/perplexity/openrouter responses configs, which all override supports_native_websocket() to False since the OpenAI-compatible endpoint has no native wss:// responses transport. --------- Co-authored-by: Sameer Kankute <sameer@berri.ai> * fix(spend-logs): preserve error_message on ProxyException failures (#30381) * fix(spend-logs): preserve error_message on ProxyException failures `StandardLoggingPayloadSetup.get_error_information` used `str(original_exception)` to populate the human-readable error message stored in `spend_logs.metadata.error_information.error_message`. `ProxyException` (litellm/proxy/_types.py:3453) sets `self.message` in its constructor but does NOT call `super().__init__(message)` and does NOT define `__str__`. As a result, `str(ProxyException(...))` returns the empty string, and every auth/budget/quota rejection was landing in spend_logs with `error_message=""` despite a fully populated traceback. Operator impact: dashboard "LLM Failure" rows became untriageable — the only way to tell a 401 from a 429 was to manually unpack the traceback JSON via psql. Burst failure patterns (e.g. a UI session polling with a stale token) produced 20-30 indistinguishable `error_code=401` rows per second. Fix: prefer the `.message` attribute (set by ProxyException and every litellm.exceptions.* class) over `str(exc)`. The `str(exc)` fallback is retained for non-litellm exception types, preserving prior behavior. Test plan: - 2 new unit tests in tests/test_litellm/litellm_core_utils/ test_litellm_logging.py: * test_get_error_information_prefers_message_attribute_over_str * test_get_error_information_falls_back_to_str_when_no_message_attr - Existing test_get_error_information_error_code_priority still passes - End-to-end verified: bad-key 401 now stores full "Authentication Error, Invalid proxy server token passed..." message in spend_logs.metadata.error_information.error_message * fix(spend-logs): preserve explicit empty .message + drop dead reference Greptile P2 on #30381. The truthiness check `if message_attr:` silently skipped an explicit empty-string `.message` and fell through to `str(original_exception)`. For ProxyException-shaped objects both produce empty, so the bug was latent; for other exception types it would inject a different string into error_information.error_message and corrupt the signal. Use `is not None` so an empty string survives verbatim. Also drop the stale `See e2e/cases/11.` comment reference — that path does not exist anywhere in the repo and confuses future readers. Regression test added: an exception with `.message=""` and a non-empty `super().__init__()` arg must yield error_message == "". * ci: retrigger workflows after base branch change to litellm_internal_staging * fix(anthropic): strip LiteLLM-injected total_tokens from /v1/messages response (#30382) * fix(anthropic): strip LiteLLM-injected total_tokens from /v1/messages response The non-streaming /v1/messages response carries a LiteLLM-injected usage.total_tokens = input_tokens + output_tokens that is not part of the Anthropic API spec. This caused three problems: 1. Shape divergence with streaming on the same endpoint. message_delta.usage in the SSE path never carries total_tokens. Clients parsing both paths get two different schemas from one endpoint. 2. Shape divergence with upstream. Direct calls to https://api.anthropic.com/v1/messages return no total_tokens field, so clients using the official Anthropic SDK couldn't rely on it, and clients that did rely on the LiteLLM-injected one broke when bypassing the proxy. 3. Numerical misuse. total = input + output undercounts when cache_read_input_tokens and cache_creation_input_tokens are non-zero, because cache tokens are reported in their own fields. A 100k-token cached prompt with 1 non-cache input token + 200 output tokens reports total_tokens = 201, off by ~99.8% from any reasonable definition of "total." Fix: add _strip_total_tokens_from_anthropic_response in litellm/proxy/anthropic_endpoints/endpoints.py and invoke it in the success path of anthropic_response right before returning. Only mutates dict-shaped responses; streaming (which already lacks the field) is left untouched. spend_logs / Prometheus continue to compute total_tokens internally for billing — this fix only strips the field from the wire response. Scope: only the Anthropic passthrough endpoint /v1/messages. The OpenAI-shape /v1/chat/completions is unaffected. * fix(anthropic): gate total_tokens strip behind flag + handle Pydantic .usage Two P1 greptile threads on #30382: P1 — **Backwards-incompatible removal without a feature flag** Stripping `usage.total_tokens` unconditionally breaks any client currently reading the LiteLLM-shaped non-streaming /v1/messages response. Per the codebase's policy (mirrors #30418), gate behind a new flag. - `litellm.strip_anthropic_total_tokens: bool = False` (default — backward-compat: clients keep seeing total_tokens). - Env override: `LITELLM_STRIP_ANTHROPIC_TOTAL_TOKENS=true`. - Docstring: planned to flip to True in a future major release; opt in early. P1 — **Silent no-op if `result` is a Pydantic model** `base_process_llm_request` may return a Pydantic-style object whose `.usage` is a plain dict (the most common shape — e.g. objects wrapping raw upstream JSON). The original `isinstance(response, dict)` guard skipped strip on those, so `total_tokens` would still hit the wire. Helper now also reads `getattr(response, "usage", None)` and strips when that's a dict. Strongly-typed Pydantic `Usage` sub-models with required `total_tokens` fields are still skipped — those impose type constraints the helper doesn't try to subvert. Tests: - `test_strips_total_tokens_on_pydantic_model_with_dict_usage` - `test_flag_defaults_off` 8/8 pass locally. * fix(anthropic): drop env var for strip flag (docs CI) Mirrors #30418's pattern (`expose_router_debug_in_errors: bool = True`, no `os.getenv`). The `LITELLM_STRIP_ANTHROPIC_TOTAL_TOKENS` env var introduced in the prior commit was flagged by `tests/documentation_tests/test_env_keys.py` because the documentation file `docs/my-website/docs/proxy/config_settings.md` lives in `BerriAI/litellm-docs` (separate repo) and registering a new env key requires a parallel docs PR — a friction we avoid here by exposing the flag only as a Python attribute + `litellm_settings` config key, both of which load through the existing proxy config plumbing without needing the env-var registry to be updated. No semantic change: default still False, behavior identical when set via `litellm.strip_anthropic_total_tokens = True` or `litellm_settings.strip_anthropic_total_tokens: true` in config.yaml. Verified locally: env scan no longer surfaces the key; 8/8 tests pass. * ci: retrigger workflows after base branch change to litellm_internal_staging * fix(pricing): correct swapped input/output token costs for command-r7b-12-2024 (#30413) * fix(pricing): correct swapped input/output token costs for command-r7b-12-2024 * test: resolve model prices JSON relative to test file for pip installs * fix(exception-mapping): map Gemini upstream-error body code 429 to RateLimitError (#30417) * fix(exception-mapping): map Gemini upstream-error body code 429 to RateLimitError Some Gemini-compatible gateways (e.g. new-api) wrap a 429 rate-limit signal from upstream inside an HTTP 500/503 envelope, with the real code only surfaced in the JSON body: {"error":{"message":"...high demand...","type":"upstream_error", "param":"","code":429}} Previously LiteLLM only looked at the HTTP status and mapped this to InternalServerError, which Router treats as non-retryable for many configs — so users got hard 500s instead of fallback/retry. Now the Gemini/Vertex exception mapper parses error.code from the body and routes code 429 to RateLimitError before falling through to the HTTP-status branches. Other body codes fall through unchanged. Tests cover: - new-api gateway's `code:429` payload now maps to RateLimitError - Genuine 500-body responses stay InternalServerError - Non-JSON body strings fall through to status-code mapping unchanged * fix(exception-mapping): scope body-code 429 promotion to 5xx envelopes Addresses greptile P1/P2 + @Sameerlite's review on #30417. The new elif branch was firing for any HTTP status, so a gateway response of HTTP 400 with body {"error":{"code":429,...}} would be incorrectly promoted to RateLimitError (retryable) instead of falling through to BadRequestError. Same trap for 401 -> AuthenticationError. Scoped the body-code 429 check to `500 <= status_code < 600` — covers 500/502/503/504 (gateways wrapping upstream 429 in any 5xx envelope) without inviting the 4xx misclassification. Tests: parametrized table now covers 5xx (500/502/503), 4xx (400/401), and the existing fall-through cases, asserting each maps to the exception type that matches the HTTP status code. 50/50 pass locally. * ci: retrigger workflows after base branch change to litellm_internal_staging * feat(router): add expose_router_debug_in_errors flag (default True) to redact internal model_group/fallback names (#30418) * feat(router)!: redact internal model_group/fallback names from exception messages The Router was unconditionally appending internal config names onto exception.message: - "Received Model Group=..." - "Available Model Group Fallbacks=..." - "No fallback model group found... Fallbacks={...}" - "context_window_fallbacks={...}" - Deployment-timeout messages including model_group - Fallback failure detail listing fallback chain ProxyException forwards .message verbatim to clients, so gateways were leaking their model_name / fallback wiring in every failed call. Fix: gate all five mutation sites on a new `litellm.expose_router_debug_in_errors` flag (default False). Set to True to restore upstream debug behavior for local debugging. Why: matches the redaction posture this codebase already has for upstream model identifiers (cf. _litellm_returned_model_name) and removes the last common error-path leak of internal model_group names. Breaking change marker (!): if anything parses "Received Model Group=" out of client error messages, flip the flag on or migrate to the x-litellm-* response headers instead. Tests: 7 cases covering each of the 5 redaction sites + the flag-on inverse path, plus a "default off" sanity check. * test(router): cover sites 1 + 3 of expose_router_debug_in_errors gate Addresses Greptile / codecov feedback on #30418: patch coverage was 55.6% with 4 lines uncovered in litellm/router.py. The existing tests exercised sites 2 (ContextWindowExceededError), 4 (no-fallback-found), and 5 (Received Model Group) — both default and flag-on. Sites 1 and 3 were declared in the PR description as covered by "site 5 also fires" but the gate body lines for each (the `e.message +=` inside the `if litellm.expose_router_debug_in_errors:` branch) only execute when the flag is on AND the specific exception path is taken, which neither existing test triggered. Added 4 new tests (default + flag-on × 2 sites): - test_default_does_not_leak_deployment_timeout_debug - test_flag_on_leaks_deployment_timeout_debug - test_default_does_not_leak_content_policy_fallback_hint - test_flag_on_leaks_content_policy_fallback_hint Trigger details: - Site 1 (litellm.Timeout in _acompletion) is reached via the Router-supported `mock_timeout=True` + `timeout=0.001` kwargs on `acompletion(...)`. Cannot embed a Timeout instance in model_list because Router.__init__ deep-copies it and Timeout.__reduce__ does not preserve the required positional args. - Site 3 (ContentPolicyViolationError without content_policy_fallbacks set, in async_function_with_fallbacks_common_utils) is reached by passing a `mock_response=litellm.ContentPolicyViolationError(...)` instance via the call-site kwarg — same deepcopy-avoidance reason. 11/11 tests pass locally. Patch coverage on litellm/router.py for this PR's diff should now be 100%. * chore(router): flip expose_router_debug_in_errors default to True Addresses @Sameerlite's review on #30418 — maintain backward compat on the wire. Redact becomes opt-in via setting the flag to False; the historical behavior (leak internal model_group / fallback wiring through exception messages) is preserved as the default. - litellm/__init__.py: default flipped to True, docstring rewritten with deprecation note pointing at a future flip to False (redact by default) in a major release. - tests/test_litellm/test_router_exception_redaction.py: fixture resets to True (was False); the "off" tests now explicitly set False; the "default_leaks_*" tests rely on the fixture default. test_flag_defaults_off -> test_flag_defaults_on. - No router.py change needed; the gate keys off the same flag, only the default changes. - PR title no longer needs the breaking-change `!` marker — no client sees a behavior change at default settings. 11/11 pass locally. * ci: retrigger workflows after base branch change to litellm_internal_staging * feat(guardrails): integrate Repelloai Argus guardrail (#30465) * feat(guardrails): add RepelloAI Argus guardrail integration (#1) * feat(guardrails): add RepelloAI Argus guardrail integration Add a new guardrail hook backed by RepelloAI Argus, with dashboard-managed asset policies enforced via an asset_id and X-API-Key auth. * fix(guardrails): harden RepelloAI Argus guardrail - scan streaming responses on output (was bypassing the guardrail) - log blocked verdicts as guardrail_intervened instead of success - treat auth/config errors (401/403/404/422) as misconfiguration that always blocks, not a fail-open-able unreachable error - default unreachable_fallback to fail_closed and read it directly; block on unknown/malformed verdicts so an API change can't silently disable enforcement - type unreachable_fallback as a Literal, drop the duplicate config model, expose unreachable_fallback in the config schema, and stop leaking the raw provider response / exception strings to the client * fix(guardrails): address RepelloAI Argus review feedback - support ARGUS_API_KEY (with REPELLOAI_API_KEY fallback) - make asset_id required in the config model - normalize unreachable_fallback so only fail_open opens; block on 400 misconfig - correct the shared unreachable_fallback field description * docs(guardrails): add RepelloAI Argus docs page and dashboard listing - add docs page covering config, env vars, modes, verdicts, failure semantics - list RepelloAI Argus in the Guardrail Garden with provider/logo mappings - add a regression test for the provider logo and display-name resolution * fix(guardrails): keep RepelloAI asset_id optional in config model A required asset_id leaked onto the shared LitellmParams (which inherits RepelloAIGuardrailConfigModel), breaking validation for every other guardrail. Keep it optional like sibling models; the guardrail __init__ still raises when asset_id is missing, which is the real enforcement. * Add comment for last user turn scanning * feat(guardrails): harden repelloai scanning * feat(guardrails): expand repelloai scanning to include tool definitions Add extraction of tool definitions and tool call arguments to the RepelloAI guardrail scanning. Improves detection coverage by including function schemas and parameters in the prompt sent to the guardrail service. Also captures detailed error responses in logs and adds guardrail header to streaming responses. * refactor(guardrails): fix and harden repelloai schema text extraction - Fix duplicate text in _iter_schema_text: previously all dict values were re-queued onto the stack even after scalar/list keys were already extracted explicitly, causing names/descriptions to appear twice in the scanned prompt - Extract schema key frozensets to module-level constants so they are not reconstructed on every call - Change _iter_schema_text from @classmethod to @staticmethod (cls unused) - Narrow _call_analyze stage param from str to Literal["prompt", "response"] - Add HttpxResponse type annotation to _raise_for_config_error - Add LLMResponseTypes annotation to async_post_call_success_hook response param * fix(guardrails): resolve pyright type errors in repelloai guardrail - Narrow async_handler.post return from Response|None to Response with explicit None guard before calling raise_for_status/json - Fix list comprehension returning str|None by switching to explicit loop with isinstance guard so pyright tracks the narrowing - Cast model_dump() result to Dict since hasattr does not narrow object type in pyright * fix(guardrails/repello): include Responses API instructions field in prompt scan The /v1/responses top-level `instructions` field was not included in _extract_prompt_text, allowing a caller to bypass guardrail policy checks by putting blocked content in `instructions` while keeping `input` benign. * feat: add api_key to config model and read prompt from data dict * fix(guardrails/repello): plug input_text and tool-call response bypass gaps Responses API input content parts with type 'input_text' were silently dropped by build_inspection_messages (which only handles type='text'), allowing callers to send blocked content via that path without triggering the pre-call scan. Fix: add _extract_input_text_parts to RepelloAIGuardrail and call it when walking the Responses API input messages. Post-call scanning skipped responses whose choices contained only tool_calls or function_call (message.content=None), letting models put blocked output in function arguments undetected. Fix: _extract_chat_completion_text now calls _extract_tool_call_args_from_message on each choice message. Also replace typing.Dict/List with builtin dict/list to clear TID251 strict ruff violations introduced by this file. * fix(guardrails/repello): scan Responses API function_call output arguments Output items with type 'function_call' in a /v1/responses response were skipped by _extract_responses_api_text; only 'message' items were walked. A model could return blocked content in function_call.arguments undetected. Now extract arguments from function_call output items before scanning. * fix(anthropic): drop orphaned server_tool_use on multi-turn replay from generic OpenAI clients (#30486) * fix(anthropic): drop orphaned server_tool_use on multi-turn replay from generic OpenAI clients When an Anthropic server-side tool (web_search, id `srvtoolu_...`) is used, its result is carried in `provider_specific_fields.web_search_results` — PRs #17746 / #17798 restore it for callers that round-trip provider_specific_fields. A generic OpenAI client that does NOT preserve provider_specific_fields (e.g. Open WebUI talking to a Vertex/Anthropic model over /chat/completions) drops it on replay and instead sends back an assistant `tool_call` + a `tool` message both keyed to the `srvtoolu_` id. The transform then produced a bare `server_tool_use` (with no following *_tool_result) plus a user `tool_result` for the same id — both invalid, so the next turn 400s: messages.N.content.0: unexpected `tool_use_id` found in `tool_result` blocks: srvtoolu_... Each `tool_result` block must have a corresponding `tool_use` block in the previous message. This is the commonly-reported vertex_ai symptom where Gemini works but Claude 400s on the 2nd turn of a web-search chat. Fix (litellm/litellm_core_utils/prompt_templates/factory.py): - convert_to_anthropic_tool_invoke: only emit a server_tool_use when its matching *_tool_result is available to pair with it; otherwise skip it (a bare server_tool_use is itself rejected). - anthropic_messages_pt: drop a replayed `tool`/`function` message whose tool_call_id starts with `srvtoolu_` (a server-executed tool produces no client result; a user tool_result for it is invalid). The existing reconstruction path (provider_specific_fields present, e.g. the litellm SDK) is unchanged, as is regular client tool_use/tool_result. Tests (tests/llm_translation/test_prompt_factory.py): - update test_convert_to_anthropic_tool_invoke_server_tool -> test_convert_to_anthropic_tool_invoke_server_tool_without_result_is_dropped - add test_anthropic_messages_pt_generic_client_drops_orphan_server_tool Follow-up to #17746 / #17798; addresses the generic-client (no provider_specific_fields) case of #17737. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(anthropic): cover the srvtoolu_ round-trip fix in the test_litellm unit suite The regression tests added in tests/llm_translation/test_prompt_factory.py aren't run by the coverage CI job (it runs tests/test_litellm), so the new factory.py branches showed as uncovered (codecov patch coverage). Add equivalent focused tests in the unit suite so both new branches are exercised there: - convert_to_anthropic_tool_invoke drops a srvtoolu_ server_tool_use when no matching *_tool_result is available. - anthropic_messages_pt drops the orphaned srvtoolu_ tool message a generic OpenAI client replays. Refs #17737 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(anthropic): cover the server_tool_use + result valid-pair path in unit suite Covers the remaining patch-coverage lines codecov flagged: convert_to_anthropic_tool_invoke emitting server_tool_use followed by its web_search_tool_result when the matching result is present (the litellm-SDK round-trip path). Refs #17737 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * style(anthropic): flatten srvtoolu_ tool-message guard to a negated if Addresses the Greptile style nit: replace the if-pass/else with a single negated `if not (...)` guard around the tool_result append. Behavior unchanged. Refs #17737 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(proxy): require premium only when enabling premium metadata fields (#30285) (#30506) Co-authored-by: Sameer Kankute <sameer@berri.ai> * fix(perplexity): stop double-billing reasoning tokens in manual cost fallback (#30488) * fix(perplexity): stop double-billing reasoning tokens in manual cost fallback When perplexity_cost_per_token cannot use the API-provided usage.cost.total_cost short-circuit and falls back to manual calculation, it multiplies the full usage.completion_tokens by output_cost_per_token and then adds reasoning_tokens * output_cost_per_reasoning_token on top. Per the OpenAI/Perplexity usage convention codified for the central path in PR #18607, completion_tokens already INCLUDES reasoning_tokens, so the manual fallback double-bills reasoning at both the output and reasoning rate. Concrete impact on perplexity/sonar-deep-research (input 2e-6, output 8e-6, reasoning 3e-6): for the exact usage shape exercised by the live response fixture in tests/llm_translation/test_perplexity_reasoning.py (prompt_tokens=9, completion_tokens=20, reasoning_tokens=15) the current code charges 0.000223 vs the convention-correct 0.000103, a 2.165x overcharge. The bug is reachable whenever Perplexity omits the cost object (streaming chunks, fixture-driven paths, older API versions). Subtracts reasoning_tokens (clamped at zero) from completion_tokens before applying the output rate, mirroring how dashscope/cost_calculator.py and the central generic_cost_per_token already handle it. Preserves the existing fallback behaviour when output_cost_per_reasoning_token is unset (all completion_tokens stay at the output rate). Existing tests in tests/test_litellm/llms/perplexity/test_perplexity_cost_calculator.py asserted the buggy math and are updated to the convention-correct math. Adds a focused regression test using the exact usage shape from the live response fixture so this class of bug cannot be silently reintroduced. * style(perplexity): drop redundant type annotation on else branch to satisfy mypy mypy [no-redef] flagged 'completion_cost' as declared in both if and else arms; keeping the annotation only on the first declaration matches existing patterns in this file. * fix(perplexity): update integration test expected costs for non-double-billed math Three tests in test_perplexity_integration.py asserted the old buggy expectation that reasoning_tokens are billed in addition to the full completion_tokens count. After the fix in cost_per_token, reasoning_tokens are billed at the reasoning rate and the remaining (completion_tokens - reasoning_tokens) at the standard output rate, matching OpenAI/Perplexity convention (PR #18607). Updates: test_end_to_end_cost_calculation_with_transformation, test_main_cost_calculator_integration, test_high_volume_cost_calculation. The high-volume sanity threshold drops to 0.25 to reflect the corrected total. * fix(ui): use dynamic proxy base URL in MCP usage examples (#30487) Replace hardcoded http://localhost:4000 with getProxyBaseUrl() in the MCP server usage example and copy-to-clipboard snippet so the generated configuration works for non-local deployments. Fixes #30466 * feat: add missing UK PII entity types to Presidio guardrail (#30537) * feat: add missing UK PII entity types to Presidio guardrail Add UK_PASSPORT, UK_POSTCODE, and UK_VEHICLE_REGISTRATION to PiiEntityType enum and PII_ENTITY_CATEGORIES_MAP. These entity types are supported by Microsoft Presidio but were missing from litellm's type definitions, preventing users from configuring UK-specific PII detection. * test: remove fragile hardcoded entity count test Remove test_uk_category_entity_count which hardcodes len() == 5. The test_uk_entities_match_presidio_recognizers test already verifies exact set equality, making the count test redundant and fragile to future Presidio additions. * style: apply Black formatting to match CI requirements * fix: route volcengine (Doubao) tiered-pricing models to the tiered cost handler (#30357) Volcengine (Doubao) models define `tiered_pricing` but no flat per-token cost, so cost_per_token fell through to generic_cost_per_token (which only reads flat costs) and tracked them at $0 Route custom_llm_provider == "volcengine" to the shared tiered-pricing handler in litellm/llms/dashscope/cost_calculator.py, which already computes graduated tier costs. Make that handler provider-agnostic by adding a custom_llm_provider argument (default "dashscope" preserves existing behavior) so get_model_info resolves the correct model map entry Fixes #30346 * feat(mcp): make MCP gateway name and description configurable via env vars (#30473) * feat(mcp): make MCP gateway name and description configurable via env vars * Rename function _restore_env to _apply_env * docs(mcp): document import-time capture of env-backed identity constants Address Greptile review feedback: clarify that LITELLM_MCP_SERVER_NAME and LITELLM_MCP_SERVER_DESCRIPTION are read once at import and require a module reload to observe env changes after import. Generated with AI assistance Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Yevhen Luhovtsov <yevhen.luhovtsov@intapp.com> Co-authored-by: Claude <noreply@anthropic.com> * fix(mcp): preserve native tools in semantic filter hook (#26650) * fix(mcp): preserve native tools in semantic filter hook The SemanticToolFilterHook.async_pre_call_hook passed ALL tools (MCP + native) to filter_tools(), which only knows MCP-registered tool names. Native tools silently failed the name match in _get_tools_by_names() and were dropped from the request. Fix: partition tools into native and MCP-registered before filtering. Run the semantic filter only on MCP tools, then merge native tools back unconditionally. Changes: - Robust _is_mcp_tool() using shape-based detection for OpenAI-format dicts, safe regardless of future _extract_tool_info changes - Single-pass partition loop (no double _is_mcp_tool calls) - Preserve native tools in MCP expansion path (mixed requests) - Track MCP expansion to prevent expanded tools bypassing filtering - filter_stats reports MCP-only counts for accurate metrics - Extracted _emit_filter_metadata() helper - Skip spurious filter headers for all-native tool requests Closes #26212 * remove stale docstring note referencing tools_expanded_from_mcp * fix: handle Responses API name collision and preserve tool ordering - Classify Responses API tools ({type: 'function', name: '...'}) as native to prevent name collisions with MCP canonical names - Preserve original request tool ordering using id()-based merge instead of naive native+mcp concatenation - Add 2 regression tests: name collision and ordering preservation * style: apply black formatting * fix(mcp): harden semantic filter — preserve all native tool formats, safe metadata access, graceful expansion failure, name-based merge * lint: suppress PLR0915 on async_pre_call_hook (matches codebase convention) * ci: retrigger checks after rebase onto litellm_internal_staging * feat(fireworks): sync Fireworks AI model registry with current platform catalog (#30616) Adds 12 new Fireworks serverless models and updates 3 existing entries in model_prices_and_context_window.json and its bundled backup to match the current Fireworks platform model list. New direct models: glm-5p2, qwen3p7-plus, minimax-m3, minimax-m2p7, kimi-k2p7-code, kimi-k2p6, deepseek-v4-pro, deepseek-v4-flash. New router endpoints: glm-5p1-fast, kimi-k2p6-fast, kimi-k2p7-code-fast. Updated: glm-5p1, gpt-oss-120b, and gpt-oss-20b now carry correct output token caps, cache-read pricing, and explicit capability flags max_tokens is set equal to max_output_tokens (not the full context window) for models whose generation cap is below their context window. This avoids the shared input+output budget path in get_modified_max_tokens, which would otherwise let callers request output sizes the model cannot produce. The same fix corrects the pre-existing glm-5p1, gpt-oss-120b, and gpt-oss-20b entries that had max_tokens equal to the full context window Short-form aliases (fireworks_ai/<model>) are added for every direct accounts/fireworks/models/ entry so cost attribution works for callers using bare model names. Router endpoints get short-form aliases too, and transform_request now routes bare names ending in -fast to the accounts/fireworks/routers/ path instead of defaulting every bare name to models/. This keeps the kimi-k2p6-fast router from being misrouted to the nonexistent models/kimi-k2p6-fast endpoint kimi-k2p6-turbo is intentionally excluded; kimi-k2p6-fast is its replacement. Context windows for deepseek-v4 and kimi models use the power-of-two values (1048576 and 262144) published on the Fireworks model pages, matching the convention already used by existing entries Two regression tests in test_utils.py assert the exact per-token costs, token limits, capability flags, and short-form-to-long-form equality for all 15 models against both the main and backup cost maps. Two routing tests in test_fireworks_ai_chat_transformation.py verify bare -fast names route to routers/ and bare direct-model names route to models/ * fix(bedrock): handle role:"system" inside the messages array on /v1/messages (#29698) (#30443) * feat(anthropic): hoist leading in-array system to top-level (helper) * test(anthropic): cover _system_content_to_blocks edge cases; deepcopy cache_control * test(anthropic): mid-conversation system normalization cases * feat: add supports_mid_conversation_system flag to Claude Opus 4.8 Add supports_mid_conversation_system: true to all 9 claude-opus-4-8 cost-map entries (Anthropic-native, Bedrock, Vertex, Azure AI) in both the root cost map and the bundled package backup, since the runtime helper and tests read the backup in local/offline mode. Pin the mid-system passthrough regression test to the local cost map via the existing local_model_cost_map fixture so it reads the branch-local flag rather than the network-fetched main copy. * fix(bedrock): normalize in-array system in /v1/messages handler (#29698) Wire normalize_system_messages_for_anthropic into anthropic_messages_handler so all Bedrock /v1/messages paths (Invoke / Mantle / ClaudePlatform / Converse-bridge) hoist leading in-array system entries (and demote mid-conversation ones on models lacking supports_mid_conversation_system) into the top-level system field. The normalized messages/system are written back into the local_vars snapshot the base_llm branch reads from, otherwise the Invoke/Mantle fix would silently no-op. Also fix the helper to resolve supports_mid_conversation_system through the prefix-aware AnthropicModelInfo._supports_model_capability resolver. The raw _supports_factory could not see the flag once get_llm_provider left the invoke/ prefix on the model id, which would have wrongly demoted mid-conversation system on a Bedrock invoke opus-4-8 path. * fix(bedrock): resolve mid-conversation-system flag through mantle/invoke/converse route prefixes; drop unused param * fix(types): widen system param to Union[str, List] for hoisted system blocks * refactor(bedrock): drop dead local_vars messages writeback * fix(bedrock/converse): translate in-array system in anthropic->openai adapter (#29698) * fix(bedrock/converse): preserve cache_control on in-array system; test drop-empty * fix(bedrock/converse): rename colliding local to satisfy mypy; test handler system-merge branches * fix(types): register supports_mid_conversation_system in model-info schema The cost-map JSON-schema validation test (test_aaamodel_prices_and_context_window_json_is_valid) rejects unknown properties, so adding supports_mid_conversation_system to the opus-4-8 cost-map entries failed CI with 'Additional properties are not allowed'. Register the flag in the INTENDED_SCHEMA allow-list and in the ProviderSpecificModelInfo TypedDict so it is a typed, first-class capability flag alongside its peers (supports_output_config, etc.). --------- Co-authored-by: Sameer Kankute <sameer@berri.ai> * fix(bedrock/agentcore): optionally forward multimodal content blocks in InvokeAgentRuntime payload (#28885) * fix(bedrock/agentcore): optionally forward multimodal content blocks in InvokeAgentRuntime payload By default the agentcore provider flattens the last message to a text-only {"prompt": "..."} payload via convert_content_list_to_str, silently dropping OpenAI multimodal blocks (image_url, file, input_audio, ...). This adds an opt-in `forward_multimodal_content` litellm param. When truthy and the last message's content is a list containing a non-text block, the original OpenAI content list is forwarded verbatim under a new "content" field so an attachment-aware AgentCore agent can read it. Default off keeps the payload byte-identical to the legacy {"prompt": "..."} shape — existing agents are unaffected. The flag is read from optional_params (where other AgentCore params land) with a litellm_params fallback, and accepts a bool or a config/env string ('true', '1', ...). AgentCore Runtime is schemaless on the agent side — the agent's @app.entrypoint parses arbitrary JSON up to 100 MB (per https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-invoke-agent.html), so this is a purely upstream change; no AgentCore-side schema is asserted. * fix(bedrock/agentcore): shallow-copy forwarded multimodal content list Address review feedback (Sameerlite): payload["content"] = last_content aliased the caller's mutable messages[-1]["content"] list. Harmless today because the payload is JSON-serialized immediately, but a latent footgun if a future caller mutates the returned payload before serialization. Forward list(last_content) so the payload owns its own list. Block dicts stay shared on purpose — a deep copy would clone potentially large base64 media on the request hot path, and the flagged risk was the shared list, not the blocks. Update the passthrough tests to assert equality + distinct identity, and add a regression test that mutating the payload list can't leak back into the original message content. * Revert "fix(mcp): preserve native tools in semantic filter hook (#26650)" This reverts commit 438c825. * Revert "feat(guardrails): integrate Repelloai Argus guardrail (#30465)" This reverts commit 54da785. * Revert "feat(dashscope): add Responses API support (#30286)" This reverts commit 6766256. * Revert "fix(bedrock): handle role:"system" inside the messages array on /v1/messages (#29698) (#30443)" This reverts commit b8a8083. * Revert "fix(anthropic): drop orphaned server_tool_use on multi-turn replay from generic OpenAI clients (#30486)" This reverts commit 6e9c0b0. * Revert "fix: route volcengine (Doubao) tiered-pricing models to the tiered cost handler (#30357)" This reverts commit 172e302. * Revert "feat(proxy): serve Anthropic-native /v1/models for Claude Code gateway discovery (#30273)" This reverts commit 4e31885. * fix: pass key_limit=None in team_member_update and patch model_cost in pricing test team_member_update called team_info without key_limit, so the fastapi.Query default object (not None) was passed through to get_data, which failed when serializing it. Pass key_limit=None explicitly to avoid this. test_get_model_info_costs patched litellm.model_cost from the local backup so the assertion holds before the PR is merged and the remote main URL is updated. * fix(security): validate resolved model in /realtime/client_secrets for non-transcription sessions (#30710) Omitting both model and session.model caused the endpoint to default to gpt-4o-realtime-preview without running can_key_call_resolved_model, so any key could access that model regardless of its allowed-model list. The transcription path already called can_key_call_resolved_model; this adds the same call for the realtime path before returning. * fix(lint): fix F821 undefined model_info and F841 unused metadata in create_model_info_response * fix: black formatting and stub get_model_group_info in third team translation test * fix: reformat utils.py with black 26.3.1 to match CI * fix: replace Optional[X] with X | None to satisfy UP045 ruff strict gate --------- Co-authored-by: Habon Laszlo <habonlaci@users.noreply.github.com> Co-authored-by: habonlaci <4699494+habonlaci@users.noreply.github.com> Co-authored-by: Armaan Sandhu <74664101+Ar-maan05@users.noreply.github.com> Co-authored-by: santino18727-debug <santino18727@gmail.com> Co-authored-by: Eric (GabiDevFamily) <271972409+santino18727-debug@users.noreply.github.com> Co-authored-by: Nitish Agarwal <1592163+nitishagar@users.noreply.github.com> Co-authored-by: jho1-godaddy <171078705+jho1-godaddy@users.noreply.github.com> Co-authored-by: 安妮的心动录 <74543653+anneheartrecord@users.noreply.github.com> Co-authored-by: Harshith Gujjeti <153299927+Harshxth@users.noreply.github.com> Co-authored-by: Tomoya Tabuchi <t@tomoyat1.com> Co-authored-by: Vedant Agarwal <43557509+Vedant-Agarwal@users.noreply.github.com> Co-authored-by: Prathamesh Jadhav <55660103+lollinng@users.noreply.github.com> Co-authored-by: songkuan-zheng <252822057+songkuan-zheng@users.noreply.github.com> Co-authored-by: Kropiunig <48442031+Kropiunig@users.noreply.github.com> Co-authored-by: Lavish Bansal <lavish.bansal619@gmail.com> Co-authored-by: Shane Emmons <27679+semmons99@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Anuj ojha <ojhaanuj224@gmail.com> Co-authored-by: Nahrin <nahrin@nahrinoda.com> Co-authored-by: Nbouyaa <67773915+FadelT@users.noreply.github.com> Co-authored-by: Vineeth Sai <vineethsai4444@gmail.com> Co-authored-by: Eugene Lugovtsov <34510252+EugeneLugovtsov@users.noreply.github.com> Co-authored-by: Yevhen Luhovtsov <yevhen.luhovtsov@intapp.com> Co-authored-by: Ayush Shekhar <106994833+ayushh0110@users.noreply.github.com> Co-authored-by: Ahmad Shahzad <107808273+shzdehmd@users.noreply.github.com> Co-authored-by: Kent <72616338+kingdoooo@users.noreply.github.com> Co-authored-by: Jón Levy <levy@apro.is>
Comment on lines
+24
to
+29
| import { | ||
| useBudgets, | ||
| useDeleteBudget, | ||
| useCreateBudget, | ||
| useUpdateBudget, | ||
| } from "@/app/(dashboard)/hooks/budgets/useBudgets"; |
| @@ -417,11 +417,11 @@ | |||
| # ) | |||
| # response.stream_to_file("output_speech.mp3") | |||
| `;break;default:t="\n# Code generation for this endpoint is not implemented yet."}return`${w} | |||
| ${t}`}],190272)},916925,e=>{"use strict";var t,a=((t={}).A2A_Agent="A2A Agent",t.AI21="Ai21",t.AI21_CHAT="Ai21 Chat",t.AIML="AI/ML API",t.AIOHTTP_OPENAI="Aiohttp Openai",t.Anthropic="Anthropic",t.ANTHROPIC_TEXT="Anthropic Text",t.AssemblyAI="AssemblyAI",t.AUTO_ROUTER="Auto Router",t.Bedrock="Amazon Bedrock",t.BedrockMantle="Amazon Bedrock Mantle",t.SageMaker="AWS SageMaker",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Foundry (Studio)",t.AZURE_TEXT="Azure Text",t.BASETEN="Baseten",t.BYTEZ="Bytez",t.Cerebras="Cerebras",t.CLARIFAI="Clarifai",t.CLOUDFLARE="Cloudflare",t.CODESTRAL="Codestral",t.Cohere="Cohere",t.COHERE_CHAT="Cohere Chat",t.COMETAPI="Cometapi",t.COMPACTIFAI="Compactifai",t.Cursor="Cursor",t.Dashscope="Dashscope",t.Databricks="Databricks (Qwen API)",t.DATAROBOT="Datarobot",t.DeepInfra="DeepInfra",t.Deepgram="Deepgram",t.Deepseek="Deepseek",t.DOCKER_MODEL_RUNNER="Docker Model Runner",t.DOTPROMPT="Dotprompt",t.ElevenLabs="ElevenLabs",t.EMPOWER="Empower",t.FalAI="Fal AI",t.FEATHERLESS_AI="Featherless Ai",t.FireworksAI="Fireworks AI",t.FRIENDLIAI="Friendliai",t.GALADRIEL="Galadriel",t.GITHUB_COPILOT="Github Copilot",t.Google_AI_Studio="Google AI Studio",t.GradientAI="GradientAI",t.Groq="Groq",t.HEROKU="Heroku",t.Hosted_Vllm="vllm",t.HUGGINGFACE="Huggingface",t.HYPERBOLIC="Hyperbolic",t.Infinity="Infinity",t.JinaAI="Jina AI",t.LAMBDA_AI="Lambda Ai",t.LEMONADE="Lemonade",t.LLAMAFILE="Llamafile",t.LM_STUDIO="Lm Studio",t.LLAMA="Meta Llama",t.MARITALK="Maritalk",t.MiniMax="MiniMax",t.MistralAI="Mistral AI",t.MOONSHOT="Moonshot",t.MORPH="Morph",t.NEBIUS="Nebius",t.NLP_CLOUD="Nlp Cloud",t.NOVITA="Novita",t.NSCALE="Nscale",t.NVIDIA_NIM="Nvidia Nim",t.Ollama="Ollama",t.OLLAMA_CHAT="Ollama Chat",t.OOBABOOGA="Oobabooga",t.OpenAI="OpenAI",t.OPENAI_LIKE="Openai Like",t.OpenAI_Compatible="OpenAI-Compatible Endpoints (Together AI, etc.)",t.OpenAI_Text="OpenAI Text Completion",t.OpenAI_Text_Compatible="OpenAI-Compatible Text Completion Models (Together AI, etc.)",t.Openrouter="Openrouter",t.Oracle="Oracle Cloud Infrastructure (OCI)",t.OVHCLOUD="Ovhcloud",t.Perplexity="Perplexity",t.PETALS="Petals",t.PG_VECTOR="Pg Vector",t.PREDIBASE="Predibase",t.RECRAFT="Recraft",t.REPLICATE="Replicate",t.RunwayML="RunwayML",t.SAGEMAKER_LEGACY="Sagemaker",t.Sambanova="Sambanova",t.SAP="SAP Generative AI Hub",t.Snowflake="Snowflake",t.TEXT_COMPLETION_CODESTRAL="Text-Completion-Codestral",t.TogetherAI="TogetherAI",t.TOPAZ="Topaz",t.Triton="Triton",t.V0="V0",t.VERCEL_AI_GATEWAY="Vercel Ai Gateway",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.VERTEX_AI_BETA="Vertex Ai Beta",t.VLLM="Vllm",t.VolcEngine="VolcEngine",t.Voyage="Voyage AI",t.WANDB="Wandb",t.WATSONX="Watsonx",t.WATSONX_TEXT="Watsonx Text",t.xAI="xAI",t.XINFERENCE="Xinference",t.ZAI="Z.AI (Zhipu AI)",t);let i={A2A_Agent:"a2a_agent",AI21:"ai21",AI21_CHAT:"ai21_chat",AIML:"aiml",AIOHTTP_OPENAI:"aiohttp_openai",Anthropic:"anthropic",ANTHROPIC_TEXT:"anthropic_text",AssemblyAI:"assemblyai",AUTO_ROUTER:"auto_router",Azure:"azure",Azure_AI_Studio:"azure_ai",AZURE_TEXT:"azure_text",BASETEN:"baseten",Bedrock:"bedrock",BedrockMantle:"bedrock_mantle",BYTEZ:"bytez",Cerebras:"cerebras",CLARIFAI:"clarifai",CLOUDFLARE:"cloudflare",CODESTRAL:"codestral",Cohere:"cohere",COHERE_CHAT:"cohere_chat",COMETAPI:"cometapi",COMPACTIFAI:"compactifai",Cursor:"cursor",Dashscope:"dashscope",Databricks:"databricks",DATAROBOT:"datarobot",DeepInfra:"deepinfra",Deepgram:"deepgram",Deepseek:"deepseek",DOCKER_MODEL_RUNNER:"docker_model_runner",DOTPROMPT:"dotprompt",ElevenLabs:"elevenlabs",EMPOWER:"empower",FalAI:"fal_ai",FEATHERLESS_AI:"featherless_ai",FireworksAI:"fireworks_ai",FRIENDLIAI:"friendliai",GALADRIEL:"galadriel",GITHUB_COPILOT:"github_copilot",Google_AI_Studio:"gemini",GradientAI:"gradient_ai",Groq:"groq",HEROKU:"heroku",Hosted_Vllm:"hosted_vllm",HUGGINGFACE:"huggingface",HYPERBOLIC:"hyperbolic",Infinity:"infinity",JinaAI:"jina_ai",LAMBDA_AI:"lambda_ai",LEMONADE:"lemonade",LLAMAFILE:"llamafile",LLAMA:"meta_llama",LM_STUDIO:"lm_studio",MARITALK:"maritalk",MiniMax:"minimax",MistralAI:"mistral",MOONSHOT:"moonshot",MORPH:"morph",NEBIUS:"nebius",NLP_CLOUD:"nlp_cloud",NOVITA:"novita",NSCALE:"nscale",NVIDIA_NIM:"nvidia_nim",Ollama:"ollama",OLLAMA_CHAT:"ollama_chat",OOBABOOGA:"oobabooga",OpenAI:"openai",OPENAI_LIKE:"openai_like",OpenAI_Compatible:"openai",OpenAI_Text:"text-completion-openai",OpenAI_Text_Compatible:"text-completion-openai",Openrouter:"openrouter",Oracle:"oci",OVHCLOUD:"ovhcloud",Perplexity:"perplexity",PETALS:"petals",PG_VECTOR:"pg_vector",PREDIBASE:"predibase",RECRAFT:"recraft",REPLICATE:"replicate",RunwayML:"runwayml",SAGEMAKER_LEGACY:"sagemaker",SageMaker:"sagemaker_chat",Sambanova:"sambanova",SAP:"sap",Snowflake:"snowflake",TEXT_COMPLETION_CODESTRAL:"text-completion-codestral",TogetherAI:"together_ai",TOPAZ:"topaz",Triton:"triton",V0:"v0",VERCEL_AI_GATEWAY:"vercel_ai_gateway",Vertex_AI:"vertex_ai",VERTEX_AI_BETA:"vertex_ai_beta",VLLM:"vllm",VolcEngine:"volcengine",Voyage:"voyage",WANDB:"wandb",WATSONX:"watsonx",WATSONX_TEXT:"watsonx_text",xAI:"xai",XINFERENCE:"xinference",ZAI:"zai"},n="../ui/assets/logos/",o={"A2A Agent":`${n}a2a_agent.png`,Ai21:`${n}ai21.svg`,"Ai21 Chat":`${n}ai21.svg`,"AI/ML API":`${n}aiml_api.svg`,"Aiohttp Openai":`${n}openai_small.svg`,Anthropic:`${n}anthropic.svg`,"Anthropic Text":`${n}anthropic.svg`,AssemblyAI:`${n}assemblyai_small.png`,Azure:`${n}microsoft_azure.svg`,"Azure AI Foundry (Studio)":`${n}microsoft_azure.svg`,"Azure Text":`${n}microsoft_azure.svg`,Baseten:`${n}baseten.svg`,"Amazon Bedrock":`${n}bedrock.svg`,"Amazon Bedrock Mantle":`${n}bedrock.svg`,"AWS SageMaker":`${n}bedrock.svg`,Cerebras:`${n}cerebras.svg`,Cloudflare:`${n}cloudflare.svg`,Codestral:`${n}mistral.svg`,Cohere:`${n}cohere.svg`,"Cohere Chat":`${n}cohere.svg`,Cometapi:`${n}cometapi.svg`,Cursor:`${n}cursor.svg`,"Databricks (Qwen API)":`${n}databricks.svg`,Dashscope:`${n}dashscope.svg`,Deepseek:`${n}deepseek.svg`,Deepgram:`${n}deepgram.png`,DeepInfra:`${n}deepinfra.png`,ElevenLabs:`${n}elevenlabs.png`,"Fal AI":`${n}fal_ai.jpg`,"Featherless Ai":`${n}featherless.svg`,"Fireworks AI":`${n}fireworks.svg`,Friendliai:`${n}friendli.svg`,"Github Copilot":`${n}github_copilot.svg`,"Google AI Studio":`${n}google.svg`,GradientAI:`${n}gradientai.svg`,Groq:`${n}groq.svg`,vllm:`${n}vllm.png`,Huggingface:`${n}huggingface.svg`,Hyperbolic:`${n}hyperbolic.svg`,Infinity:`${n}infinity.png`,"Jina AI":`${n}jina.png`,"Lambda Ai":`${n}lambda.svg`,"Lm Studio":`${n}lmstudio.svg`,"Meta Llama":`${n}meta_llama.svg`,MiniMax:`${n}minimax.svg`,"Mistral AI":`${n}mistral.svg`,Moonshot:`${n}moonshot.svg`,Morph:`${n}morph.svg`,Nebius:`${n}nebius.svg`,Novita:`${n}novita.svg`,"Nvidia Nim":`${n}nvidia_nim.svg`,Ollama:`${n}ollama.svg`,"Ollama Chat":`${n}ollama.svg`,Oobabooga:`${n}openai_small.svg`,OpenAI:`${n}openai_small.svg`,"Openai Like":`${n}openai_small.svg`,"OpenAI Text Completion":`${n}openai_small.svg`,"OpenAI-Compatible Text Completion Models (Together AI, etc.)":`${n}openai_small.svg`,"OpenAI-Compatible Endpoints (Together AI, etc.)":`${n}openai_small.svg`,Openrouter:`${n}openrouter.svg`,"Oracle Cloud Infrastructure (OCI)":`${n}oracle.svg`,Perplexity:`${n}perplexity-ai.svg`,Recraft:`${n}recraft.svg`,Replicate:`${n}replicate.svg`,RunwayML:`${n}runwayml.png`,Sagemaker:`${n}bedrock.svg`,Sambanova:`${n}sambanova.svg`,"SAP Generative AI Hub":`${n}sap.png`,Snowflake:`${n}snowflake.svg`,"Text-Completion-Codestral":`${n}mistral.svg`,TogetherAI:`${n}togetherai.svg`,Topaz:`${n}topaz.svg`,Triton:`${n}nvidia_triton.png`,V0:`${n}v0.svg`,"Vercel Ai Gateway":`${n}vercel.svg`,"Vertex AI (Anthropic, Gemini, etc.)":`${n}google.svg`,"Vertex Ai Beta":`${n}google.svg`,Vllm:`${n}vllm.png`,VolcEngine:`${n}volcengine.png`,"Voyage AI":`${n}voyage.webp`,Watsonx:`${n}watsonx.svg`,"Watsonx Text":`${n}watsonx.svg`,xAI:`${n}xai.svg`,Xinference:`${n}xinference.svg`};e.s(["Providers",()=>a,"getPlaceholder",0,e=>{if("AI/ML API"===e)return"aiml/flux-pro/v1.1";if("Vertex AI (Anthropic, Gemini, etc.)"===e)return"gemini-pro";if("Anthropic"==e)return"claude-3-opus";if("Amazon Bedrock"==e)return"claude-3-opus";if("AWS SageMaker"==e)return"sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b";else if("Google AI Studio"==e)return"gemini-pro";else if("Azure AI Foundry (Studio)"==e)return"azure_ai/command-r-plus";else if("Azure"==e)return"my-deployment";else if("Oracle Cloud Infrastructure (OCI)"==e)return"oci/xai.grok-4";else if("Snowflake"==e)return"snowflake/mistral-7b";else if("Voyage AI"==e)return"voyage/";else if("Jina AI"==e)return"jina_ai/";else if("VolcEngine"==e)return"volcengine/<any-model-on-volcengine>";else if("DeepInfra"==e)return"deepinfra/<any-model-on-deepinfra>";else if("Fal AI"==e)return"fal_ai/fal-ai/flux-pro/v1.1-ultra";else if("RunwayML"==e)return"runwayml/gen4_turbo";else if("Watsonx"===e)return"watsonx/ibm/granite-3-3-8b-instruct";else if("Cursor"===e)return"cursor/claude-4-sonnet";else if("Z.AI (Zhipu AI)"===e)return"zai/glm-4.5";else return"gpt-3.5-turbo"},"getProviderLogoAndName",0,e=>{if(!e)return{logo:"",displayName:"-"};if("gemini"===e.toLowerCase()){let e="Google AI Studio";return{logo:o[e],displayName:e}}let t=Object.keys(i).find(t=>i[t].toLowerCase()===e.toLowerCase());if(!t)return{logo:"",displayName:e};let n=a[t];return{logo:o[n],displayName:n}},"getProviderModels",0,(e,t)=>{console.log(`Provider key: ${e}`);let a=i[e];console.log(`Provider mapped to: ${a}`);let n=[];return e&&"object"==typeof t&&(Object.entries(t).forEach(([e,t])=>{if(null!==t&&"object"==typeof t&&"litellm_provider"in t){let i=t.litellm_provider;(i===a||"string"==typeof i&&(i.startsWith(`${a}_`)||i.startsWith(`${a}-`)))&&n.push(e)}}),"Cohere"==e&&(console.log("Adding cohere chat models"),Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"cohere_chat"===t.litellm_provider&&n.push(e)})),"AWS SageMaker"==e&&(console.log("Adding sagemaker chat models"),Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"sagemaker_chat"===t.litellm_provider&&n.push(e)}))),n},"providerLogoMap",0,o,"provider_map",0,i])},185793,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),i=e.i(242064),n=e.i(529681);let o=e=>{let{prefixCls:i,className:n,style:o,size:r,shape:l}=e,s=(0,a.default)({[`${i}-lg`]:"large"===r,[`${i}-sm`]:"small"===r}),c=(0,a.default)({[`${i}-circle`]:"circle"===l,[`${i}-square`]:"square"===l,[`${i}-round`]:"round"===l}),p=t.useMemo(()=>"number"==typeof r?{width:r,height:r,lineHeight:`${r}px`}:{},[r]);return t.createElement("span",{className:(0,a.default)(i,s,c,n),style:Object.assign(Object.assign({},p),o)})};e.i(296059);var r=e.i(694758),l=e.i(915654),s=e.i(246422),c=e.i(838378);let p=new r.Keyframes("ant-skeleton-loading",{"0%":{backgroundPosition:"100% 50%"},"100%":{backgroundPosition:"0 50%"}}),d=e=>({height:e,lineHeight:(0,l.unit)(e)}),g=e=>Object.assign({width:e},d(e)),u=(e,t)=>Object.assign({width:t(e).mul(5).equal(),minWidth:t(e).mul(5).equal()},d(e)),m=e=>Object.assign({width:e},d(e)),f=(e,t,a)=>{let{skeletonButtonCls:i}=e;return{[`${a}${i}-circle`]:{width:t,minWidth:t,borderRadius:"50%"},[`${a}${i}-round`]:{borderRadius:t}}},_=(e,t)=>Object.assign({width:t(e).mul(2).equal(),minWidth:t(e).mul(2).equal()},d(e)),h=(0,s.genStyleHooks)("Skeleton",e=>{let{componentCls:t,calc:a}=e;return(e=>{let{componentCls:t,skeletonAvatarCls:a,skeletonTitleCls:i,skeletonParagraphCls:n,skeletonButtonCls:o,skeletonInputCls:r,skeletonImageCls:l,controlHeight:s,controlHeightLG:c,controlHeightSM:d,gradientFromColor:h,padding:b,marginSM:A,borderRadius:v,titleHeight:O,blockRadius:I,paragraphLiHeight:$,controlHeightXS:x,paragraphMarginTop:E}=e;return{[t]:{display:"table",width:"100%",[`${t}-header`]:{display:"table-cell",paddingInlineEnd:b,verticalAlign:"top",[a]:Object.assign({display:"inline-block",verticalAlign:"top",background:h},g(s)),[`${a}-circle`]:{borderRadius:"50%"},[`${a}-lg`]:Object.assign({},g(c)),[`${a}-sm`]:Object.assign({},g(d))},[`${t}-content`]:{display:"table-cell",width:"100%",verticalAlign:"top",[i]:{width:"100%",height:O,background:h,borderRadius:I,[`+ ${n}`]:{marginBlockStart:d}},[n]:{padding:0,"> li":{width:"100%",height:$,listStyle:"none",background:h,borderRadius:I,"+ li":{marginBlockStart:x}}},[`${n}> li:last-child:not(:first-child):not(:nth-child(2))`]:{width:"61%"}},[`&-round ${t}-content`]:{[`${i}, ${n} > li`]:{borderRadius:v}}},[`${t}-with-avatar ${t}-content`]:{[i]:{marginBlockStart:A,[`+ ${n}`]:{marginBlockStart:E}}},[`${t}${t}-element`]:Object.assign(Object.assign(Object.assign(Object.assign({display:"inline-block",width:"auto"},(e=>{let{borderRadiusSM:t,skeletonButtonCls:a,controlHeight:i,controlHeightLG:n,controlHeightSM:o,gradientFromColor:r,calc:l}=e;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({[a]:Object.assign({display:"inline-block",verticalAlign:"top",background:r,borderRadius:t,width:l(i).mul(2).equal(),minWidth:l(i).mul(2).equal()},_(i,l))},f(e,i,a)),{[`${a}-lg`]:Object.assign({},_(n,l))}),f(e,n,`${a}-lg`)),{[`${a}-sm`]:Object.assign({},_(o,l))}),f(e,o,`${a}-sm`))})(e)),(e=>{let{skeletonAvatarCls:t,gradientFromColor:a,controlHeight:i,controlHeightLG:n,controlHeightSM:o}=e;return{[t]:Object.assign({display:"inline-block",verticalAlign:"top",background:a},g(i)),[`${t}${t}-circle`]:{borderRadius:"50%"},[`${t}${t}-lg`]:Object.assign({},g(n)),[`${t}${t}-sm`]:Object.assign({},g(o))}})(e)),(e=>{let{controlHeight:t,borderRadiusSM:a,skeletonInputCls:i,controlHeightLG:n,controlHeightSM:o,gradientFromColor:r,calc:l}=e;return{[i]:Object.assign({display:"inline-block",verticalAlign:"top",background:r,borderRadius:a},u(t,l)),[`${i}-lg`]:Object.assign({},u(n,l)),[`${i}-sm`]:Object.assign({},u(o,l))}})(e)),(e=>{let{skeletonImageCls:t,imageSizeBase:a,gradientFromColor:i,borderRadiusSM:n,calc:o}=e;return{[t]:Object.assign(Object.assign({display:"inline-flex",alignItems:"center",justifyContent:"center",verticalAlign:"middle",background:i,borderRadius:n},m(o(a).mul(2).equal())),{[`${t}-path`]:{fill:"#bfbfbf"},[`${t}-svg`]:Object.assign(Object.assign({},m(a)),{maxWidth:o(a).mul(4).equal(),maxHeight:o(a).mul(4).equal()}),[`${t}-svg${t}-svg-circle`]:{borderRadius:"50%"}}),[`${t}${t}-circle`]:{borderRadius:"50%"}}})(e)),[`${t}${t}-block`]:{width:"100%",[o]:{width:"100%"},[r]:{width:"100%"}},[`${t}${t}-active`]:{[` | |||
| ${t}`}],190272)},916925,e=>{"use strict";var t,a=((t={}).A2A_Agent="A2A Agent",t.AI21="Ai21",t.AI21_CHAT="Ai21 Chat",t.AIML="AI/ML API",t.AIOHTTP_OPENAI="Aiohttp Openai",t.Anthropic="Anthropic",t.ANTHROPIC_TEXT="Anthropic Text",t.AssemblyAI="AssemblyAI",t.AUTO_ROUTER="Auto Router",t.Bedrock="Amazon Bedrock",t.BedrockMantle="Amazon Bedrock Mantle",t.SageMaker="AWS SageMaker",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Foundry (Studio)",t.AZURE_TEXT="Azure Text",t.BASETEN="Baseten",t.BYTEZ="Bytez",t.Cerebras="Cerebras",t.CLARIFAI="Clarifai",t.CLOUDFLARE="Cloudflare",t.CODESTRAL="Codestral",t.Cohere="Cohere",t.COHERE_CHAT="Cohere Chat",t.COMETAPI="Cometapi",t.COMPACTIFAI="Compactifai",t.Cursor="Cursor",t.Dashscope="Dashscope",t.Databricks="Databricks (Qwen API)",t.DATAROBOT="Datarobot",t.DeepInfra="DeepInfra",t.Deepgram="Deepgram",t.Deepseek="Deepseek",t.DOCKER_MODEL_RUNNER="Docker Model Runner",t.DOTPROMPT="Dotprompt",t.ElevenLabs="ElevenLabs",t.EMPOWER="Empower",t.FalAI="Fal AI",t.FEATHERLESS_AI="Featherless Ai",t.FireworksAI="Fireworks AI",t.FRIENDLIAI="Friendliai",t.GALADRIEL="Galadriel",t.GITHUB_COPILOT="Github Copilot",t.Google_AI_Studio="Google AI Studio",t.GradientAI="GradientAI",t.Groq="Groq",t.HEROKU="Heroku",t.Hosted_Vllm="vllm",t.HUGGINGFACE="Huggingface",t.HYPERBOLIC="Hyperbolic",t.Infinity="Infinity",t.JinaAI="Jina AI",t.LAMBDA_AI="Lambda Ai",t.LEMONADE="Lemonade",t.LLAMAFILE="Llamafile",t.LM_STUDIO="Lm Studio",t.LLAMA="Meta Llama",t.MARITALK="Maritalk",t.MiniMax="MiniMax",t.MistralAI="Mistral AI",t.MOONSHOT="Moonshot",t.MORPH="Morph",t.NEBIUS="Nebius",t.NLP_CLOUD="Nlp Cloud",t.NOVITA="Novita",t.NSCALE="Nscale",t.NVIDIA_NIM="Nvidia Nim",t.Ollama="Ollama",t.OLLAMA_CHAT="Ollama Chat",t.OOBABOOGA="Oobabooga",t.OpenAI="OpenAI",t.OPENAI_LIKE="Openai Like",t.OpenAI_Compatible="OpenAI-Compatible Endpoints (Together AI, etc.)",t.OpenAI_Text="OpenAI Text Completion",t.OpenAI_Text_Compatible="OpenAI-Compatible Text Completion Models (Together AI, etc.)",t.Openrouter="Openrouter",t.Oracle="Oracle Cloud Infrastructure (OCI)",t.OVHCLOUD="Ovhcloud",t.Perplexity="Perplexity",t.PETALS="Petals",t.PG_VECTOR="Pg Vector",t.PREDIBASE="Predibase",t.RECRAFT="Recraft",t.REPLICATE="Replicate",t.RunwayML="RunwayML",t.SAGEMAKER_LEGACY="Sagemaker",t.Sambanova="Sambanova",t.SAP="SAP Generative AI Hub",t.Snowflake="Snowflake",t.Soniox="Soniox",t.TEXT_COMPLETION_CODESTRAL="Text-Completion-Codestral",t.TogetherAI="TogetherAI",t.TOPAZ="Topaz",t.Triton="Triton",t.V0="V0",t.VERCEL_AI_GATEWAY="Vercel Ai Gateway",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.VERTEX_AI_BETA="Vertex Ai Beta",t.VLLM="Vllm",t.VolcEngine="VolcEngine",t.Voyage="Voyage AI",t.WANDB="Wandb",t.WATSONX="Watsonx",t.WATSONX_TEXT="Watsonx Text",t.xAI="xAI",t.XINFERENCE="Xinference",t.ZAI="Z.AI (Zhipu AI)",t);let i={A2A_Agent:"a2a_agent",AI21:"ai21",AI21_CHAT:"ai21_chat",AIML:"aiml",AIOHTTP_OPENAI:"aiohttp_openai",Anthropic:"anthropic",ANTHROPIC_TEXT:"anthropic_text",AssemblyAI:"assemblyai",AUTO_ROUTER:"auto_router",Azure:"azure",Azure_AI_Studio:"azure_ai",AZURE_TEXT:"azure_text",BASETEN:"baseten",Bedrock:"bedrock",BedrockMantle:"bedrock_mantle",BYTEZ:"bytez",Cerebras:"cerebras",CLARIFAI:"clarifai",CLOUDFLARE:"cloudflare",CODESTRAL:"codestral",Cohere:"cohere",COHERE_CHAT:"cohere_chat",COMETAPI:"cometapi",COMPACTIFAI:"compactifai",Cursor:"cursor",Dashscope:"dashscope",Databricks:"databricks",DATAROBOT:"datarobot",DeepInfra:"deepinfra",Deepgram:"deepgram",Deepseek:"deepseek",DOCKER_MODEL_RUNNER:"docker_model_runner",DOTPROMPT:"dotprompt",ElevenLabs:"elevenlabs",EMPOWER:"empower",FalAI:"fal_ai",FEATHERLESS_AI:"featherless_ai",FireworksAI:"fireworks_ai",FRIENDLIAI:"friendliai",GALADRIEL:"galadriel",GITHUB_COPILOT:"github_copilot",Google_AI_Studio:"gemini",GradientAI:"gradient_ai",Groq:"groq",HEROKU:"heroku",Hosted_Vllm:"hosted_vllm",HUGGINGFACE:"huggingface",HYPERBOLIC:"hyperbolic",Infinity:"infinity",JinaAI:"jina_ai",LAMBDA_AI:"lambda_ai",LEMONADE:"lemonade",LLAMAFILE:"llamafile",LLAMA:"meta_llama",LM_STUDIO:"lm_studio",MARITALK:"maritalk",MiniMax:"minimax",MistralAI:"mistral",MOONSHOT:"moonshot",MORPH:"morph",NEBIUS:"nebius",NLP_CLOUD:"nlp_cloud",NOVITA:"novita",NSCALE:"nscale",NVIDIA_NIM:"nvidia_nim",Ollama:"ollama",OLLAMA_CHAT:"ollama_chat",OOBABOOGA:"oobabooga",OpenAI:"openai",OPENAI_LIKE:"openai_like",OpenAI_Compatible:"openai",OpenAI_Text:"text-completion-openai",OpenAI_Text_Compatible:"text-completion-openai",Openrouter:"openrouter",Oracle:"oci",OVHCLOUD:"ovhcloud",Perplexity:"perplexity",PETALS:"petals",PG_VECTOR:"pg_vector",PREDIBASE:"predibase",RECRAFT:"recraft",REPLICATE:"replicate",RunwayML:"runwayml",SAGEMAKER_LEGACY:"sagemaker",SageMaker:"sagemaker_chat",Sambanova:"sambanova",SAP:"sap",Snowflake:"snowflake",Soniox:"soniox",TEXT_COMPLETION_CODESTRAL:"text-completion-codestral",TogetherAI:"together_ai",TOPAZ:"topaz",Triton:"triton",V0:"v0",VERCEL_AI_GATEWAY:"vercel_ai_gateway",Vertex_AI:"vertex_ai",VERTEX_AI_BETA:"vertex_ai_beta",VLLM:"vllm",VolcEngine:"volcengine",Voyage:"voyage",WANDB:"wandb",WATSONX:"watsonx",WATSONX_TEXT:"watsonx_text",xAI:"xai",XINFERENCE:"xinference",ZAI:"zai"},n="../ui/assets/logos/",o={"A2A Agent":`${n}a2a_agent.png`,Ai21:`${n}ai21.svg`,"Ai21 Chat":`${n}ai21.svg`,"AI/ML API":`${n}aiml_api.svg`,"Aiohttp Openai":`${n}openai_small.svg`,Anthropic:`${n}anthropic.svg`,"Anthropic Text":`${n}anthropic.svg`,AssemblyAI:`${n}assemblyai_small.png`,Azure:`${n}microsoft_azure.svg`,"Azure AI Foundry (Studio)":`${n}microsoft_azure.svg`,"Azure Text":`${n}microsoft_azure.svg`,Baseten:`${n}baseten.svg`,"Amazon Bedrock":`${n}bedrock.svg`,"Amazon Bedrock Mantle":`${n}bedrock.svg`,"AWS SageMaker":`${n}bedrock.svg`,Cerebras:`${n}cerebras.svg`,Cloudflare:`${n}cloudflare.svg`,Codestral:`${n}mistral.svg`,Cohere:`${n}cohere.svg`,"Cohere Chat":`${n}cohere.svg`,Cometapi:`${n}cometapi.svg`,Cursor:`${n}cursor.svg`,"Databricks (Qwen API)":`${n}databricks.svg`,Dashscope:`${n}dashscope.svg`,Deepseek:`${n}deepseek.svg`,Deepgram:`${n}deepgram.png`,DeepInfra:`${n}deepinfra.png`,ElevenLabs:`${n}elevenlabs.png`,"Fal AI":`${n}fal_ai.jpg`,"Featherless Ai":`${n}featherless.svg`,"Fireworks AI":`${n}fireworks.svg`,Friendliai:`${n}friendli.svg`,"Github Copilot":`${n}github_copilot.svg`,"Google AI Studio":`${n}google.svg`,GradientAI:`${n}gradientai.svg`,Groq:`${n}groq.svg`,vllm:`${n}vllm.png`,Huggingface:`${n}huggingface.svg`,Hyperbolic:`${n}hyperbolic.svg`,Infinity:`${n}infinity.png`,"Jina AI":`${n}jina.png`,"Lambda Ai":`${n}lambda.svg`,"Lm Studio":`${n}lmstudio.svg`,"Meta Llama":`${n}meta_llama.svg`,MiniMax:`${n}minimax.svg`,"Mistral AI":`${n}mistral.svg`,Moonshot:`${n}moonshot.svg`,Morph:`${n}morph.svg`,Nebius:`${n}nebius.svg`,Novita:`${n}novita.svg`,"Nvidia Nim":`${n}nvidia_nim.svg`,Ollama:`${n}ollama.svg`,"Ollama Chat":`${n}ollama.svg`,Oobabooga:`${n}openai_small.svg`,OpenAI:`${n}openai_small.svg`,"Openai Like":`${n}openai_small.svg`,"OpenAI Text Completion":`${n}openai_small.svg`,"OpenAI-Compatible Text Completion Models (Together AI, etc.)":`${n}openai_small.svg`,"OpenAI-Compatible Endpoints (Together AI, etc.)":`${n}openai_small.svg`,Openrouter:`${n}openrouter.svg`,"Oracle Cloud Infrastructure (OCI)":`${n}oracle.svg`,Perplexity:`${n}perplexity-ai.svg`,Recraft:`${n}recraft.svg`,Replicate:`${n}replicate.svg`,RunwayML:`${n}runwayml.png`,Sagemaker:`${n}bedrock.svg`,Sambanova:`${n}sambanova.svg`,"SAP Generative AI Hub":`${n}sap.png`,Snowflake:`${n}snowflake.svg`,Soniox:`${n}soniox.svg`,"Text-Completion-Codestral":`${n}mistral.svg`,TogetherAI:`${n}togetherai.svg`,Topaz:`${n}topaz.svg`,Triton:`${n}nvidia_triton.png`,V0:`${n}v0.svg`,"Vercel Ai Gateway":`${n}vercel.svg`,"Vertex AI (Anthropic, Gemini, etc.)":`${n}google.svg`,"Vertex Ai Beta":`${n}google.svg`,Vllm:`${n}vllm.png`,VolcEngine:`${n}volcengine.png`,"Voyage AI":`${n}voyage.webp`,Watsonx:`${n}watsonx.svg`,"Watsonx Text":`${n}watsonx.svg`,xAI:`${n}xai.svg`,Xinference:`${n}xinference.svg`};e.s(["Providers",()=>a,"getPlaceholder",0,e=>{if("AI/ML API"===e)return"aiml/flux-pro/v1.1";if("Vertex AI (Anthropic, Gemini, etc.)"===e)return"gemini-pro";if("Anthropic"==e)return"claude-3-opus";if("Amazon Bedrock"==e)return"claude-3-opus";if("AWS SageMaker"==e)return"sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b";else if("Google AI Studio"==e)return"gemini-pro";else if("Azure AI Foundry (Studio)"==e)return"azure_ai/command-r-plus";else if("Azure"==e)return"my-deployment";else if("Oracle Cloud Infrastructure (OCI)"==e)return"oci/xai.grok-4";else if("Snowflake"==e)return"snowflake/mistral-7b";else if("Voyage AI"==e)return"voyage/";else if("Jina AI"==e)return"jina_ai/";else if("VolcEngine"==e)return"volcengine/<any-model-on-volcengine>";else if("DeepInfra"==e)return"deepinfra/<any-model-on-deepinfra>";else if("Fal AI"==e)return"fal_ai/fal-ai/flux-pro/v1.1-ultra";else if("RunwayML"==e)return"runwayml/gen4_turbo";else if("Watsonx"===e)return"watsonx/ibm/granite-3-3-8b-instruct";else if("Cursor"===e)return"cursor/claude-4-sonnet";else if("Z.AI (Zhipu AI)"===e)return"zai/glm-4.5";else return"gpt-3.5-turbo"},"getProviderLogoAndName",0,e=>{if(!e)return{logo:"",displayName:"-"};if("gemini"===e.toLowerCase()){let e="Google AI Studio";return{logo:o[e],displayName:e}}let t=Object.keys(i).find(t=>i[t].toLowerCase()===e.toLowerCase());if(!t)return{logo:"",displayName:e};let n=a[t];return{logo:o[n],displayName:n}},"getProviderModels",0,(e,t)=>{console.log(`Provider key: ${e}`);let a=i[e];console.log(`Provider mapped to: ${a}`);let n=[];return e&&"object"==typeof t&&(Object.entries(t).forEach(([e,t])=>{if(null!==t&&"object"==typeof t&&"litellm_provider"in t){let i=t.litellm_provider;(i===a||"string"==typeof i&&(i.startsWith(`${a}_`)||i.startsWith(`${a}-`)))&&n.push(e)}}),"Cohere"==e&&(console.log("Adding cohere chat models"),Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"cohere_chat"===t.litellm_provider&&n.push(e)})),"AWS SageMaker"==e&&(console.log("Adding sagemaker chat models"),Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"sagemaker_chat"===t.litellm_provider&&n.push(e)}))),n},"providerLogoMap",0,o,"provider_map",0,i])},185793,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),i=e.i(242064),n=e.i(529681);let o=e=>{let{prefixCls:i,className:n,style:o,size:r,shape:l}=e,s=(0,a.default)({[`${i}-lg`]:"large"===r,[`${i}-sm`]:"small"===r}),c=(0,a.default)({[`${i}-circle`]:"circle"===l,[`${i}-square`]:"square"===l,[`${i}-round`]:"round"===l}),p=t.useMemo(()=>"number"==typeof r?{width:r,height:r,lineHeight:`${r}px`}:{},[r]);return t.createElement("span",{className:(0,a.default)(i,s,c,n),style:Object.assign(Object.assign({},p),o)})};e.i(296059);var r=e.i(694758),l=e.i(915654),s=e.i(246422),c=e.i(838378);let p=new r.Keyframes("ant-skeleton-loading",{"0%":{backgroundPosition:"100% 50%"},"100%":{backgroundPosition:"0 50%"}}),d=e=>({height:e,lineHeight:(0,l.unit)(e)}),g=e=>Object.assign({width:e},d(e)),u=(e,t)=>Object.assign({width:t(e).mul(5).equal(),minWidth:t(e).mul(5).equal()},d(e)),m=e=>Object.assign({width:e},d(e)),f=(e,t,a)=>{let{skeletonButtonCls:i}=e;return{[`${a}${i}-circle`]:{width:t,minWidth:t,borderRadius:"50%"},[`${a}${i}-round`]:{borderRadius:t}}},_=(e,t)=>Object.assign({width:t(e).mul(2).equal(),minWidth:t(e).mul(2).equal()},d(e)),h=(0,s.genStyleHooks)("Skeleton",e=>{let{componentCls:t,calc:a}=e;return(e=>{let{componentCls:t,skeletonAvatarCls:a,skeletonTitleCls:i,skeletonParagraphCls:n,skeletonButtonCls:o,skeletonInputCls:r,skeletonImageCls:l,controlHeight:s,controlHeightLG:c,controlHeightSM:d,gradientFromColor:h,padding:b,marginSM:A,borderRadius:v,titleHeight:O,blockRadius:I,paragraphLiHeight:x,controlHeightXS:$,paragraphMarginTop:E}=e;return{[t]:{display:"table",width:"100%",[`${t}-header`]:{display:"table-cell",paddingInlineEnd:b,verticalAlign:"top",[a]:Object.assign({display:"inline-block",verticalAlign:"top",background:h},g(s)),[`${a}-circle`]:{borderRadius:"50%"},[`${a}-lg`]:Object.assign({},g(c)),[`${a}-sm`]:Object.assign({},g(d))},[`${t}-content`]:{display:"table-cell",width:"100%",verticalAlign:"top",[i]:{width:"100%",height:O,background:h,borderRadius:I,[`+ ${n}`]:{marginBlockStart:d}},[n]:{padding:0,"> li":{width:"100%",height:x,listStyle:"none",background:h,borderRadius:I,"+ li":{marginBlockStart:$}}},[`${n}> li:last-child:not(:first-child):not(:nth-child(2))`]:{width:"61%"}},[`&-round ${t}-content`]:{[`${i}, ${n} > li`]:{borderRadius:v}}},[`${t}-with-avatar ${t}-content`]:{[i]:{marginBlockStart:A,[`+ ${n}`]:{marginBlockStart:E}}},[`${t}${t}-element`]:Object.assign(Object.assign(Object.assign(Object.assign({display:"inline-block",width:"auto"},(e=>{let{borderRadiusSM:t,skeletonButtonCls:a,controlHeight:i,controlHeightLG:n,controlHeightSM:o,gradientFromColor:r,calc:l}=e;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({[a]:Object.assign({display:"inline-block",verticalAlign:"top",background:r,borderRadius:t,width:l(i).mul(2).equal(),minWidth:l(i).mul(2).equal()},_(i,l))},f(e,i,a)),{[`${a}-lg`]:Object.assign({},_(n,l))}),f(e,n,`${a}-lg`)),{[`${a}-sm`]:Object.assign({},_(o,l))}),f(e,o,`${a}-sm`))})(e)),(e=>{let{skeletonAvatarCls:t,gradientFromColor:a,controlHeight:i,controlHeightLG:n,controlHeightSM:o}=e;return{[t]:Object.assign({display:"inline-block",verticalAlign:"top",background:a},g(i)),[`${t}${t}-circle`]:{borderRadius:"50%"},[`${t}${t}-lg`]:Object.assign({},g(n)),[`${t}${t}-sm`]:Object.assign({},g(o))}})(e)),(e=>{let{controlHeight:t,borderRadiusSM:a,skeletonInputCls:i,controlHeightLG:n,controlHeightSM:o,gradientFromColor:r,calc:l}=e;return{[i]:Object.assign({display:"inline-block",verticalAlign:"top",background:r,borderRadius:a},u(t,l)),[`${i}-lg`]:Object.assign({},u(n,l)),[`${i}-sm`]:Object.assign({},u(o,l))}})(e)),(e=>{let{skeletonImageCls:t,imageSizeBase:a,gradientFromColor:i,borderRadiusSM:n,calc:o}=e;return{[t]:Object.assign(Object.assign({display:"inline-flex",alignItems:"center",justifyContent:"center",verticalAlign:"middle",background:i,borderRadius:n},m(o(a).mul(2).equal())),{[`${t}-path`]:{fill:"#bfbfbf"},[`${t}-svg`]:Object.assign(Object.assign({},m(a)),{maxWidth:o(a).mul(4).equal(),maxHeight:o(a).mul(4).equal()}),[`${t}-svg${t}-svg-circle`]:{borderRadius:"50%"}}),[`${t}${t}-circle`]:{borderRadius:"50%"}}})(e)),[`${t}${t}-block`]:{width:"100%",[o]:{width:"100%"},[r]:{width:"100%"}},[`${t}${t}-active`]:{[` | |||
| @@ -1,4 +1,4 @@ | |||
| (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,798496,e=>{"use strict";var t=e.i(843476),a=e.i(152990),i=e.i(682830),n=e.i(271645),o=e.i(269200),r=e.i(427612),l=e.i(64848),s=e.i(942232),c=e.i(496020),p=e.i(977572),d=e.i(94629),g=e.i(360820),u=e.i(871943);function m({data:e=[],columns:m,isLoading:f=!1,defaultSorting:_=[],pagination:h,onPaginationChange:b,enablePagination:A=!1,onRowClick:v}){let[O,I]=n.default.useState(_),[$]=n.default.useState("onChange"),[x,E]=n.default.useState({}),[C,y]=n.default.useState({}),w=(0,a.useReactTable)({data:e,columns:m,state:{sorting:O,columnSizing:x,columnVisibility:C,...A&&h?{pagination:h}:{}},columnResizeMode:$,onSortingChange:I,onColumnSizingChange:E,onColumnVisibilityChange:y,...A&&b?{onPaginationChange:b}:{},getCoreRowModel:(0,i.getCoreRowModel)(),getSortedRowModel:(0,i.getSortedRowModel)(),...A?{getPaginationRowModel:(0,i.getPaginationRowModel)()}:{},enableSorting:!0,enableColumnResizing:!0,defaultColumn:{minSize:40,maxSize:500}});return(0,t.jsx)("div",{className:"rounded-lg custom-border relative",children:(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsx)("div",{className:"relative min-w-full",children:(0,t.jsxs)(o.Table,{className:"[&_td]:py-2 [&_th]:py-2",style:{width:w.getTotalSize(),minWidth:"100%",tableLayout:"fixed"},children:[(0,t.jsx)(r.TableHead,{children:w.getHeaderGroups().map(e=>(0,t.jsx)(c.TableRow,{children:e.headers.map(e=>(0,t.jsxs)(l.TableHeaderCell,{className:`py-1 h-8 relative ${"actions"===e.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)] w-[120px] ml-8":""} ${e.column.columnDef.meta?.className||""}`,style:{width:"actions"===e.id?120:e.getSize(),position:"actions"===e.id?"sticky":"relative",right:"actions"===e.id?0:"auto"},onClick:e.column.getCanSort()?e.column.getToggleSortingHandler():void 0,children:[(0,t.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,t.jsx)("div",{className:"flex items-center",children:e.isPlaceholder?null:(0,a.flexRender)(e.column.columnDef.header,e.getContext())}),"actions"!==e.id&&e.column.getCanSort()&&(0,t.jsx)("div",{className:"w-4",children:e.column.getIsSorted()?({asc:(0,t.jsx)(g.ChevronUpIcon,{className:"h-4 w-4 text-blue-500"}),desc:(0,t.jsx)(u.ChevronDownIcon,{className:"h-4 w-4 text-blue-500"})})[e.column.getIsSorted()]:(0,t.jsx)(d.SwitchVerticalIcon,{className:"h-4 w-4 text-gray-400"})})]}),e.column.getCanResize()&&(0,t.jsx)("div",{onMouseDown:e.getResizeHandler(),onTouchStart:e.getResizeHandler(),className:`absolute right-0 top-0 h-full w-2 cursor-col-resize select-none touch-none ${e.column.getIsResizing()?"bg-blue-500":"hover:bg-blue-200"}`})]},e.id))},e.id))}),(0,t.jsx)(s.TableBody,{children:f?(0,t.jsx)(c.TableRow,{children:(0,t.jsx)(p.TableCell,{colSpan:m.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:"🚅 Loading models..."})})})}):w.getRowModel().rows.length>0?w.getRowModel().rows.map(e=>(0,t.jsx)(c.TableRow,{onClick:()=>v?.(e.original),className:v?"cursor-pointer hover:bg-gray-50":"",children:e.getVisibleCells().map(e=>(0,t.jsx)(p.TableCell,{className:`py-0.5 overflow-hidden ${"actions"===e.column.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)] w-[120px] ml-8":""} ${e.column.columnDef.meta?.className||""}`,style:{width:"actions"===e.column.id?120:e.column.getSize(),position:"actions"===e.column.id?"sticky":"relative",right:"actions"===e.column.id?0:"auto"},children:(0,a.flexRender)(e.column.columnDef.cell,e.getContext())},e.id))},e.id)):(0,t.jsx)(c.TableRow,{children:(0,t.jsx)(p.TableCell,{colSpan:m.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:"No models found"})})})})})]})})})})}e.s(["ModelDataTable",()=>m])},326373,e=>{"use strict";var t=e.i(21539);e.s(["Dropdown",()=>t.default])},755151,e=>{"use strict";var t=e.i(247153);e.s(["DownOutlined",()=>t.default])},62478,e=>{"use strict";var t=e.i(764205);let a=async e=>{if(!e)return null;try{return await (0,t.getProxyUISettings)(e)}catch(e){return console.error("Error fetching proxy settings:",e),null}};e.s(["fetchProxySettings",0,a])},818581,(e,t,a)=>{"use strict";Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"useMergedRef",{enumerable:!0,get:function(){return n}});let i=e.r(271645);function n(e,t){let a=(0,i.useRef)(null),n=(0,i.useRef)(null);return(0,i.useCallback)(i=>{if(null===i){let e=a.current;e&&(a.current=null,e());let t=n.current;t&&(n.current=null,t())}else e&&(a.current=o(e,i)),t&&(n.current=o(t,i))},[e,t])}function o(e,t){if("function"!=typeof e)return e.current=t,()=>{e.current=null};{let a=e(t);return"function"==typeof a?a:()=>e(null)}}("function"==typeof a.default||"object"==typeof a.default&&null!==a.default)&&void 0===a.default.__esModule&&(Object.defineProperty(a.default,"__esModule",{value:!0}),Object.assign(a.default,a),t.exports=a.default)},602073,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64L128 192v384c0 212.1 171.9 384 384 384s384-171.9 384-384V192L512 64zm312 512c0 172.3-139.7 312-312 312S200 748.3 200 576V246l312-110 312 110v330z"}},{tag:"path",attrs:{d:"M378.4 475.1a35.91 35.91 0 00-50.9 0 35.91 35.91 0 000 50.9l129.4 129.4 2.1 2.1a33.98 33.98 0 0048.1 0L730.6 434a33.98 33.98 0 000-48.1l-2.8-2.8a33.98 33.98 0 00-48.1 0L483 579.7 378.4 475.1z"}}]},name:"safety",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:i}))});e.s(["SafetyOutlined",0,o],602073)},928685,e=>{"use strict";var t=e.i(38953);e.s(["SearchOutlined",()=>t.default])},44121,186515,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 000 13.8z"}}]},name:"menu-fold",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:i}))});e.s(["MenuFoldOutlined",0,o],44121);let r={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 000-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0014.4 7z"}}]},name:"menu-unfold",theme:"outlined"};var l=a.forwardRef(function(e,i){return a.createElement(n.default,(0,t.default)({},e,{ref:i,icon:r}))});e.s(["MenuUnfoldOutlined",0,l],186515)},283713,e=>{"use strict";var t=e.i(271645),a=e.i(764205),i=e.i(612256);let n="litellm_selected_worker_id";e.s(["useWorker",0,()=>{let{data:e}=(0,i.useUIConfig)(),o=e?.is_control_plane??!1,r=e?.workers??[],[l,s]=(0,t.useState)(()=>localStorage.getItem(n));(0,t.useEffect)(()=>{if(!l||0===r.length)return;let e=r.find(e=>e.worker_id===l);e&&(0,a.switchToWorkerUrl)(e.url)},[l,r]);let c=r.find(e=>e.worker_id===l)??null,p=(0,t.useCallback)(e=>{let t=r.find(t=>t.worker_id===e);t&&(s(e),localStorage.setItem(n,e),(0,a.switchToWorkerUrl)(t.url))},[r]);return{isControlPlane:o,workers:r,selectedWorkerId:l,selectedWorker:c,selectWorker:p,disconnectFromWorker:(0,t.useCallback)(()=>{s(null),localStorage.removeItem(n),(0,a.switchToWorkerUrl)(null)},[])}}])},295320,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M704 446H320c-4.4 0-8 3.6-8 8v402c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8V454c0-4.4-3.6-8-8-8zm-328 64h272v117H376V510zm272 290H376V683h272v117z"}},{tag:"path",attrs:{d:"M424 748a32 32 0 1064 0 32 32 0 10-64 0zm0-178a32 32 0 1064 0 32 32 0 10-64 0z"}},{tag:"path",attrs:{d:"M811.4 368.9C765.6 248 648.9 162 512.2 162S258.8 247.9 213 368.8C126.9 391.5 63.5 470.2 64 563.6 64.6 668 145.6 752.9 247.6 762c4.7.4 8.7-3.3 8.7-8v-60.4c0-4-3-7.4-7-7.9-27-3.4-52.5-15.2-72.1-34.5-24-23.5-37.2-55.1-37.2-88.6 0-28 9.1-54.4 26.2-76.4 16.7-21.4 40.2-36.9 66.1-43.7l37.9-10 13.9-36.7c8.6-22.8 20.6-44.2 35.7-63.5 14.9-19.2 32.6-36 52.4-50 41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.3c19.9 14 37.5 30.8 52.4 50 15.1 19.3 27.1 40.7 35.7 63.5l13.8 36.6 37.8 10c54.2 14.4 92.1 63.7 92.1 120 0 33.6-13.2 65.1-37.2 88.6-19.5 19.2-44.9 31.1-71.9 34.5-4 .5-6.9 3.9-6.9 7.9V754c0 4.7 4.1 8.4 8.8 8 101.7-9.2 182.5-94 183.2-198.2.6-93.4-62.7-172.1-148.6-194.9z"}}]},name:"cloud-server",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:i}))});e.s(["CloudServerOutlined",0,o],295320)},190272,785913,e=>{"use strict";var t,a,i=((t={}).AUDIO_SPEECH="audio_speech",t.AUDIO_TRANSCRIPTION="audio_transcription",t.IMAGE_GENERATION="image_generation",t.VIDEO_GENERATION="video_generation",t.CHAT="chat",t.RESPONSES="responses",t.IMAGE_EDITS="image_edits",t.ANTHROPIC_MESSAGES="anthropic_messages",t.EMBEDDING="embedding",t),n=((a={}).IMAGE="image",a.VIDEO="video",a.CHAT="chat",a.RESPONSES="responses",a.IMAGE_EDITS="image_edits",a.ANTHROPIC_MESSAGES="anthropic_messages",a.EMBEDDINGS="embeddings",a.SPEECH="speech",a.TRANSCRIPTION="transcription",a.A2A_AGENTS="a2a_agents",a.MCP="mcp",a.REALTIME="realtime",a.INTERACTIONS="interactions",a);let o={image_generation:"image",video_generation:"video",chat:"chat",responses:"responses",image_edits:"image_edits",anthropic_messages:"anthropic_messages",audio_speech:"speech",audio_transcription:"transcription",embedding:"embeddings"};e.s(["EndpointType",()=>n,"getEndpointType",0,e=>{if(console.log("getEndpointType:",e),Object.values(i).includes(e)){let t=o[e];return console.log("endpointType:",t),t}return"chat"}],785913),e.s(["generateCodeSnippet",0,e=>{let t,{apiKeySource:a,accessToken:i,apiKey:o,inputMessage:r,chatHistory:l,selectedTags:s,selectedVectorStores:c,selectedGuardrails:p,selectedPolicies:d,selectedMCPServers:g,mcpServers:u,mcpServerToolRestrictions:m,selectedVoice:f,endpointType:_,selectedModel:h,selectedSdk:b,proxySettings:A}=e,v="session"===a?i:o,O=window.location.origin,I=A?.LITELLM_UI_API_DOC_BASE_URL;I&&I.trim()?O=I:A?.PROXY_BASE_URL&&(O=A.PROXY_BASE_URL);let $=r||"Your prompt here",x=$.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n"),E=l.filter(e=>!e.isImage).map(({role:e,content:t})=>({role:e,content:t})),C={};s.length>0&&(C.tags=s),c.length>0&&(C.vector_stores=c),p.length>0&&(C.guardrails=p),d.length>0&&(C.policies=d);let y=h||"your-model-name",w="azure"===b?`import openai | |||
| (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,798496,e=>{"use strict";var t=e.i(843476),a=e.i(152990),i=e.i(682830),n=e.i(271645),o=e.i(269200),r=e.i(427612),l=e.i(64848),s=e.i(942232),c=e.i(496020),p=e.i(977572),d=e.i(94629),g=e.i(360820),u=e.i(871943);function m({data:e=[],columns:m,isLoading:f=!1,defaultSorting:_=[],pagination:h,onPaginationChange:b,enablePagination:A=!1,onRowClick:v}){let[O,I]=n.default.useState(_),[x]=n.default.useState("onChange"),[$,E]=n.default.useState({}),[C,y]=n.default.useState({}),w=(0,a.useReactTable)({data:e,columns:m,state:{sorting:O,columnSizing:$,columnVisibility:C,...A&&h?{pagination:h}:{}},columnResizeMode:x,onSortingChange:I,onColumnSizingChange:E,onColumnVisibilityChange:y,...A&&b?{onPaginationChange:b}:{},getCoreRowModel:(0,i.getCoreRowModel)(),getSortedRowModel:(0,i.getSortedRowModel)(),...A?{getPaginationRowModel:(0,i.getPaginationRowModel)()}:{},enableSorting:!0,enableColumnResizing:!0,defaultColumn:{minSize:40,maxSize:500}});return(0,t.jsx)("div",{className:"rounded-lg custom-border relative",children:(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsx)("div",{className:"relative min-w-full",children:(0,t.jsxs)(o.Table,{className:"[&_td]:py-2 [&_th]:py-2",style:{width:w.getTotalSize(),minWidth:"100%",tableLayout:"fixed"},children:[(0,t.jsx)(r.TableHead,{children:w.getHeaderGroups().map(e=>(0,t.jsx)(c.TableRow,{children:e.headers.map(e=>(0,t.jsxs)(l.TableHeaderCell,{className:`py-1 h-8 relative ${"actions"===e.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)] w-[120px] ml-8":""} ${e.column.columnDef.meta?.className||""}`,style:{width:"actions"===e.id?120:e.getSize(),position:"actions"===e.id?"sticky":"relative",right:"actions"===e.id?0:"auto"},onClick:e.column.getCanSort()?e.column.getToggleSortingHandler():void 0,children:[(0,t.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,t.jsx)("div",{className:"flex items-center",children:e.isPlaceholder?null:(0,a.flexRender)(e.column.columnDef.header,e.getContext())}),"actions"!==e.id&&e.column.getCanSort()&&(0,t.jsx)("div",{className:"w-4",children:e.column.getIsSorted()?({asc:(0,t.jsx)(g.ChevronUpIcon,{className:"h-4 w-4 text-blue-500"}),desc:(0,t.jsx)(u.ChevronDownIcon,{className:"h-4 w-4 text-blue-500"})})[e.column.getIsSorted()]:(0,t.jsx)(d.SwitchVerticalIcon,{className:"h-4 w-4 text-gray-400"})})]}),e.column.getCanResize()&&(0,t.jsx)("div",{onMouseDown:e.getResizeHandler(),onTouchStart:e.getResizeHandler(),className:`absolute right-0 top-0 h-full w-2 cursor-col-resize select-none touch-none ${e.column.getIsResizing()?"bg-blue-500":"hover:bg-blue-200"}`})]},e.id))},e.id))}),(0,t.jsx)(s.TableBody,{children:f?(0,t.jsx)(c.TableRow,{children:(0,t.jsx)(p.TableCell,{colSpan:m.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:"🚅 Loading models..."})})})}):w.getRowModel().rows.length>0?w.getRowModel().rows.map(e=>(0,t.jsx)(c.TableRow,{onClick:()=>v?.(e.original),className:v?"cursor-pointer hover:bg-gray-50":"",children:e.getVisibleCells().map(e=>(0,t.jsx)(p.TableCell,{className:`py-0.5 overflow-hidden ${"actions"===e.column.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)] w-[120px] ml-8":""} ${e.column.columnDef.meta?.className||""}`,style:{width:"actions"===e.column.id?120:e.column.getSize(),position:"actions"===e.column.id?"sticky":"relative",right:"actions"===e.column.id?0:"auto"},children:(0,a.flexRender)(e.column.columnDef.cell,e.getContext())},e.id))},e.id)):(0,t.jsx)(c.TableRow,{children:(0,t.jsx)(p.TableCell,{colSpan:m.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:"No models found"})})})})})]})})})})}e.s(["ModelDataTable",()=>m])},326373,e=>{"use strict";var t=e.i(21539);e.s(["Dropdown",()=>t.default])},755151,e=>{"use strict";var t=e.i(247153);e.s(["DownOutlined",()=>t.default])},62478,e=>{"use strict";var t=e.i(602869);let a=async e=>{if(!e)return null;try{return await (0,t.getProxyUISettings)(e)}catch(e){return console.error("Error fetching proxy settings:",e),null}};e.s(["fetchProxySettings",0,a])},818581,(e,t,a)=>{"use strict";Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"useMergedRef",{enumerable:!0,get:function(){return n}});let i=e.r(271645);function n(e,t){let a=(0,i.useRef)(null),n=(0,i.useRef)(null);return(0,i.useCallback)(i=>{if(null===i){let e=a.current;e&&(a.current=null,e());let t=n.current;t&&(n.current=null,t())}else e&&(a.current=o(e,i)),t&&(n.current=o(t,i))},[e,t])}function o(e,t){if("function"!=typeof e)return e.current=t,()=>{e.current=null};{let a=e(t);return"function"==typeof a?a:()=>e(null)}}("function"==typeof a.default||"object"==typeof a.default&&null!==a.default)&&void 0===a.default.__esModule&&(Object.defineProperty(a.default,"__esModule",{value:!0}),Object.assign(a.default,a),t.exports=a.default)},602073,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64L128 192v384c0 212.1 171.9 384 384 384s384-171.9 384-384V192L512 64zm312 512c0 172.3-139.7 312-312 312S200 748.3 200 576V246l312-110 312 110v330z"}},{tag:"path",attrs:{d:"M378.4 475.1a35.91 35.91 0 00-50.9 0 35.91 35.91 0 000 50.9l129.4 129.4 2.1 2.1a33.98 33.98 0 0048.1 0L730.6 434a33.98 33.98 0 000-48.1l-2.8-2.8a33.98 33.98 0 00-48.1 0L483 579.7 378.4 475.1z"}}]},name:"safety",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:i}))});e.s(["SafetyOutlined",0,o],602073)},928685,e=>{"use strict";var t=e.i(38953);e.s(["SearchOutlined",()=>t.default])},44121,186515,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 000 13.8z"}}]},name:"menu-fold",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:i}))});e.s(["MenuFoldOutlined",0,o],44121);let r={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 000-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0014.4 7z"}}]},name:"menu-unfold",theme:"outlined"};var l=a.forwardRef(function(e,i){return a.createElement(n.default,(0,t.default)({},e,{ref:i,icon:r}))});e.s(["MenuUnfoldOutlined",0,l],186515)},283713,e=>{"use strict";var t=e.i(271645),a=e.i(602869),i=e.i(612256);let n="litellm_selected_worker_id";e.s(["useWorker",0,()=>{let{data:e}=(0,i.useUIConfig)(),o=e?.is_control_plane??!1,r=e?.workers??[],[l,s]=(0,t.useState)(()=>localStorage.getItem(n));(0,t.useEffect)(()=>{if(!l||0===r.length)return;let e=r.find(e=>e.worker_id===l);e&&(0,a.switchToWorkerUrl)(e.url)},[l,r]);let c=r.find(e=>e.worker_id===l)??null,p=(0,t.useCallback)(e=>{let t=r.find(t=>t.worker_id===e);t&&(s(e),localStorage.setItem(n,e),(0,a.switchToWorkerUrl)(t.url))},[r]);return{isControlPlane:o,workers:r,selectedWorkerId:l,selectedWorker:c,selectWorker:p,disconnectFromWorker:(0,t.useCallback)(()=>{s(null),localStorage.removeItem(n),(0,a.switchToWorkerUrl)(null)},[])}}])},295320,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M704 446H320c-4.4 0-8 3.6-8 8v402c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8V454c0-4.4-3.6-8-8-8zm-328 64h272v117H376V510zm272 290H376V683h272v117z"}},{tag:"path",attrs:{d:"M424 748a32 32 0 1064 0 32 32 0 10-64 0zm0-178a32 32 0 1064 0 32 32 0 10-64 0z"}},{tag:"path",attrs:{d:"M811.4 368.9C765.6 248 648.9 162 512.2 162S258.8 247.9 213 368.8C126.9 391.5 63.5 470.2 64 563.6 64.6 668 145.6 752.9 247.6 762c4.7.4 8.7-3.3 8.7-8v-60.4c0-4-3-7.4-7-7.9-27-3.4-52.5-15.2-72.1-34.5-24-23.5-37.2-55.1-37.2-88.6 0-28 9.1-54.4 26.2-76.4 16.7-21.4 40.2-36.9 66.1-43.7l37.9-10 13.9-36.7c8.6-22.8 20.6-44.2 35.7-63.5 14.9-19.2 32.6-36 52.4-50 41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.3c19.9 14 37.5 30.8 52.4 50 15.1 19.3 27.1 40.7 35.7 63.5l13.8 36.6 37.8 10c54.2 14.4 92.1 63.7 92.1 120 0 33.6-13.2 65.1-37.2 88.6-19.5 19.2-44.9 31.1-71.9 34.5-4 .5-6.9 3.9-6.9 7.9V754c0 4.7 4.1 8.4 8.8 8 101.7-9.2 182.5-94 183.2-198.2.6-93.4-62.7-172.1-148.6-194.9z"}}]},name:"cloud-server",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:i}))});e.s(["CloudServerOutlined",0,o],295320)},190272,785913,e=>{"use strict";var t,a,i=((t={}).AUDIO_SPEECH="audio_speech",t.AUDIO_TRANSCRIPTION="audio_transcription",t.IMAGE_GENERATION="image_generation",t.VIDEO_GENERATION="video_generation",t.CHAT="chat",t.RESPONSES="responses",t.IMAGE_EDITS="image_edits",t.ANTHROPIC_MESSAGES="anthropic_messages",t.EMBEDDING="embedding",t),n=((a={}).IMAGE="image",a.VIDEO="video",a.CHAT="chat",a.RESPONSES="responses",a.IMAGE_EDITS="image_edits",a.ANTHROPIC_MESSAGES="anthropic_messages",a.EMBEDDINGS="embeddings",a.SPEECH="speech",a.TRANSCRIPTION="transcription",a.A2A_AGENTS="a2a_agents",a.MCP="mcp",a.REALTIME="realtime",a.INTERACTIONS="interactions",a);let o={image_generation:"image",video_generation:"video",chat:"chat",responses:"responses",image_edits:"image_edits",anthropic_messages:"anthropic_messages",audio_speech:"speech",audio_transcription:"transcription",embedding:"embeddings"};e.s(["EndpointType",()=>n,"getEndpointType",0,e=>{if(console.log("getEndpointType:",e),Object.values(i).includes(e)){let t=o[e];return console.log("endpointType:",t),t}return"chat"}],785913),e.s(["generateCodeSnippet",0,e=>{let t,{apiKeySource:a,accessToken:i,apiKey:o,inputMessage:r,chatHistory:l,selectedTags:s,selectedVectorStores:c,selectedGuardrails:p,selectedPolicies:d,selectedMCPServers:g,mcpServers:u,mcpServerToolRestrictions:m,selectedVoice:f,endpointType:_,selectedModel:h,selectedSdk:b,proxySettings:A}=e,v="session"===a?i:o,O=window.location.origin,I=A?.LITELLM_UI_API_DOC_BASE_URL;I&&I.trim()?O=I:A?.PROXY_BASE_URL&&(O=A.PROXY_BASE_URL);let x=r||"Your prompt here",$=x.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n"),E=l.filter(e=>!e.isImage).map(({role:e,content:t})=>({role:e,content:t})),C={};s.length>0&&(C.tags=s),c.length>0&&(C.vector_stores=c),p.length>0&&(C.guardrails=p),d.length>0&&(C.policies=d);let y=h||"your-model-name",w="azure"===b?`import openai | |||
| @@ -1,4 +1,4 @@ | |||
| (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,798496,e=>{"use strict";var t=e.i(843476),a=e.i(152990),i=e.i(682830),n=e.i(271645),o=e.i(269200),r=e.i(427612),l=e.i(64848),s=e.i(942232),c=e.i(496020),p=e.i(977572),d=e.i(94629),g=e.i(360820),u=e.i(871943);function m({data:e=[],columns:m,isLoading:f=!1,defaultSorting:_=[],pagination:h,onPaginationChange:b,enablePagination:A=!1,onRowClick:v}){let[O,I]=n.default.useState(_),[$]=n.default.useState("onChange"),[x,E]=n.default.useState({}),[C,y]=n.default.useState({}),w=(0,a.useReactTable)({data:e,columns:m,state:{sorting:O,columnSizing:x,columnVisibility:C,...A&&h?{pagination:h}:{}},columnResizeMode:$,onSortingChange:I,onColumnSizingChange:E,onColumnVisibilityChange:y,...A&&b?{onPaginationChange:b}:{},getCoreRowModel:(0,i.getCoreRowModel)(),getSortedRowModel:(0,i.getSortedRowModel)(),...A?{getPaginationRowModel:(0,i.getPaginationRowModel)()}:{},enableSorting:!0,enableColumnResizing:!0,defaultColumn:{minSize:40,maxSize:500}});return(0,t.jsx)("div",{className:"rounded-lg custom-border relative",children:(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsx)("div",{className:"relative min-w-full",children:(0,t.jsxs)(o.Table,{className:"[&_td]:py-2 [&_th]:py-2",style:{width:w.getTotalSize(),minWidth:"100%",tableLayout:"fixed"},children:[(0,t.jsx)(r.TableHead,{children:w.getHeaderGroups().map(e=>(0,t.jsx)(c.TableRow,{children:e.headers.map(e=>(0,t.jsxs)(l.TableHeaderCell,{className:`py-1 h-8 relative ${"actions"===e.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)] w-[120px] ml-8":""} ${e.column.columnDef.meta?.className||""}`,style:{width:"actions"===e.id?120:e.getSize(),position:"actions"===e.id?"sticky":"relative",right:"actions"===e.id?0:"auto"},onClick:e.column.getCanSort()?e.column.getToggleSortingHandler():void 0,children:[(0,t.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,t.jsx)("div",{className:"flex items-center",children:e.isPlaceholder?null:(0,a.flexRender)(e.column.columnDef.header,e.getContext())}),"actions"!==e.id&&e.column.getCanSort()&&(0,t.jsx)("div",{className:"w-4",children:e.column.getIsSorted()?({asc:(0,t.jsx)(g.ChevronUpIcon,{className:"h-4 w-4 text-blue-500"}),desc:(0,t.jsx)(u.ChevronDownIcon,{className:"h-4 w-4 text-blue-500"})})[e.column.getIsSorted()]:(0,t.jsx)(d.SwitchVerticalIcon,{className:"h-4 w-4 text-gray-400"})})]}),e.column.getCanResize()&&(0,t.jsx)("div",{onMouseDown:e.getResizeHandler(),onTouchStart:e.getResizeHandler(),className:`absolute right-0 top-0 h-full w-2 cursor-col-resize select-none touch-none ${e.column.getIsResizing()?"bg-blue-500":"hover:bg-blue-200"}`})]},e.id))},e.id))}),(0,t.jsx)(s.TableBody,{children:f?(0,t.jsx)(c.TableRow,{children:(0,t.jsx)(p.TableCell,{colSpan:m.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:"🚅 Loading models..."})})})}):w.getRowModel().rows.length>0?w.getRowModel().rows.map(e=>(0,t.jsx)(c.TableRow,{onClick:()=>v?.(e.original),className:v?"cursor-pointer hover:bg-gray-50":"",children:e.getVisibleCells().map(e=>(0,t.jsx)(p.TableCell,{className:`py-0.5 overflow-hidden ${"actions"===e.column.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)] w-[120px] ml-8":""} ${e.column.columnDef.meta?.className||""}`,style:{width:"actions"===e.column.id?120:e.column.getSize(),position:"actions"===e.column.id?"sticky":"relative",right:"actions"===e.column.id?0:"auto"},children:(0,a.flexRender)(e.column.columnDef.cell,e.getContext())},e.id))},e.id)):(0,t.jsx)(c.TableRow,{children:(0,t.jsx)(p.TableCell,{colSpan:m.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:"No models found"})})})})})]})})})})}e.s(["ModelDataTable",()=>m])},326373,e=>{"use strict";var t=e.i(21539);e.s(["Dropdown",()=>t.default])},755151,e=>{"use strict";var t=e.i(247153);e.s(["DownOutlined",()=>t.default])},62478,e=>{"use strict";var t=e.i(764205);let a=async e=>{if(!e)return null;try{return await (0,t.getProxyUISettings)(e)}catch(e){return console.error("Error fetching proxy settings:",e),null}};e.s(["fetchProxySettings",0,a])},818581,(e,t,a)=>{"use strict";Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"useMergedRef",{enumerable:!0,get:function(){return n}});let i=e.r(271645);function n(e,t){let a=(0,i.useRef)(null),n=(0,i.useRef)(null);return(0,i.useCallback)(i=>{if(null===i){let e=a.current;e&&(a.current=null,e());let t=n.current;t&&(n.current=null,t())}else e&&(a.current=o(e,i)),t&&(n.current=o(t,i))},[e,t])}function o(e,t){if("function"!=typeof e)return e.current=t,()=>{e.current=null};{let a=e(t);return"function"==typeof a?a:()=>e(null)}}("function"==typeof a.default||"object"==typeof a.default&&null!==a.default)&&void 0===a.default.__esModule&&(Object.defineProperty(a.default,"__esModule",{value:!0}),Object.assign(a.default,a),t.exports=a.default)},602073,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64L128 192v384c0 212.1 171.9 384 384 384s384-171.9 384-384V192L512 64zm312 512c0 172.3-139.7 312-312 312S200 748.3 200 576V246l312-110 312 110v330z"}},{tag:"path",attrs:{d:"M378.4 475.1a35.91 35.91 0 00-50.9 0 35.91 35.91 0 000 50.9l129.4 129.4 2.1 2.1a33.98 33.98 0 0048.1 0L730.6 434a33.98 33.98 0 000-48.1l-2.8-2.8a33.98 33.98 0 00-48.1 0L483 579.7 378.4 475.1z"}}]},name:"safety",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:i}))});e.s(["SafetyOutlined",0,o],602073)},928685,e=>{"use strict";var t=e.i(38953);e.s(["SearchOutlined",()=>t.default])},44121,186515,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 000 13.8z"}}]},name:"menu-fold",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:i}))});e.s(["MenuFoldOutlined",0,o],44121);let r={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 000-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0014.4 7z"}}]},name:"menu-unfold",theme:"outlined"};var l=a.forwardRef(function(e,i){return a.createElement(n.default,(0,t.default)({},e,{ref:i,icon:r}))});e.s(["MenuUnfoldOutlined",0,l],186515)},283713,e=>{"use strict";var t=e.i(271645),a=e.i(764205),i=e.i(612256);let n="litellm_selected_worker_id";e.s(["useWorker",0,()=>{let{data:e}=(0,i.useUIConfig)(),o=e?.is_control_plane??!1,r=e?.workers??[],[l,s]=(0,t.useState)(()=>localStorage.getItem(n));(0,t.useEffect)(()=>{if(!l||0===r.length)return;let e=r.find(e=>e.worker_id===l);e&&(0,a.switchToWorkerUrl)(e.url)},[l,r]);let c=r.find(e=>e.worker_id===l)??null,p=(0,t.useCallback)(e=>{let t=r.find(t=>t.worker_id===e);t&&(s(e),localStorage.setItem(n,e),(0,a.switchToWorkerUrl)(t.url))},[r]);return{isControlPlane:o,workers:r,selectedWorkerId:l,selectedWorker:c,selectWorker:p,disconnectFromWorker:(0,t.useCallback)(()=>{s(null),localStorage.removeItem(n),(0,a.switchToWorkerUrl)(null)},[])}}])},295320,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M704 446H320c-4.4 0-8 3.6-8 8v402c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8V454c0-4.4-3.6-8-8-8zm-328 64h272v117H376V510zm272 290H376V683h272v117z"}},{tag:"path",attrs:{d:"M424 748a32 32 0 1064 0 32 32 0 10-64 0zm0-178a32 32 0 1064 0 32 32 0 10-64 0z"}},{tag:"path",attrs:{d:"M811.4 368.9C765.6 248 648.9 162 512.2 162S258.8 247.9 213 368.8C126.9 391.5 63.5 470.2 64 563.6 64.6 668 145.6 752.9 247.6 762c4.7.4 8.7-3.3 8.7-8v-60.4c0-4-3-7.4-7-7.9-27-3.4-52.5-15.2-72.1-34.5-24-23.5-37.2-55.1-37.2-88.6 0-28 9.1-54.4 26.2-76.4 16.7-21.4 40.2-36.9 66.1-43.7l37.9-10 13.9-36.7c8.6-22.8 20.6-44.2 35.7-63.5 14.9-19.2 32.6-36 52.4-50 41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.3c19.9 14 37.5 30.8 52.4 50 15.1 19.3 27.1 40.7 35.7 63.5l13.8 36.6 37.8 10c54.2 14.4 92.1 63.7 92.1 120 0 33.6-13.2 65.1-37.2 88.6-19.5 19.2-44.9 31.1-71.9 34.5-4 .5-6.9 3.9-6.9 7.9V754c0 4.7 4.1 8.4 8.8 8 101.7-9.2 182.5-94 183.2-198.2.6-93.4-62.7-172.1-148.6-194.9z"}}]},name:"cloud-server",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:i}))});e.s(["CloudServerOutlined",0,o],295320)},190272,785913,e=>{"use strict";var t,a,i=((t={}).AUDIO_SPEECH="audio_speech",t.AUDIO_TRANSCRIPTION="audio_transcription",t.IMAGE_GENERATION="image_generation",t.VIDEO_GENERATION="video_generation",t.CHAT="chat",t.RESPONSES="responses",t.IMAGE_EDITS="image_edits",t.ANTHROPIC_MESSAGES="anthropic_messages",t.EMBEDDING="embedding",t),n=((a={}).IMAGE="image",a.VIDEO="video",a.CHAT="chat",a.RESPONSES="responses",a.IMAGE_EDITS="image_edits",a.ANTHROPIC_MESSAGES="anthropic_messages",a.EMBEDDINGS="embeddings",a.SPEECH="speech",a.TRANSCRIPTION="transcription",a.A2A_AGENTS="a2a_agents",a.MCP="mcp",a.REALTIME="realtime",a.INTERACTIONS="interactions",a);let o={image_generation:"image",video_generation:"video",chat:"chat",responses:"responses",image_edits:"image_edits",anthropic_messages:"anthropic_messages",audio_speech:"speech",audio_transcription:"transcription",embedding:"embeddings"};e.s(["EndpointType",()=>n,"getEndpointType",0,e=>{if(console.log("getEndpointType:",e),Object.values(i).includes(e)){let t=o[e];return console.log("endpointType:",t),t}return"chat"}],785913),e.s(["generateCodeSnippet",0,e=>{let t,{apiKeySource:a,accessToken:i,apiKey:o,inputMessage:r,chatHistory:l,selectedTags:s,selectedVectorStores:c,selectedGuardrails:p,selectedPolicies:d,selectedMCPServers:g,mcpServers:u,mcpServerToolRestrictions:m,selectedVoice:f,endpointType:_,selectedModel:h,selectedSdk:b,proxySettings:A}=e,v="session"===a?i:o,O=window.location.origin,I=A?.LITELLM_UI_API_DOC_BASE_URL;I&&I.trim()?O=I:A?.PROXY_BASE_URL&&(O=A.PROXY_BASE_URL);let $=r||"Your prompt here",x=$.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n"),E=l.filter(e=>!e.isImage).map(({role:e,content:t})=>({role:e,content:t})),C={};s.length>0&&(C.tags=s),c.length>0&&(C.vector_stores=c),p.length>0&&(C.guardrails=p),d.length>0&&(C.policies=d);let y=h||"your-model-name",w="azure"===b?`import openai | |||
| (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,798496,e=>{"use strict";var t=e.i(843476),a=e.i(152990),i=e.i(682830),n=e.i(271645),o=e.i(269200),r=e.i(427612),l=e.i(64848),s=e.i(942232),c=e.i(496020),p=e.i(977572),d=e.i(94629),g=e.i(360820),u=e.i(871943);function m({data:e=[],columns:m,isLoading:f=!1,defaultSorting:_=[],pagination:h,onPaginationChange:b,enablePagination:A=!1,onRowClick:v}){let[O,I]=n.default.useState(_),[x]=n.default.useState("onChange"),[$,E]=n.default.useState({}),[C,y]=n.default.useState({}),w=(0,a.useReactTable)({data:e,columns:m,state:{sorting:O,columnSizing:$,columnVisibility:C,...A&&h?{pagination:h}:{}},columnResizeMode:x,onSortingChange:I,onColumnSizingChange:E,onColumnVisibilityChange:y,...A&&b?{onPaginationChange:b}:{},getCoreRowModel:(0,i.getCoreRowModel)(),getSortedRowModel:(0,i.getSortedRowModel)(),...A?{getPaginationRowModel:(0,i.getPaginationRowModel)()}:{},enableSorting:!0,enableColumnResizing:!0,defaultColumn:{minSize:40,maxSize:500}});return(0,t.jsx)("div",{className:"rounded-lg custom-border relative",children:(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsx)("div",{className:"relative min-w-full",children:(0,t.jsxs)(o.Table,{className:"[&_td]:py-2 [&_th]:py-2",style:{width:w.getTotalSize(),minWidth:"100%",tableLayout:"fixed"},children:[(0,t.jsx)(r.TableHead,{children:w.getHeaderGroups().map(e=>(0,t.jsx)(c.TableRow,{children:e.headers.map(e=>(0,t.jsxs)(l.TableHeaderCell,{className:`py-1 h-8 relative ${"actions"===e.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)] w-[120px] ml-8":""} ${e.column.columnDef.meta?.className||""}`,style:{width:"actions"===e.id?120:e.getSize(),position:"actions"===e.id?"sticky":"relative",right:"actions"===e.id?0:"auto"},onClick:e.column.getCanSort()?e.column.getToggleSortingHandler():void 0,children:[(0,t.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,t.jsx)("div",{className:"flex items-center",children:e.isPlaceholder?null:(0,a.flexRender)(e.column.columnDef.header,e.getContext())}),"actions"!==e.id&&e.column.getCanSort()&&(0,t.jsx)("div",{className:"w-4",children:e.column.getIsSorted()?({asc:(0,t.jsx)(g.ChevronUpIcon,{className:"h-4 w-4 text-blue-500"}),desc:(0,t.jsx)(u.ChevronDownIcon,{className:"h-4 w-4 text-blue-500"})})[e.column.getIsSorted()]:(0,t.jsx)(d.SwitchVerticalIcon,{className:"h-4 w-4 text-gray-400"})})]}),e.column.getCanResize()&&(0,t.jsx)("div",{onMouseDown:e.getResizeHandler(),onTouchStart:e.getResizeHandler(),className:`absolute right-0 top-0 h-full w-2 cursor-col-resize select-none touch-none ${e.column.getIsResizing()?"bg-blue-500":"hover:bg-blue-200"}`})]},e.id))},e.id))}),(0,t.jsx)(s.TableBody,{children:f?(0,t.jsx)(c.TableRow,{children:(0,t.jsx)(p.TableCell,{colSpan:m.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:"🚅 Loading models..."})})})}):w.getRowModel().rows.length>0?w.getRowModel().rows.map(e=>(0,t.jsx)(c.TableRow,{onClick:()=>v?.(e.original),className:v?"cursor-pointer hover:bg-gray-50":"",children:e.getVisibleCells().map(e=>(0,t.jsx)(p.TableCell,{className:`py-0.5 overflow-hidden ${"actions"===e.column.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)] w-[120px] ml-8":""} ${e.column.columnDef.meta?.className||""}`,style:{width:"actions"===e.column.id?120:e.column.getSize(),position:"actions"===e.column.id?"sticky":"relative",right:"actions"===e.column.id?0:"auto"},children:(0,a.flexRender)(e.column.columnDef.cell,e.getContext())},e.id))},e.id)):(0,t.jsx)(c.TableRow,{children:(0,t.jsx)(p.TableCell,{colSpan:m.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:"No models found"})})})})})]})})})})}e.s(["ModelDataTable",()=>m])},326373,e=>{"use strict";var t=e.i(21539);e.s(["Dropdown",()=>t.default])},755151,e=>{"use strict";var t=e.i(247153);e.s(["DownOutlined",()=>t.default])},62478,e=>{"use strict";var t=e.i(602869);let a=async e=>{if(!e)return null;try{return await (0,t.getProxyUISettings)(e)}catch(e){return console.error("Error fetching proxy settings:",e),null}};e.s(["fetchProxySettings",0,a])},818581,(e,t,a)=>{"use strict";Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"useMergedRef",{enumerable:!0,get:function(){return n}});let i=e.r(271645);function n(e,t){let a=(0,i.useRef)(null),n=(0,i.useRef)(null);return(0,i.useCallback)(i=>{if(null===i){let e=a.current;e&&(a.current=null,e());let t=n.current;t&&(n.current=null,t())}else e&&(a.current=o(e,i)),t&&(n.current=o(t,i))},[e,t])}function o(e,t){if("function"!=typeof e)return e.current=t,()=>{e.current=null};{let a=e(t);return"function"==typeof a?a:()=>e(null)}}("function"==typeof a.default||"object"==typeof a.default&&null!==a.default)&&void 0===a.default.__esModule&&(Object.defineProperty(a.default,"__esModule",{value:!0}),Object.assign(a.default,a),t.exports=a.default)},602073,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64L128 192v384c0 212.1 171.9 384 384 384s384-171.9 384-384V192L512 64zm312 512c0 172.3-139.7 312-312 312S200 748.3 200 576V246l312-110 312 110v330z"}},{tag:"path",attrs:{d:"M378.4 475.1a35.91 35.91 0 00-50.9 0 35.91 35.91 0 000 50.9l129.4 129.4 2.1 2.1a33.98 33.98 0 0048.1 0L730.6 434a33.98 33.98 0 000-48.1l-2.8-2.8a33.98 33.98 0 00-48.1 0L483 579.7 378.4 475.1z"}}]},name:"safety",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:i}))});e.s(["SafetyOutlined",0,o],602073)},928685,e=>{"use strict";var t=e.i(38953);e.s(["SearchOutlined",()=>t.default])},44121,186515,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 000 13.8z"}}]},name:"menu-fold",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:i}))});e.s(["MenuFoldOutlined",0,o],44121);let r={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 000-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0014.4 7z"}}]},name:"menu-unfold",theme:"outlined"};var l=a.forwardRef(function(e,i){return a.createElement(n.default,(0,t.default)({},e,{ref:i,icon:r}))});e.s(["MenuUnfoldOutlined",0,l],186515)},283713,e=>{"use strict";var t=e.i(271645),a=e.i(602869),i=e.i(612256);let n="litellm_selected_worker_id";e.s(["useWorker",0,()=>{let{data:e}=(0,i.useUIConfig)(),o=e?.is_control_plane??!1,r=e?.workers??[],[l,s]=(0,t.useState)(()=>localStorage.getItem(n));(0,t.useEffect)(()=>{if(!l||0===r.length)return;let e=r.find(e=>e.worker_id===l);e&&(0,a.switchToWorkerUrl)(e.url)},[l,r]);let c=r.find(e=>e.worker_id===l)??null,p=(0,t.useCallback)(e=>{let t=r.find(t=>t.worker_id===e);t&&(s(e),localStorage.setItem(n,e),(0,a.switchToWorkerUrl)(t.url))},[r]);return{isControlPlane:o,workers:r,selectedWorkerId:l,selectedWorker:c,selectWorker:p,disconnectFromWorker:(0,t.useCallback)(()=>{s(null),localStorage.removeItem(n),(0,a.switchToWorkerUrl)(null)},[])}}])},295320,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M704 446H320c-4.4 0-8 3.6-8 8v402c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8V454c0-4.4-3.6-8-8-8zm-328 64h272v117H376V510zm272 290H376V683h272v117z"}},{tag:"path",attrs:{d:"M424 748a32 32 0 1064 0 32 32 0 10-64 0zm0-178a32 32 0 1064 0 32 32 0 10-64 0z"}},{tag:"path",attrs:{d:"M811.4 368.9C765.6 248 648.9 162 512.2 162S258.8 247.9 213 368.8C126.9 391.5 63.5 470.2 64 563.6 64.6 668 145.6 752.9 247.6 762c4.7.4 8.7-3.3 8.7-8v-60.4c0-4-3-7.4-7-7.9-27-3.4-52.5-15.2-72.1-34.5-24-23.5-37.2-55.1-37.2-88.6 0-28 9.1-54.4 26.2-76.4 16.7-21.4 40.2-36.9 66.1-43.7l37.9-10 13.9-36.7c8.6-22.8 20.6-44.2 35.7-63.5 14.9-19.2 32.6-36 52.4-50 41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.3c19.9 14 37.5 30.8 52.4 50 15.1 19.3 27.1 40.7 35.7 63.5l13.8 36.6 37.8 10c54.2 14.4 92.1 63.7 92.1 120 0 33.6-13.2 65.1-37.2 88.6-19.5 19.2-44.9 31.1-71.9 34.5-4 .5-6.9 3.9-6.9 7.9V754c0 4.7 4.1 8.4 8.8 8 101.7-9.2 182.5-94 183.2-198.2.6-93.4-62.7-172.1-148.6-194.9z"}}]},name:"cloud-server",theme:"outlined"};var n=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(n.default,(0,t.default)({},e,{ref:o,icon:i}))});e.s(["CloudServerOutlined",0,o],295320)},190272,785913,e=>{"use strict";var t,a,i=((t={}).AUDIO_SPEECH="audio_speech",t.AUDIO_TRANSCRIPTION="audio_transcription",t.IMAGE_GENERATION="image_generation",t.VIDEO_GENERATION="video_generation",t.CHAT="chat",t.RESPONSES="responses",t.IMAGE_EDITS="image_edits",t.ANTHROPIC_MESSAGES="anthropic_messages",t.EMBEDDING="embedding",t),n=((a={}).IMAGE="image",a.VIDEO="video",a.CHAT="chat",a.RESPONSES="responses",a.IMAGE_EDITS="image_edits",a.ANTHROPIC_MESSAGES="anthropic_messages",a.EMBEDDINGS="embeddings",a.SPEECH="speech",a.TRANSCRIPTION="transcription",a.A2A_AGENTS="a2a_agents",a.MCP="mcp",a.REALTIME="realtime",a.INTERACTIONS="interactions",a);let o={image_generation:"image",video_generation:"video",chat:"chat",responses:"responses",image_edits:"image_edits",anthropic_messages:"anthropic_messages",audio_speech:"speech",audio_transcription:"transcription",embedding:"embeddings"};e.s(["EndpointType",()=>n,"getEndpointType",0,e=>{if(console.log("getEndpointType:",e),Object.values(i).includes(e)){let t=o[e];return console.log("endpointType:",t),t}return"chat"}],785913),e.s(["generateCodeSnippet",0,e=>{let t,{apiKeySource:a,accessToken:i,apiKey:o,inputMessage:r,chatHistory:l,selectedTags:s,selectedVectorStores:c,selectedGuardrails:p,selectedPolicies:d,selectedMCPServers:g,mcpServers:u,mcpServerToolRestrictions:m,selectedVoice:f,endpointType:_,selectedModel:h,selectedSdk:b,proxySettings:A}=e,v="session"===a?i:o,O=window.location.origin,I=A?.LITELLM_UI_API_DOC_BASE_URL;I&&I.trim()?O=I:A?.PROXY_BASE_URL&&(O=A.PROXY_BASE_URL);let x=r||"Your prompt here",$=x.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n"),E=l.filter(e=>!e.isImage).map(({role:e,content:t})=>({role:e,content:t})),C={};s.length>0&&(C.tags=s),c.length>0&&(C.vector_stores=c),p.length>0&&(C.guardrails=p),d.length>0&&(C.policies=d);let y=h||"your-model-name",w="azure"===b?`import openai | |||
| ${i}, | ||
| ${r} > li, | ||
| ${a}, | ||
| ${n}, | ||
| ${o}, | ||
| ${l} | ||
| `]:Object.assign({},{background:e.skeletonLoadingBackground,backgroundSize:"400% 100%",animationName:c,animationDuration:e.skeletonLoadingMotionDuration,animationTimingFunction:"ease",animationIterationCount:"infinite"})}}})((0,p.mergeToken)(e,{skeletonAvatarCls:`${t}-avatar`,skeletonTitleCls:`${t}-title`,skeletonParagraphCls:`${t}-paragraph`,skeletonButtonCls:`${t}-button`,skeletonInputCls:`${t}-input`,skeletonImageCls:`${t}-image`,imageSizeBase:a(e.controlHeight).mul(1.5).equal(),borderRadius:100,skeletonLoadingBackground:`linear-gradient(90deg, ${e.gradientFromColor} 25%, ${e.gradientToColor} 37%, ${e.gradientFromColor} 63%)`,skeletonLoadingMotionDuration:"1.4s"}))},e=>{let{colorFillContent:t,colorFill:a}=e;return{color:t,colorGradientEnd:a,gradientFromColor:t,gradientToColor:a,titleHeight:e.controlHeight/2,blockRadius:e.borderRadiusSM,paragraphMarginTop:e.marginLG+e.marginXXS,paragraphLiHeight:e.controlHeight/2}},{deprecatedTokens:[["color","gradientFromColor"],["colorGradientEnd","gradientToColor"]]}),b=e=>{let{prefixCls:i,className:r,style:n,rows:o=0}=e,l=Array.from({length:o}).map((a,i)=>t.createElement("li",{key:i,style:{width:((e,t)=>{let{width:a,rows:i=2}=t;return Array.isArray(a)?a[e]:i-1===e?a:void 0})(i,e)}}));return t.createElement("ul",{className:(0,a.default)(i,r),style:n},l)},A=({prefixCls:e,className:i,width:r,style:n})=>t.createElement("h3",{className:(0,a.default)(e,i),style:Object.assign({width:r},n)});function v(e){return e&&"object"==typeof e?e:{}}let O=e=>{let{prefixCls:r,loading:o,className:l,rootClassName:s,style:p,children:c,avatar:g=!1,title:u=!0,paragraph:d=!0,active:m,round:f}=e,{getPrefixCls:_,direction:O,className:I,style:$}=(0,i.useComponentConfig)("skeleton"),E=_("skeleton",r),[C,y,x]=h(E);if(o||!("loading"in e)){let e,i,r=!!g,o=!!u,c=!!d;if(r){let a=Object.assign(Object.assign({prefixCls:`${E}-avatar`},o&&!c?{size:"large",shape:"square"}:{size:"large",shape:"circle"}),v(g));e=t.createElement("div",{className:`${E}-header`},t.createElement(n,Object.assign({},a)))}if(o||c){let e,a;if(o){let a=Object.assign(Object.assign({prefixCls:`${E}-title`},!r&&c?{width:"38%"}:r&&c?{width:"50%"}:{}),v(u));e=t.createElement(A,Object.assign({},a))}if(c){let e,i=Object.assign(Object.assign({prefixCls:`${E}-paragraph`},(e={},r&&o||(e.width="61%"),!r&&o?e.rows=3:e.rows=2,e)),v(d));a=t.createElement(b,Object.assign({},i))}i=t.createElement("div",{className:`${E}-content`},e,a)}let _=(0,a.default)(E,{[`${E}-with-avatar`]:r,[`${E}-active`]:m,[`${E}-rtl`]:"rtl"===O,[`${E}-round`]:f},I,l,s,y,x);return C(t.createElement("div",{className:_,style:Object.assign(Object.assign({},$),p)},e,i))}return null!=c?c:null};O.Button=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,block:c=!1,size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p,[`${d}-block`]:c},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-button`,size:g},b))))},O.Avatar=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,shape:c="circle",size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls","className"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-avatar`,shape:c,size:g},b))))},O.Input=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,block:c,size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p,[`${d}-block`]:c},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-input`,size:g},b))))},O.Image=e=>{let{prefixCls:r,className:n,rootClassName:o,style:l,active:s}=e,{getPrefixCls:p}=t.useContext(i.ConfigContext),c=p("skeleton",r),[g,u,d]=h(c),m=(0,a.default)(c,`${c}-element`,{[`${c}-active`]:s},n,o,u,d);return g(t.createElement("div",{className:m},t.createElement("div",{className:(0,a.default)(`${c}-image`,n),style:l},t.createElement("svg",{viewBox:"0 0 1098 1024",xmlns:"http://www.w3.org/2000/svg",className:`${c}-image-svg`},t.createElement("title",null,"Image placeholder"),t.createElement("path",{d:"M365.714286 329.142857q0 45.714286-32.036571 77.677714t-77.677714 32.036571-77.677714-32.036571-32.036571-77.677714 32.036571-77.677714 77.677714-32.036571 77.677714 32.036571 32.036571 77.677714zM950.857143 548.571429l0 256-804.571429 0 0-109.714286 182.857143-182.857143 91.428571 91.428571 292.571429-292.571429zM1005.714286 146.285714l-914.285714 0q-7.460571 0-12.873143 5.412571t-5.412571 12.873143l0 694.857143q0 7.460571 5.412571 12.873143t12.873143 5.412571l914.285714 0q7.460571 0 12.873143-5.412571t5.412571-12.873143l0-694.857143q0-7.460571-5.412571-12.873143t-12.873143-5.412571zM1097.142857 164.571429l0 694.857143q0 37.741714-26.843429 64.585143t-64.585143 26.843429l-914.285714 0q-37.741714 0-64.585143-26.843429t-26.843429-64.585143l0-694.857143q0-37.741714 26.843429-64.585143t64.585143-26.843429l914.285714 0q37.741714 0 64.585143 26.843429t26.843429 64.585143z",className:`${c}-image-path`})))))},O.Node=e=>{let{prefixCls:r,className:n,rootClassName:o,style:l,active:s,children:p}=e,{getPrefixCls:c}=t.useContext(i.ConfigContext),g=c("skeleton",r),[u,d,m]=h(g),f=(0,a.default)(g,`${g}-element`,{[`${g}-active`]:s},d,n,o,m);return u(t.createElement("div",{className:f},t.createElement("div",{className:(0,a.default)(`${g}-image`,n),style:l},p)))},e.s(["default",0,O],185793)},959013,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"}},{tag:"path",attrs:{d:"M192 474h672q8 0 8 8v60q0 8-8 8H160q-8 0-8-8v-60q0-8 8-8z"}}]},name:"plus",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["default",0,n],959013)},282786,836938,310730,829672,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),i=e.i(914949),r=e.i(404948);let n=e=>e?"function"==typeof e?e():e:null;e.s(["getRenderPropValue",0,n],836938);var o=e.i(613541),l=e.i(763731),s=e.i(242064),p=e.i(491816);e.i(793154);var c=e.i(880476),g=e.i(183293),u=e.i(717356),d=e.i(320560),m=e.i(307358),f=e.i(246422),_=e.i(838378),h=e.i(617933);let b=(0,f.genStyleHooks)("Popover",e=>{let{colorBgElevated:t,colorText:a}=e,i=(0,_.mergeToken)(e,{popoverBg:t,popoverColor:a});return[(e=>{let{componentCls:t,popoverColor:a,titleMinWidth:i,fontWeightStrong:r,innerPadding:n,boxShadowSecondary:o,colorTextHeading:l,borderRadiusLG:s,zIndexPopup:p,titleMarginBottom:c,colorBgElevated:u,popoverBg:m,titleBorderBottom:f,innerContentPadding:_,titlePadding:h}=e;return[{[t]:Object.assign(Object.assign({},(0,g.resetComponent)(e)),{position:"absolute",top:0,left:{_skip_check_:!0,value:0},zIndex:p,fontWeight:"normal",whiteSpace:"normal",textAlign:"start",cursor:"auto",userSelect:"text","--valid-offset-x":"var(--arrow-offset-horizontal, var(--arrow-x))",transformOrigin:"var(--valid-offset-x, 50%) var(--arrow-y, 50%)","--antd-arrow-background-color":u,width:"max-content",maxWidth:"100vw","&-rtl":{direction:"rtl"},"&-hidden":{display:"none"},[`${t}-content`]:{position:"relative"},[`${t}-inner`]:{backgroundColor:m,backgroundClip:"padding-box",borderRadius:s,boxShadow:o,padding:n},[`${t}-title`]:{minWidth:i,marginBottom:c,color:l,fontWeight:r,borderBottom:f,padding:h},[`${t}-inner-content`]:{color:a,padding:_}})},(0,d.default)(e,"var(--antd-arrow-background-color)"),{[`${t}-pure`]:{position:"relative",maxWidth:"none",margin:e.sizePopupArrow,display:"inline-block",[`${t}-content`]:{display:"inline-block"}}}]})(i),(e=>{let{componentCls:t}=e;return{[t]:h.PresetColors.map(a=>{let i=e[`${a}6`];return{[`&${t}-${a}`]:{"--antd-arrow-background-color":i,[`${t}-inner`]:{backgroundColor:i},[`${t}-arrow`]:{background:"transparent"}}}})}})(i),(0,u.initZoomMotion)(i,"zoom-big")]},e=>{let{lineWidth:t,controlHeight:a,fontHeight:i,padding:r,wireframe:n,zIndexPopupBase:o,borderRadiusLG:l,marginXS:s,lineType:p,colorSplit:c,paddingSM:g}=e,u=a-i;return Object.assign(Object.assign(Object.assign({titleMinWidth:177,zIndexPopup:o+30},(0,m.getArrowToken)(e)),(0,d.getArrowOffsetToken)({contentRadius:l,limitVerticalRadius:!0})),{innerPadding:12*!n,titleMarginBottom:n?0:s,titlePadding:n?`${u/2}px ${r}px ${u/2-t}px`:0,titleBorderBottom:n?`${t}px ${p} ${c}`:"none",innerContentPadding:n?`${g}px ${r}px`:0})},{resetStyle:!1,deprecatedTokens:[["width","titleMinWidth"],["minWidth","titleMinWidth"]]});var A=function(e,t){var a={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(a[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,i=Object.getOwnPropertySymbols(e);r<i.length;r++)0>t.indexOf(i[r])&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(a[i[r]]=e[i[r]]);return a};let v=({title:e,content:a,prefixCls:i})=>e||a?t.createElement(t.Fragment,null,e&&t.createElement("div",{className:`${i}-title`},e),a&&t.createElement("div",{className:`${i}-inner-content`},a)):null,O=e=>{let{hashId:i,prefixCls:r,className:o,style:l,placement:s="top",title:p,content:g,children:u}=e,d=n(p),m=n(g),f=(0,a.default)(i,r,`${r}-pure`,`${r}-placement-${s}`,o);return t.createElement("div",{className:f,style:l},t.createElement("div",{className:`${r}-arrow`}),t.createElement(c.Popup,Object.assign({},e,{className:i,prefixCls:r}),u||t.createElement(v,{prefixCls:r,title:d,content:m})))},I=e=>{let{prefixCls:i,className:r}=e,n=A(e,["prefixCls","className"]),{getPrefixCls:o}=t.useContext(s.ConfigContext),l=o("popover",i),[p,c,g]=b(l);return p(t.createElement(O,Object.assign({},n,{prefixCls:l,hashId:c,className:(0,a.default)(r,g)})))};e.s(["Overlay",0,v,"default",0,I],310730);var $=function(e,t){var a={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(a[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,i=Object.getOwnPropertySymbols(e);r<i.length;r++)0>t.indexOf(i[r])&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(a[i[r]]=e[i[r]]);return a};let E=t.forwardRef((e,c)=>{var g,u;let{prefixCls:d,title:m,content:f,overlayClassName:_,placement:h="top",trigger:A="hover",children:O,mouseEnterDelay:I=.1,mouseLeaveDelay:E=.1,onOpenChange:C,overlayStyle:y={},styles:x,classNames:T}=e,k=$(e,["prefixCls","title","content","overlayClassName","placement","trigger","children","mouseEnterDelay","mouseLeaveDelay","onOpenChange","overlayStyle","styles","classNames"]),{getPrefixCls:w,className:L,style:S,classNames:M,styles:R}=(0,s.useComponentConfig)("popover"),j=w("popover",d),[N,P,D]=b(j),z=w(),H=(0,a.default)(_,P,D,L,M.root,null==T?void 0:T.root),B=(0,a.default)(M.body,null==T?void 0:T.body),[G,V]=(0,i.default)(!1,{value:null!=(g=e.open)?g:e.visible,defaultValue:null!=(u=e.defaultOpen)?u:e.defaultVisible}),F=(e,t)=>{V(e,!0),null==C||C(e,t)},q=n(m),U=n(f);return N(t.createElement(p.default,Object.assign({placement:h,trigger:A,mouseEnterDelay:I,mouseLeaveDelay:E},k,{prefixCls:j,classNames:{root:H,body:B},styles:{root:Object.assign(Object.assign(Object.assign(Object.assign({},R.root),S),y),null==x?void 0:x.root),body:Object.assign(Object.assign({},R.body),null==x?void 0:x.body)},ref:c,open:G,onOpenChange:e=>{F(e)},overlay:q||U?t.createElement(v,{prefixCls:j,title:q,content:U}):null,transitionName:(0,o.getTransitionName)(z,"zoom-big",k.transitionName),"data-popover-inject":!0}),(0,l.cloneElement)(O,{onKeyDown:e=>{var a,i;(0,t.isValidElement)(O)&&(null==(i=null==O?void 0:(a=O.props).onKeyDown)||i.call(a,e)),e.keyCode===r.default.ESC&&F(!1,e)}})))});E._InternalPanelDoNotUseOrYouWillBeFired=I,e.s(["default",0,E],829672),e.s(["Popover",0,E],282786)},166406,e=>{"use strict";var t=e.i(190144);e.s(["CopyOutlined",()=>t.default])},447566,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 000 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"}}]},name:"arrow-left",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["ArrowLeftOutlined",0,n],447566)},492030,e=>{"use strict";var t=e.i(121229);e.s(["CheckOutlined",()=>t.default])},596239,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M574 665.4a8.03 8.03 0 00-11.3 0L446.5 781.6c-53.8 53.8-144.6 59.5-204 0-59.5-59.5-53.8-150.2 0-204l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3l-39.8-39.8a8.03 8.03 0 00-11.3 0L191.4 526.5c-84.6 84.6-84.6 221.5 0 306s221.5 84.6 306 0l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3L574 665.4zm258.6-474c-84.6-84.6-221.5-84.6-306 0L410.3 307.6a8.03 8.03 0 000 11.3l39.7 39.7c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c53.8-53.8 144.6-59.5 204 0 59.5 59.5 53.8 150.2 0 204L665.3 562.6a8.03 8.03 0 000 11.3l39.8 39.8c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c84.5-84.6 84.5-221.5 0-306.1zM610.1 372.3a8.03 8.03 0 00-11.3 0L372.3 598.7a8.03 8.03 0 000 11.3l39.6 39.6c3.1 3.1 8.2 3.1 11.3 0l226.4-226.4c3.1-3.1 3.1-8.2 0-11.3l-39.5-39.6z"}}]},name:"link",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["LinkOutlined",0,n],596239)},326373,e=>{"use strict";var t=e.i(21539);e.s(["Dropdown",()=>t.default])},755151,e=>{"use strict";var t=e.i(247153);e.s(["DownOutlined",()=>t.default])},62478,e=>{"use strict";var t=e.i(764205);let a=async e=>{if(!e)return null;try{return await (0,t.getProxyUISettings)(e)}catch(e){return console.error("Error fetching proxy settings:",e),null}};e.s(["fetchProxySettings",0,a])},818581,(e,t,a)=>{"use strict";Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"useMergedRef",{enumerable:!0,get:function(){return r}});let i=e.r(271645);function r(e,t){let a=(0,i.useRef)(null),r=(0,i.useRef)(null);return(0,i.useCallback)(i=>{if(null===i){let e=a.current;e&&(a.current=null,e());let t=r.current;t&&(r.current=null,t())}else e&&(a.current=n(e,i)),t&&(r.current=n(t,i))},[e,t])}function n(e,t){if("function"!=typeof e)return e.current=t,()=>{e.current=null};{let a=e(t);return"function"==typeof a?a:()=>e(null)}}("function"==typeof a.default||"object"==typeof a.default&&null!==a.default)&&void 0===a.default.__esModule&&(Object.defineProperty(a.default,"__esModule",{value:!0}),Object.assign(a.default,a),t.exports=a.default)},602073,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64L128 192v384c0 212.1 171.9 384 384 384s384-171.9 384-384V192L512 64zm312 512c0 172.3-139.7 312-312 312S200 748.3 200 576V246l312-110 312 110v330z"}},{tag:"path",attrs:{d:"M378.4 475.1a35.91 35.91 0 00-50.9 0 35.91 35.91 0 000 50.9l129.4 129.4 2.1 2.1a33.98 33.98 0 0048.1 0L730.6 434a33.98 33.98 0 000-48.1l-2.8-2.8a33.98 33.98 0 00-48.1 0L483 579.7 378.4 475.1z"}}]},name:"safety",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["SafetyOutlined",0,n],602073)},44121,186515,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 000 13.8z"}}]},name:"menu-fold",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["MenuFoldOutlined",0,n],44121);let o={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 000-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0014.4 7z"}}]},name:"menu-unfold",theme:"outlined"};var l=a.forwardRef(function(e,i){return a.createElement(r.default,(0,t.default)({},e,{ref:i,icon:o}))});e.s(["MenuUnfoldOutlined",0,l],186515)},928685,e=>{"use strict";var t=e.i(38953);e.s(["SearchOutlined",()=>t.default])},283713,e=>{"use strict";var t=e.i(271645),a=e.i(764205),i=e.i(612256);let r="litellm_selected_worker_id";e.s(["useWorker",0,()=>{let{data:e}=(0,i.useUIConfig)(),n=e?.is_control_plane??!1,o=e?.workers??[],[l,s]=(0,t.useState)(()=>localStorage.getItem(r));(0,t.useEffect)(()=>{if(!l||0===o.length)return;let e=o.find(e=>e.worker_id===l);e&&(0,a.switchToWorkerUrl)(e.url)},[l,o]);let p=o.find(e=>e.worker_id===l)??null,c=(0,t.useCallback)(e=>{let t=o.find(t=>t.worker_id===e);t&&(s(e),localStorage.setItem(r,e),(0,a.switchToWorkerUrl)(t.url))},[o]);return{isControlPlane:n,workers:o,selectedWorkerId:l,selectedWorker:p,selectWorker:c,disconnectFromWorker:(0,t.useCallback)(()=>{s(null),localStorage.removeItem(r),(0,a.switchToWorkerUrl)(null)},[])}}])},295320,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M704 446H320c-4.4 0-8 3.6-8 8v402c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8V454c0-4.4-3.6-8-8-8zm-328 64h272v117H376V510zm272 290H376V683h272v117z"}},{tag:"path",attrs:{d:"M424 748a32 32 0 1064 0 32 32 0 10-64 0zm0-178a32 32 0 1064 0 32 32 0 10-64 0z"}},{tag:"path",attrs:{d:"M811.4 368.9C765.6 248 648.9 162 512.2 162S258.8 247.9 213 368.8C126.9 391.5 63.5 470.2 64 563.6 64.6 668 145.6 752.9 247.6 762c4.7.4 8.7-3.3 8.7-8v-60.4c0-4-3-7.4-7-7.9-27-3.4-52.5-15.2-72.1-34.5-24-23.5-37.2-55.1-37.2-88.6 0-28 9.1-54.4 26.2-76.4 16.7-21.4 40.2-36.9 66.1-43.7l37.9-10 13.9-36.7c8.6-22.8 20.6-44.2 35.7-63.5 14.9-19.2 32.6-36 52.4-50 41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.3c19.9 14 37.5 30.8 52.4 50 15.1 19.3 27.1 40.7 35.7 63.5l13.8 36.6 37.8 10c54.2 14.4 92.1 63.7 92.1 120 0 33.6-13.2 65.1-37.2 88.6-19.5 19.2-44.9 31.1-71.9 34.5-4 .5-6.9 3.9-6.9 7.9V754c0 4.7 4.1 8.4 8.8 8 101.7-9.2 182.5-94 183.2-198.2.6-93.4-62.7-172.1-148.6-194.9z"}}]},name:"cloud-server",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["CloudServerOutlined",0,n],295320)},190272,785913,e=>{"use strict";var t,a,i=((t={}).AUDIO_SPEECH="audio_speech",t.AUDIO_TRANSCRIPTION="audio_transcription",t.IMAGE_GENERATION="image_generation",t.VIDEO_GENERATION="video_generation",t.CHAT="chat",t.RESPONSES="responses",t.IMAGE_EDITS="image_edits",t.ANTHROPIC_MESSAGES="anthropic_messages",t.EMBEDDING="embedding",t),r=((a={}).IMAGE="image",a.VIDEO="video",a.CHAT="chat",a.RESPONSES="responses",a.IMAGE_EDITS="image_edits",a.ANTHROPIC_MESSAGES="anthropic_messages",a.EMBEDDINGS="embeddings",a.SPEECH="speech",a.TRANSCRIPTION="transcription",a.A2A_AGENTS="a2a_agents",a.MCP="mcp",a.REALTIME="realtime",a.INTERACTIONS="interactions",a);let n={image_generation:"image",video_generation:"video",chat:"chat",responses:"responses",image_edits:"image_edits",anthropic_messages:"anthropic_messages",audio_speech:"speech",audio_transcription:"transcription",embedding:"embeddings"};e.s(["EndpointType",()=>r,"getEndpointType",0,e=>{if(console.log("getEndpointType:",e),Object.values(i).includes(e)){let t=n[e];return console.log("endpointType:",t),t}return"chat"}],785913),e.s(["generateCodeSnippet",0,e=>{let t,{apiKeySource:a,accessToken:i,apiKey:n,inputMessage:o,chatHistory:l,selectedTags:s,selectedVectorStores:p,selectedGuardrails:c,selectedPolicies:g,selectedMCPServers:u,mcpServers:d,mcpServerToolRestrictions:m,selectedVoice:f,endpointType:_,selectedModel:h,selectedSdk:b,proxySettings:A}=e,v="session"===a?i:n,O=window.location.origin,I=A?.LITELLM_UI_API_DOC_BASE_URL;I&&I.trim()?O=I:A?.PROXY_BASE_URL&&(O=A.PROXY_BASE_URL);let $=o||"Your prompt here",E=$.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n"),C=l.filter(e=>!e.isImage).map(({role:e,content:t})=>({role:e,content:t})),y={};s.length>0&&(y.tags=s),p.length>0&&(y.vector_stores=p),c.length>0&&(y.guardrails=c),g.length>0&&(y.policies=g);let x=h||"your-model-name",T="azure"===b?`import openai | ||
| `]:Object.assign({},{background:e.skeletonLoadingBackground,backgroundSize:"400% 100%",animationName:c,animationDuration:e.skeletonLoadingMotionDuration,animationTimingFunction:"ease",animationIterationCount:"infinite"})}}})((0,p.mergeToken)(e,{skeletonAvatarCls:`${t}-avatar`,skeletonTitleCls:`${t}-title`,skeletonParagraphCls:`${t}-paragraph`,skeletonButtonCls:`${t}-button`,skeletonInputCls:`${t}-input`,skeletonImageCls:`${t}-image`,imageSizeBase:a(e.controlHeight).mul(1.5).equal(),borderRadius:100,skeletonLoadingBackground:`linear-gradient(90deg, ${e.gradientFromColor} 25%, ${e.gradientToColor} 37%, ${e.gradientFromColor} 63%)`,skeletonLoadingMotionDuration:"1.4s"}))},e=>{let{colorFillContent:t,colorFill:a}=e;return{color:t,colorGradientEnd:a,gradientFromColor:t,gradientToColor:a,titleHeight:e.controlHeight/2,blockRadius:e.borderRadiusSM,paragraphMarginTop:e.marginLG+e.marginXXS,paragraphLiHeight:e.controlHeight/2}},{deprecatedTokens:[["color","gradientFromColor"],["colorGradientEnd","gradientToColor"]]}),b=e=>{let{prefixCls:i,className:r,style:n,rows:o=0}=e,l=Array.from({length:o}).map((a,i)=>t.createElement("li",{key:i,style:{width:((e,t)=>{let{width:a,rows:i=2}=t;return Array.isArray(a)?a[e]:i-1===e?a:void 0})(i,e)}}));return t.createElement("ul",{className:(0,a.default)(i,r),style:n},l)},A=({prefixCls:e,className:i,width:r,style:n})=>t.createElement("h3",{className:(0,a.default)(e,i),style:Object.assign({width:r},n)});function v(e){return e&&"object"==typeof e?e:{}}let O=e=>{let{prefixCls:r,loading:o,className:l,rootClassName:s,style:p,children:c,avatar:g=!1,title:u=!0,paragraph:d=!0,active:m,round:f}=e,{getPrefixCls:_,direction:O,className:I,style:$}=(0,i.useComponentConfig)("skeleton"),E=_("skeleton",r),[C,y,x]=h(E);if(o||!("loading"in e)){let e,i,r=!!g,o=!!u,c=!!d;if(r){let a=Object.assign(Object.assign({prefixCls:`${E}-avatar`},o&&!c?{size:"large",shape:"square"}:{size:"large",shape:"circle"}),v(g));e=t.createElement("div",{className:`${E}-header`},t.createElement(n,Object.assign({},a)))}if(o||c){let e,a;if(o){let a=Object.assign(Object.assign({prefixCls:`${E}-title`},!r&&c?{width:"38%"}:r&&c?{width:"50%"}:{}),v(u));e=t.createElement(A,Object.assign({},a))}if(c){let e,i=Object.assign(Object.assign({prefixCls:`${E}-paragraph`},(e={},r&&o||(e.width="61%"),!r&&o?e.rows=3:e.rows=2,e)),v(d));a=t.createElement(b,Object.assign({},i))}i=t.createElement("div",{className:`${E}-content`},e,a)}let _=(0,a.default)(E,{[`${E}-with-avatar`]:r,[`${E}-active`]:m,[`${E}-rtl`]:"rtl"===O,[`${E}-round`]:f},I,l,s,y,x);return C(t.createElement("div",{className:_,style:Object.assign(Object.assign({},$),p)},e,i))}return null!=c?c:null};O.Button=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,block:c=!1,size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p,[`${d}-block`]:c},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-button`,size:g},b))))},O.Avatar=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,shape:c="circle",size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls","className"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-avatar`,shape:c,size:g},b))))},O.Input=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,block:c,size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p,[`${d}-block`]:c},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-input`,size:g},b))))},O.Image=e=>{let{prefixCls:r,className:n,rootClassName:o,style:l,active:s}=e,{getPrefixCls:p}=t.useContext(i.ConfigContext),c=p("skeleton",r),[g,u,d]=h(c),m=(0,a.default)(c,`${c}-element`,{[`${c}-active`]:s},n,o,u,d);return g(t.createElement("div",{className:m},t.createElement("div",{className:(0,a.default)(`${c}-image`,n),style:l},t.createElement("svg",{viewBox:"0 0 1098 1024",xmlns:"http://www.w3.org/2000/svg",className:`${c}-image-svg`},t.createElement("title",null,"Image placeholder"),t.createElement("path",{d:"M365.714286 329.142857q0 45.714286-32.036571 77.677714t-77.677714 32.036571-77.677714-32.036571-32.036571-77.677714 32.036571-77.677714 77.677714-32.036571 77.677714 32.036571 32.036571 77.677714zM950.857143 548.571429l0 256-804.571429 0 0-109.714286 182.857143-182.857143 91.428571 91.428571 292.571429-292.571429zM1005.714286 146.285714l-914.285714 0q-7.460571 0-12.873143 5.412571t-5.412571 12.873143l0 694.857143q0 7.460571 5.412571 12.873143t12.873143 5.412571l914.285714 0q7.460571 0 12.873143-5.412571t5.412571-12.873143l0-694.857143q0-7.460571-5.412571-12.873143t-12.873143-5.412571zM1097.142857 164.571429l0 694.857143q0 37.741714-26.843429 64.585143t-64.585143 26.843429l-914.285714 0q-37.741714 0-64.585143-26.843429t-26.843429-64.585143l0-694.857143q0-37.741714 26.843429-64.585143t64.585143-26.843429l914.285714 0q37.741714 0 64.585143 26.843429t26.843429 64.585143z",className:`${c}-image-path`})))))},O.Node=e=>{let{prefixCls:r,className:n,rootClassName:o,style:l,active:s,children:p}=e,{getPrefixCls:c}=t.useContext(i.ConfigContext),g=c("skeleton",r),[u,d,m]=h(g),f=(0,a.default)(g,`${g}-element`,{[`${g}-active`]:s},d,n,o,m);return u(t.createElement("div",{className:f},t.createElement("div",{className:(0,a.default)(`${g}-image`,n),style:l},p)))},e.s(["default",0,O],185793)},959013,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"}},{tag:"path",attrs:{d:"M192 474h672q8 0 8 8v60q0 8-8 8H160q-8 0-8-8v-60q0-8 8-8z"}}]},name:"plus",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["default",0,n],959013)},282786,836938,310730,829672,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),i=e.i(914949),r=e.i(404948);let n=e=>e?"function"==typeof e?e():e:null;e.s(["getRenderPropValue",0,n],836938);var o=e.i(613541),l=e.i(763731),s=e.i(242064),p=e.i(491816);e.i(793154);var c=e.i(880476),g=e.i(183293),u=e.i(717356),d=e.i(320560),m=e.i(307358),f=e.i(246422),_=e.i(838378),h=e.i(617933);let b=(0,f.genStyleHooks)("Popover",e=>{let{colorBgElevated:t,colorText:a}=e,i=(0,_.mergeToken)(e,{popoverBg:t,popoverColor:a});return[(e=>{let{componentCls:t,popoverColor:a,titleMinWidth:i,fontWeightStrong:r,innerPadding:n,boxShadowSecondary:o,colorTextHeading:l,borderRadiusLG:s,zIndexPopup:p,titleMarginBottom:c,colorBgElevated:u,popoverBg:m,titleBorderBottom:f,innerContentPadding:_,titlePadding:h}=e;return[{[t]:Object.assign(Object.assign({},(0,g.resetComponent)(e)),{position:"absolute",top:0,left:{_skip_check_:!0,value:0},zIndex:p,fontWeight:"normal",whiteSpace:"normal",textAlign:"start",cursor:"auto",userSelect:"text","--valid-offset-x":"var(--arrow-offset-horizontal, var(--arrow-x))",transformOrigin:"var(--valid-offset-x, 50%) var(--arrow-y, 50%)","--antd-arrow-background-color":u,width:"max-content",maxWidth:"100vw","&-rtl":{direction:"rtl"},"&-hidden":{display:"none"},[`${t}-content`]:{position:"relative"},[`${t}-inner`]:{backgroundColor:m,backgroundClip:"padding-box",borderRadius:s,boxShadow:o,padding:n},[`${t}-title`]:{minWidth:i,marginBottom:c,color:l,fontWeight:r,borderBottom:f,padding:h},[`${t}-inner-content`]:{color:a,padding:_}})},(0,d.default)(e,"var(--antd-arrow-background-color)"),{[`${t}-pure`]:{position:"relative",maxWidth:"none",margin:e.sizePopupArrow,display:"inline-block",[`${t}-content`]:{display:"inline-block"}}}]})(i),(e=>{let{componentCls:t}=e;return{[t]:h.PresetColors.map(a=>{let i=e[`${a}6`];return{[`&${t}-${a}`]:{"--antd-arrow-background-color":i,[`${t}-inner`]:{backgroundColor:i},[`${t}-arrow`]:{background:"transparent"}}}})}})(i),(0,u.initZoomMotion)(i,"zoom-big")]},e=>{let{lineWidth:t,controlHeight:a,fontHeight:i,padding:r,wireframe:n,zIndexPopupBase:o,borderRadiusLG:l,marginXS:s,lineType:p,colorSplit:c,paddingSM:g}=e,u=a-i;return Object.assign(Object.assign(Object.assign({titleMinWidth:177,zIndexPopup:o+30},(0,m.getArrowToken)(e)),(0,d.getArrowOffsetToken)({contentRadius:l,limitVerticalRadius:!0})),{innerPadding:12*!n,titleMarginBottom:n?0:s,titlePadding:n?`${u/2}px ${r}px ${u/2-t}px`:0,titleBorderBottom:n?`${t}px ${p} ${c}`:"none",innerContentPadding:n?`${g}px ${r}px`:0})},{resetStyle:!1,deprecatedTokens:[["width","titleMinWidth"],["minWidth","titleMinWidth"]]});var A=function(e,t){var a={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(a[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,i=Object.getOwnPropertySymbols(e);r<i.length;r++)0>t.indexOf(i[r])&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(a[i[r]]=e[i[r]]);return a};let v=({title:e,content:a,prefixCls:i})=>e||a?t.createElement(t.Fragment,null,e&&t.createElement("div",{className:`${i}-title`},e),a&&t.createElement("div",{className:`${i}-inner-content`},a)):null,O=e=>{let{hashId:i,prefixCls:r,className:o,style:l,placement:s="top",title:p,content:g,children:u}=e,d=n(p),m=n(g),f=(0,a.default)(i,r,`${r}-pure`,`${r}-placement-${s}`,o);return t.createElement("div",{className:f,style:l},t.createElement("div",{className:`${r}-arrow`}),t.createElement(c.Popup,Object.assign({},e,{className:i,prefixCls:r}),u||t.createElement(v,{prefixCls:r,title:d,content:m})))},I=e=>{let{prefixCls:i,className:r}=e,n=A(e,["prefixCls","className"]),{getPrefixCls:o}=t.useContext(s.ConfigContext),l=o("popover",i),[p,c,g]=b(l);return p(t.createElement(O,Object.assign({},n,{prefixCls:l,hashId:c,className:(0,a.default)(r,g)})))};e.s(["Overlay",0,v,"default",0,I],310730);var $=function(e,t){var a={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(a[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,i=Object.getOwnPropertySymbols(e);r<i.length;r++)0>t.indexOf(i[r])&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(a[i[r]]=e[i[r]]);return a};let E=t.forwardRef((e,c)=>{var g,u;let{prefixCls:d,title:m,content:f,overlayClassName:_,placement:h="top",trigger:A="hover",children:O,mouseEnterDelay:I=.1,mouseLeaveDelay:E=.1,onOpenChange:C,overlayStyle:y={},styles:x,classNames:T}=e,k=$(e,["prefixCls","title","content","overlayClassName","placement","trigger","children","mouseEnterDelay","mouseLeaveDelay","onOpenChange","overlayStyle","styles","classNames"]),{getPrefixCls:w,className:L,style:S,classNames:M,styles:R}=(0,s.useComponentConfig)("popover"),j=w("popover",d),[N,P,D]=b(j),z=w(),H=(0,a.default)(_,P,D,L,M.root,null==T?void 0:T.root),B=(0,a.default)(M.body,null==T?void 0:T.body),[G,V]=(0,i.default)(!1,{value:null!=(g=e.open)?g:e.visible,defaultValue:null!=(u=e.defaultOpen)?u:e.defaultVisible}),F=(e,t)=>{V(e,!0),null==C||C(e,t)},q=n(m),U=n(f);return N(t.createElement(p.default,Object.assign({placement:h,trigger:A,mouseEnterDelay:I,mouseLeaveDelay:E},k,{prefixCls:j,classNames:{root:H,body:B},styles:{root:Object.assign(Object.assign(Object.assign(Object.assign({},R.root),S),y),null==x?void 0:x.root),body:Object.assign(Object.assign({},R.body),null==x?void 0:x.body)},ref:c,open:G,onOpenChange:e=>{F(e)},overlay:q||U?t.createElement(v,{prefixCls:j,title:q,content:U}):null,transitionName:(0,o.getTransitionName)(z,"zoom-big",k.transitionName),"data-popover-inject":!0}),(0,l.cloneElement)(O,{onKeyDown:e=>{var a,i;(0,t.isValidElement)(O)&&(null==(i=null==O?void 0:(a=O.props).onKeyDown)||i.call(a,e)),e.keyCode===r.default.ESC&&F(!1,e)}})))});E._InternalPanelDoNotUseOrYouWillBeFired=I,e.s(["default",0,E],829672),e.s(["Popover",0,E],282786)},166406,e=>{"use strict";var t=e.i(190144);e.s(["CopyOutlined",()=>t.default])},447566,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 000 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"}}]},name:"arrow-left",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["ArrowLeftOutlined",0,n],447566)},492030,e=>{"use strict";var t=e.i(121229);e.s(["CheckOutlined",()=>t.default])},596239,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M574 665.4a8.03 8.03 0 00-11.3 0L446.5 781.6c-53.8 53.8-144.6 59.5-204 0-59.5-59.5-53.8-150.2 0-204l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3l-39.8-39.8a8.03 8.03 0 00-11.3 0L191.4 526.5c-84.6 84.6-84.6 221.5 0 306s221.5 84.6 306 0l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3L574 665.4zm258.6-474c-84.6-84.6-221.5-84.6-306 0L410.3 307.6a8.03 8.03 0 000 11.3l39.7 39.7c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c53.8-53.8 144.6-59.5 204 0 59.5 59.5 53.8 150.2 0 204L665.3 562.6a8.03 8.03 0 000 11.3l39.8 39.8c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c84.5-84.6 84.5-221.5 0-306.1zM610.1 372.3a8.03 8.03 0 00-11.3 0L372.3 598.7a8.03 8.03 0 000 11.3l39.6 39.6c3.1 3.1 8.2 3.1 11.3 0l226.4-226.4c3.1-3.1 3.1-8.2 0-11.3l-39.5-39.6z"}}]},name:"link",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["LinkOutlined",0,n],596239)},326373,e=>{"use strict";var t=e.i(21539);e.s(["Dropdown",()=>t.default])},755151,e=>{"use strict";var t=e.i(247153);e.s(["DownOutlined",()=>t.default])},62478,e=>{"use strict";var t=e.i(602869);let a=async e=>{if(!e)return null;try{return await (0,t.getProxyUISettings)(e)}catch(e){return console.error("Error fetching proxy settings:",e),null}};e.s(["fetchProxySettings",0,a])},818581,(e,t,a)=>{"use strict";Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"useMergedRef",{enumerable:!0,get:function(){return r}});let i=e.r(271645);function r(e,t){let a=(0,i.useRef)(null),r=(0,i.useRef)(null);return(0,i.useCallback)(i=>{if(null===i){let e=a.current;e&&(a.current=null,e());let t=r.current;t&&(r.current=null,t())}else e&&(a.current=n(e,i)),t&&(r.current=n(t,i))},[e,t])}function n(e,t){if("function"!=typeof e)return e.current=t,()=>{e.current=null};{let a=e(t);return"function"==typeof a?a:()=>e(null)}}("function"==typeof a.default||"object"==typeof a.default&&null!==a.default)&&void 0===a.default.__esModule&&(Object.defineProperty(a.default,"__esModule",{value:!0}),Object.assign(a.default,a),t.exports=a.default)},602073,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64L128 192v384c0 212.1 171.9 384 384 384s384-171.9 384-384V192L512 64zm312 512c0 172.3-139.7 312-312 312S200 748.3 200 576V246l312-110 312 110v330z"}},{tag:"path",attrs:{d:"M378.4 475.1a35.91 35.91 0 00-50.9 0 35.91 35.91 0 000 50.9l129.4 129.4 2.1 2.1a33.98 33.98 0 0048.1 0L730.6 434a33.98 33.98 0 000-48.1l-2.8-2.8a33.98 33.98 0 00-48.1 0L483 579.7 378.4 475.1z"}}]},name:"safety",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["SafetyOutlined",0,n],602073)},44121,186515,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 000 13.8z"}}]},name:"menu-fold",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["MenuFoldOutlined",0,n],44121);let o={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 000-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0014.4 7z"}}]},name:"menu-unfold",theme:"outlined"};var l=a.forwardRef(function(e,i){return a.createElement(r.default,(0,t.default)({},e,{ref:i,icon:o}))});e.s(["MenuUnfoldOutlined",0,l],186515)},928685,e=>{"use strict";var t=e.i(38953);e.s(["SearchOutlined",()=>t.default])},283713,e=>{"use strict";var t=e.i(271645),a=e.i(602869),i=e.i(612256);let r="litellm_selected_worker_id";e.s(["useWorker",0,()=>{let{data:e}=(0,i.useUIConfig)(),n=e?.is_control_plane??!1,o=e?.workers??[],[l,s]=(0,t.useState)(()=>localStorage.getItem(r));(0,t.useEffect)(()=>{if(!l||0===o.length)return;let e=o.find(e=>e.worker_id===l);e&&(0,a.switchToWorkerUrl)(e.url)},[l,o]);let p=o.find(e=>e.worker_id===l)??null,c=(0,t.useCallback)(e=>{let t=o.find(t=>t.worker_id===e);t&&(s(e),localStorage.setItem(r,e),(0,a.switchToWorkerUrl)(t.url))},[o]);return{isControlPlane:n,workers:o,selectedWorkerId:l,selectedWorker:p,selectWorker:c,disconnectFromWorker:(0,t.useCallback)(()=>{s(null),localStorage.removeItem(r),(0,a.switchToWorkerUrl)(null)},[])}}])},295320,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M704 446H320c-4.4 0-8 3.6-8 8v402c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8V454c0-4.4-3.6-8-8-8zm-328 64h272v117H376V510zm272 290H376V683h272v117z"}},{tag:"path",attrs:{d:"M424 748a32 32 0 1064 0 32 32 0 10-64 0zm0-178a32 32 0 1064 0 32 32 0 10-64 0z"}},{tag:"path",attrs:{d:"M811.4 368.9C765.6 248 648.9 162 512.2 162S258.8 247.9 213 368.8C126.9 391.5 63.5 470.2 64 563.6 64.6 668 145.6 752.9 247.6 762c4.7.4 8.7-3.3 8.7-8v-60.4c0-4-3-7.4-7-7.9-27-3.4-52.5-15.2-72.1-34.5-24-23.5-37.2-55.1-37.2-88.6 0-28 9.1-54.4 26.2-76.4 16.7-21.4 40.2-36.9 66.1-43.7l37.9-10 13.9-36.7c8.6-22.8 20.6-44.2 35.7-63.5 14.9-19.2 32.6-36 52.4-50 41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.3c19.9 14 37.5 30.8 52.4 50 15.1 19.3 27.1 40.7 35.7 63.5l13.8 36.6 37.8 10c54.2 14.4 92.1 63.7 92.1 120 0 33.6-13.2 65.1-37.2 88.6-19.5 19.2-44.9 31.1-71.9 34.5-4 .5-6.9 3.9-6.9 7.9V754c0 4.7 4.1 8.4 8.8 8 101.7-9.2 182.5-94 183.2-198.2.6-93.4-62.7-172.1-148.6-194.9z"}}]},name:"cloud-server",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["CloudServerOutlined",0,n],295320)},190272,785913,e=>{"use strict";var t,a,i=((t={}).AUDIO_SPEECH="audio_speech",t.AUDIO_TRANSCRIPTION="audio_transcription",t.IMAGE_GENERATION="image_generation",t.VIDEO_GENERATION="video_generation",t.CHAT="chat",t.RESPONSES="responses",t.IMAGE_EDITS="image_edits",t.ANTHROPIC_MESSAGES="anthropic_messages",t.EMBEDDING="embedding",t),r=((a={}).IMAGE="image",a.VIDEO="video",a.CHAT="chat",a.RESPONSES="responses",a.IMAGE_EDITS="image_edits",a.ANTHROPIC_MESSAGES="anthropic_messages",a.EMBEDDINGS="embeddings",a.SPEECH="speech",a.TRANSCRIPTION="transcription",a.A2A_AGENTS="a2a_agents",a.MCP="mcp",a.REALTIME="realtime",a.INTERACTIONS="interactions",a);let n={image_generation:"image",video_generation:"video",chat:"chat",responses:"responses",image_edits:"image_edits",anthropic_messages:"anthropic_messages",audio_speech:"speech",audio_transcription:"transcription",embedding:"embeddings"};e.s(["EndpointType",()=>r,"getEndpointType",0,e=>{if(console.log("getEndpointType:",e),Object.values(i).includes(e)){let t=n[e];return console.log("endpointType:",t),t}return"chat"}],785913),e.s(["generateCodeSnippet",0,e=>{let t,{apiKeySource:a,accessToken:i,apiKey:n,inputMessage:o,chatHistory:l,selectedTags:s,selectedVectorStores:p,selectedGuardrails:c,selectedPolicies:g,selectedMCPServers:u,mcpServers:d,mcpServerToolRestrictions:m,selectedVoice:f,endpointType:_,selectedModel:h,selectedSdk:b,proxySettings:A}=e,v="session"===a?i:n,O=window.location.origin,I=A?.LITELLM_UI_API_DOC_BASE_URL;I&&I.trim()?O=I:A?.PROXY_BASE_URL&&(O=A.PROXY_BASE_URL);let $=o||"Your prompt here",E=$.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n"),C=l.filter(e=>!e.isImage).map(({role:e,content:t})=>({role:e,content:t})),y={};s.length>0&&(y.tags=s),p.length>0&&(y.vector_stores=p),c.length>0&&(y.guardrails=c),g.length>0&&(y.policies=g);let x=h||"your-model-name",T="azure"===b?`import openai |
| ${i}, | ||
| ${r} > li, | ||
| ${a}, | ||
| ${n}, | ||
| ${o}, | ||
| ${l} | ||
| `]:Object.assign({},{background:e.skeletonLoadingBackground,backgroundSize:"400% 100%",animationName:c,animationDuration:e.skeletonLoadingMotionDuration,animationTimingFunction:"ease",animationIterationCount:"infinite"})}}})((0,p.mergeToken)(e,{skeletonAvatarCls:`${t}-avatar`,skeletonTitleCls:`${t}-title`,skeletonParagraphCls:`${t}-paragraph`,skeletonButtonCls:`${t}-button`,skeletonInputCls:`${t}-input`,skeletonImageCls:`${t}-image`,imageSizeBase:a(e.controlHeight).mul(1.5).equal(),borderRadius:100,skeletonLoadingBackground:`linear-gradient(90deg, ${e.gradientFromColor} 25%, ${e.gradientToColor} 37%, ${e.gradientFromColor} 63%)`,skeletonLoadingMotionDuration:"1.4s"}))},e=>{let{colorFillContent:t,colorFill:a}=e;return{color:t,colorGradientEnd:a,gradientFromColor:t,gradientToColor:a,titleHeight:e.controlHeight/2,blockRadius:e.borderRadiusSM,paragraphMarginTop:e.marginLG+e.marginXXS,paragraphLiHeight:e.controlHeight/2}},{deprecatedTokens:[["color","gradientFromColor"],["colorGradientEnd","gradientToColor"]]}),b=e=>{let{prefixCls:i,className:r,style:n,rows:o=0}=e,l=Array.from({length:o}).map((a,i)=>t.createElement("li",{key:i,style:{width:((e,t)=>{let{width:a,rows:i=2}=t;return Array.isArray(a)?a[e]:i-1===e?a:void 0})(i,e)}}));return t.createElement("ul",{className:(0,a.default)(i,r),style:n},l)},A=({prefixCls:e,className:i,width:r,style:n})=>t.createElement("h3",{className:(0,a.default)(e,i),style:Object.assign({width:r},n)});function v(e){return e&&"object"==typeof e?e:{}}let O=e=>{let{prefixCls:r,loading:o,className:l,rootClassName:s,style:p,children:c,avatar:g=!1,title:u=!0,paragraph:d=!0,active:m,round:f}=e,{getPrefixCls:_,direction:O,className:I,style:$}=(0,i.useComponentConfig)("skeleton"),E=_("skeleton",r),[C,y,x]=h(E);if(o||!("loading"in e)){let e,i,r=!!g,o=!!u,c=!!d;if(r){let a=Object.assign(Object.assign({prefixCls:`${E}-avatar`},o&&!c?{size:"large",shape:"square"}:{size:"large",shape:"circle"}),v(g));e=t.createElement("div",{className:`${E}-header`},t.createElement(n,Object.assign({},a)))}if(o||c){let e,a;if(o){let a=Object.assign(Object.assign({prefixCls:`${E}-title`},!r&&c?{width:"38%"}:r&&c?{width:"50%"}:{}),v(u));e=t.createElement(A,Object.assign({},a))}if(c){let e,i=Object.assign(Object.assign({prefixCls:`${E}-paragraph`},(e={},r&&o||(e.width="61%"),!r&&o?e.rows=3:e.rows=2,e)),v(d));a=t.createElement(b,Object.assign({},i))}i=t.createElement("div",{className:`${E}-content`},e,a)}let _=(0,a.default)(E,{[`${E}-with-avatar`]:r,[`${E}-active`]:m,[`${E}-rtl`]:"rtl"===O,[`${E}-round`]:f},I,l,s,y,x);return C(t.createElement("div",{className:_,style:Object.assign(Object.assign({},$),p)},e,i))}return null!=c?c:null};O.Button=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,block:c=!1,size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p,[`${d}-block`]:c},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-button`,size:g},b))))},O.Avatar=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,shape:c="circle",size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls","className"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-avatar`,shape:c,size:g},b))))},O.Input=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,block:c,size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p,[`${d}-block`]:c},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-input`,size:g},b))))},O.Image=e=>{let{prefixCls:r,className:n,rootClassName:o,style:l,active:s}=e,{getPrefixCls:p}=t.useContext(i.ConfigContext),c=p("skeleton",r),[g,u,d]=h(c),m=(0,a.default)(c,`${c}-element`,{[`${c}-active`]:s},n,o,u,d);return g(t.createElement("div",{className:m},t.createElement("div",{className:(0,a.default)(`${c}-image`,n),style:l},t.createElement("svg",{viewBox:"0 0 1098 1024",xmlns:"http://www.w3.org/2000/svg",className:`${c}-image-svg`},t.createElement("title",null,"Image placeholder"),t.createElement("path",{d:"M365.714286 329.142857q0 45.714286-32.036571 77.677714t-77.677714 32.036571-77.677714-32.036571-32.036571-77.677714 32.036571-77.677714 77.677714-32.036571 77.677714 32.036571 32.036571 77.677714zM950.857143 548.571429l0 256-804.571429 0 0-109.714286 182.857143-182.857143 91.428571 91.428571 292.571429-292.571429zM1005.714286 146.285714l-914.285714 0q-7.460571 0-12.873143 5.412571t-5.412571 12.873143l0 694.857143q0 7.460571 5.412571 12.873143t12.873143 5.412571l914.285714 0q7.460571 0 12.873143-5.412571t5.412571-12.873143l0-694.857143q0-7.460571-5.412571-12.873143t-12.873143-5.412571zM1097.142857 164.571429l0 694.857143q0 37.741714-26.843429 64.585143t-64.585143 26.843429l-914.285714 0q-37.741714 0-64.585143-26.843429t-26.843429-64.585143l0-694.857143q0-37.741714 26.843429-64.585143t64.585143-26.843429l914.285714 0q37.741714 0 64.585143 26.843429t26.843429 64.585143z",className:`${c}-image-path`})))))},O.Node=e=>{let{prefixCls:r,className:n,rootClassName:o,style:l,active:s,children:p}=e,{getPrefixCls:c}=t.useContext(i.ConfigContext),g=c("skeleton",r),[u,d,m]=h(g),f=(0,a.default)(g,`${g}-element`,{[`${g}-active`]:s},d,n,o,m);return u(t.createElement("div",{className:f},t.createElement("div",{className:(0,a.default)(`${g}-image`,n),style:l},p)))},e.s(["default",0,O],185793)},959013,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"}},{tag:"path",attrs:{d:"M192 474h672q8 0 8 8v60q0 8-8 8H160q-8 0-8-8v-60q0-8 8-8z"}}]},name:"plus",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["default",0,n],959013)},282786,836938,310730,829672,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),i=e.i(914949),r=e.i(404948);let n=e=>e?"function"==typeof e?e():e:null;e.s(["getRenderPropValue",0,n],836938);var o=e.i(613541),l=e.i(763731),s=e.i(242064),p=e.i(491816);e.i(793154);var c=e.i(880476),g=e.i(183293),u=e.i(717356),d=e.i(320560),m=e.i(307358),f=e.i(246422),_=e.i(838378),h=e.i(617933);let b=(0,f.genStyleHooks)("Popover",e=>{let{colorBgElevated:t,colorText:a}=e,i=(0,_.mergeToken)(e,{popoverBg:t,popoverColor:a});return[(e=>{let{componentCls:t,popoverColor:a,titleMinWidth:i,fontWeightStrong:r,innerPadding:n,boxShadowSecondary:o,colorTextHeading:l,borderRadiusLG:s,zIndexPopup:p,titleMarginBottom:c,colorBgElevated:u,popoverBg:m,titleBorderBottom:f,innerContentPadding:_,titlePadding:h}=e;return[{[t]:Object.assign(Object.assign({},(0,g.resetComponent)(e)),{position:"absolute",top:0,left:{_skip_check_:!0,value:0},zIndex:p,fontWeight:"normal",whiteSpace:"normal",textAlign:"start",cursor:"auto",userSelect:"text","--valid-offset-x":"var(--arrow-offset-horizontal, var(--arrow-x))",transformOrigin:"var(--valid-offset-x, 50%) var(--arrow-y, 50%)","--antd-arrow-background-color":u,width:"max-content",maxWidth:"100vw","&-rtl":{direction:"rtl"},"&-hidden":{display:"none"},[`${t}-content`]:{position:"relative"},[`${t}-inner`]:{backgroundColor:m,backgroundClip:"padding-box",borderRadius:s,boxShadow:o,padding:n},[`${t}-title`]:{minWidth:i,marginBottom:c,color:l,fontWeight:r,borderBottom:f,padding:h},[`${t}-inner-content`]:{color:a,padding:_}})},(0,d.default)(e,"var(--antd-arrow-background-color)"),{[`${t}-pure`]:{position:"relative",maxWidth:"none",margin:e.sizePopupArrow,display:"inline-block",[`${t}-content`]:{display:"inline-block"}}}]})(i),(e=>{let{componentCls:t}=e;return{[t]:h.PresetColors.map(a=>{let i=e[`${a}6`];return{[`&${t}-${a}`]:{"--antd-arrow-background-color":i,[`${t}-inner`]:{backgroundColor:i},[`${t}-arrow`]:{background:"transparent"}}}})}})(i),(0,u.initZoomMotion)(i,"zoom-big")]},e=>{let{lineWidth:t,controlHeight:a,fontHeight:i,padding:r,wireframe:n,zIndexPopupBase:o,borderRadiusLG:l,marginXS:s,lineType:p,colorSplit:c,paddingSM:g}=e,u=a-i;return Object.assign(Object.assign(Object.assign({titleMinWidth:177,zIndexPopup:o+30},(0,m.getArrowToken)(e)),(0,d.getArrowOffsetToken)({contentRadius:l,limitVerticalRadius:!0})),{innerPadding:12*!n,titleMarginBottom:n?0:s,titlePadding:n?`${u/2}px ${r}px ${u/2-t}px`:0,titleBorderBottom:n?`${t}px ${p} ${c}`:"none",innerContentPadding:n?`${g}px ${r}px`:0})},{resetStyle:!1,deprecatedTokens:[["width","titleMinWidth"],["minWidth","titleMinWidth"]]});var A=function(e,t){var a={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(a[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,i=Object.getOwnPropertySymbols(e);r<i.length;r++)0>t.indexOf(i[r])&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(a[i[r]]=e[i[r]]);return a};let v=({title:e,content:a,prefixCls:i})=>e||a?t.createElement(t.Fragment,null,e&&t.createElement("div",{className:`${i}-title`},e),a&&t.createElement("div",{className:`${i}-inner-content`},a)):null,O=e=>{let{hashId:i,prefixCls:r,className:o,style:l,placement:s="top",title:p,content:g,children:u}=e,d=n(p),m=n(g),f=(0,a.default)(i,r,`${r}-pure`,`${r}-placement-${s}`,o);return t.createElement("div",{className:f,style:l},t.createElement("div",{className:`${r}-arrow`}),t.createElement(c.Popup,Object.assign({},e,{className:i,prefixCls:r}),u||t.createElement(v,{prefixCls:r,title:d,content:m})))},I=e=>{let{prefixCls:i,className:r}=e,n=A(e,["prefixCls","className"]),{getPrefixCls:o}=t.useContext(s.ConfigContext),l=o("popover",i),[p,c,g]=b(l);return p(t.createElement(O,Object.assign({},n,{prefixCls:l,hashId:c,className:(0,a.default)(r,g)})))};e.s(["Overlay",0,v,"default",0,I],310730);var $=function(e,t){var a={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(a[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,i=Object.getOwnPropertySymbols(e);r<i.length;r++)0>t.indexOf(i[r])&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(a[i[r]]=e[i[r]]);return a};let E=t.forwardRef((e,c)=>{var g,u;let{prefixCls:d,title:m,content:f,overlayClassName:_,placement:h="top",trigger:A="hover",children:O,mouseEnterDelay:I=.1,mouseLeaveDelay:E=.1,onOpenChange:C,overlayStyle:y={},styles:x,classNames:T}=e,k=$(e,["prefixCls","title","content","overlayClassName","placement","trigger","children","mouseEnterDelay","mouseLeaveDelay","onOpenChange","overlayStyle","styles","classNames"]),{getPrefixCls:w,className:L,style:S,classNames:M,styles:R}=(0,s.useComponentConfig)("popover"),j=w("popover",d),[N,P,D]=b(j),z=w(),H=(0,a.default)(_,P,D,L,M.root,null==T?void 0:T.root),B=(0,a.default)(M.body,null==T?void 0:T.body),[G,V]=(0,i.default)(!1,{value:null!=(g=e.open)?g:e.visible,defaultValue:null!=(u=e.defaultOpen)?u:e.defaultVisible}),F=(e,t)=>{V(e,!0),null==C||C(e,t)},q=n(m),U=n(f);return N(t.createElement(p.default,Object.assign({placement:h,trigger:A,mouseEnterDelay:I,mouseLeaveDelay:E},k,{prefixCls:j,classNames:{root:H,body:B},styles:{root:Object.assign(Object.assign(Object.assign(Object.assign({},R.root),S),y),null==x?void 0:x.root),body:Object.assign(Object.assign({},R.body),null==x?void 0:x.body)},ref:c,open:G,onOpenChange:e=>{F(e)},overlay:q||U?t.createElement(v,{prefixCls:j,title:q,content:U}):null,transitionName:(0,o.getTransitionName)(z,"zoom-big",k.transitionName),"data-popover-inject":!0}),(0,l.cloneElement)(O,{onKeyDown:e=>{var a,i;(0,t.isValidElement)(O)&&(null==(i=null==O?void 0:(a=O.props).onKeyDown)||i.call(a,e)),e.keyCode===r.default.ESC&&F(!1,e)}})))});E._InternalPanelDoNotUseOrYouWillBeFired=I,e.s(["default",0,E],829672),e.s(["Popover",0,E],282786)},166406,e=>{"use strict";var t=e.i(190144);e.s(["CopyOutlined",()=>t.default])},447566,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 000 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"}}]},name:"arrow-left",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["ArrowLeftOutlined",0,n],447566)},492030,e=>{"use strict";var t=e.i(121229);e.s(["CheckOutlined",()=>t.default])},596239,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M574 665.4a8.03 8.03 0 00-11.3 0L446.5 781.6c-53.8 53.8-144.6 59.5-204 0-59.5-59.5-53.8-150.2 0-204l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3l-39.8-39.8a8.03 8.03 0 00-11.3 0L191.4 526.5c-84.6 84.6-84.6 221.5 0 306s221.5 84.6 306 0l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3L574 665.4zm258.6-474c-84.6-84.6-221.5-84.6-306 0L410.3 307.6a8.03 8.03 0 000 11.3l39.7 39.7c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c53.8-53.8 144.6-59.5 204 0 59.5 59.5 53.8 150.2 0 204L665.3 562.6a8.03 8.03 0 000 11.3l39.8 39.8c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c84.5-84.6 84.5-221.5 0-306.1zM610.1 372.3a8.03 8.03 0 00-11.3 0L372.3 598.7a8.03 8.03 0 000 11.3l39.6 39.6c3.1 3.1 8.2 3.1 11.3 0l226.4-226.4c3.1-3.1 3.1-8.2 0-11.3l-39.5-39.6z"}}]},name:"link",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["LinkOutlined",0,n],596239)},326373,e=>{"use strict";var t=e.i(21539);e.s(["Dropdown",()=>t.default])},755151,e=>{"use strict";var t=e.i(247153);e.s(["DownOutlined",()=>t.default])},62478,e=>{"use strict";var t=e.i(764205);let a=async e=>{if(!e)return null;try{return await (0,t.getProxyUISettings)(e)}catch(e){return console.error("Error fetching proxy settings:",e),null}};e.s(["fetchProxySettings",0,a])},818581,(e,t,a)=>{"use strict";Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"useMergedRef",{enumerable:!0,get:function(){return r}});let i=e.r(271645);function r(e,t){let a=(0,i.useRef)(null),r=(0,i.useRef)(null);return(0,i.useCallback)(i=>{if(null===i){let e=a.current;e&&(a.current=null,e());let t=r.current;t&&(r.current=null,t())}else e&&(a.current=n(e,i)),t&&(r.current=n(t,i))},[e,t])}function n(e,t){if("function"!=typeof e)return e.current=t,()=>{e.current=null};{let a=e(t);return"function"==typeof a?a:()=>e(null)}}("function"==typeof a.default||"object"==typeof a.default&&null!==a.default)&&void 0===a.default.__esModule&&(Object.defineProperty(a.default,"__esModule",{value:!0}),Object.assign(a.default,a),t.exports=a.default)},602073,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64L128 192v384c0 212.1 171.9 384 384 384s384-171.9 384-384V192L512 64zm312 512c0 172.3-139.7 312-312 312S200 748.3 200 576V246l312-110 312 110v330z"}},{tag:"path",attrs:{d:"M378.4 475.1a35.91 35.91 0 00-50.9 0 35.91 35.91 0 000 50.9l129.4 129.4 2.1 2.1a33.98 33.98 0 0048.1 0L730.6 434a33.98 33.98 0 000-48.1l-2.8-2.8a33.98 33.98 0 00-48.1 0L483 579.7 378.4 475.1z"}}]},name:"safety",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["SafetyOutlined",0,n],602073)},44121,186515,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 000 13.8z"}}]},name:"menu-fold",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["MenuFoldOutlined",0,n],44121);let o={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 000-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0014.4 7z"}}]},name:"menu-unfold",theme:"outlined"};var l=a.forwardRef(function(e,i){return a.createElement(r.default,(0,t.default)({},e,{ref:i,icon:o}))});e.s(["MenuUnfoldOutlined",0,l],186515)},928685,e=>{"use strict";var t=e.i(38953);e.s(["SearchOutlined",()=>t.default])},283713,e=>{"use strict";var t=e.i(271645),a=e.i(764205),i=e.i(612256);let r="litellm_selected_worker_id";e.s(["useWorker",0,()=>{let{data:e}=(0,i.useUIConfig)(),n=e?.is_control_plane??!1,o=e?.workers??[],[l,s]=(0,t.useState)(()=>localStorage.getItem(r));(0,t.useEffect)(()=>{if(!l||0===o.length)return;let e=o.find(e=>e.worker_id===l);e&&(0,a.switchToWorkerUrl)(e.url)},[l,o]);let p=o.find(e=>e.worker_id===l)??null,c=(0,t.useCallback)(e=>{let t=o.find(t=>t.worker_id===e);t&&(s(e),localStorage.setItem(r,e),(0,a.switchToWorkerUrl)(t.url))},[o]);return{isControlPlane:n,workers:o,selectedWorkerId:l,selectedWorker:p,selectWorker:c,disconnectFromWorker:(0,t.useCallback)(()=>{s(null),localStorage.removeItem(r),(0,a.switchToWorkerUrl)(null)},[])}}])},295320,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M704 446H320c-4.4 0-8 3.6-8 8v402c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8V454c0-4.4-3.6-8-8-8zm-328 64h272v117H376V510zm272 290H376V683h272v117z"}},{tag:"path",attrs:{d:"M424 748a32 32 0 1064 0 32 32 0 10-64 0zm0-178a32 32 0 1064 0 32 32 0 10-64 0z"}},{tag:"path",attrs:{d:"M811.4 368.9C765.6 248 648.9 162 512.2 162S258.8 247.9 213 368.8C126.9 391.5 63.5 470.2 64 563.6 64.6 668 145.6 752.9 247.6 762c4.7.4 8.7-3.3 8.7-8v-60.4c0-4-3-7.4-7-7.9-27-3.4-52.5-15.2-72.1-34.5-24-23.5-37.2-55.1-37.2-88.6 0-28 9.1-54.4 26.2-76.4 16.7-21.4 40.2-36.9 66.1-43.7l37.9-10 13.9-36.7c8.6-22.8 20.6-44.2 35.7-63.5 14.9-19.2 32.6-36 52.4-50 41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.3c19.9 14 37.5 30.8 52.4 50 15.1 19.3 27.1 40.7 35.7 63.5l13.8 36.6 37.8 10c54.2 14.4 92.1 63.7 92.1 120 0 33.6-13.2 65.1-37.2 88.6-19.5 19.2-44.9 31.1-71.9 34.5-4 .5-6.9 3.9-6.9 7.9V754c0 4.7 4.1 8.4 8.8 8 101.7-9.2 182.5-94 183.2-198.2.6-93.4-62.7-172.1-148.6-194.9z"}}]},name:"cloud-server",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["CloudServerOutlined",0,n],295320)},190272,785913,e=>{"use strict";var t,a,i=((t={}).AUDIO_SPEECH="audio_speech",t.AUDIO_TRANSCRIPTION="audio_transcription",t.IMAGE_GENERATION="image_generation",t.VIDEO_GENERATION="video_generation",t.CHAT="chat",t.RESPONSES="responses",t.IMAGE_EDITS="image_edits",t.ANTHROPIC_MESSAGES="anthropic_messages",t.EMBEDDING="embedding",t),r=((a={}).IMAGE="image",a.VIDEO="video",a.CHAT="chat",a.RESPONSES="responses",a.IMAGE_EDITS="image_edits",a.ANTHROPIC_MESSAGES="anthropic_messages",a.EMBEDDINGS="embeddings",a.SPEECH="speech",a.TRANSCRIPTION="transcription",a.A2A_AGENTS="a2a_agents",a.MCP="mcp",a.REALTIME="realtime",a.INTERACTIONS="interactions",a);let n={image_generation:"image",video_generation:"video",chat:"chat",responses:"responses",image_edits:"image_edits",anthropic_messages:"anthropic_messages",audio_speech:"speech",audio_transcription:"transcription",embedding:"embeddings"};e.s(["EndpointType",()=>r,"getEndpointType",0,e=>{if(console.log("getEndpointType:",e),Object.values(i).includes(e)){let t=n[e];return console.log("endpointType:",t),t}return"chat"}],785913),e.s(["generateCodeSnippet",0,e=>{let t,{apiKeySource:a,accessToken:i,apiKey:n,inputMessage:o,chatHistory:l,selectedTags:s,selectedVectorStores:p,selectedGuardrails:c,selectedPolicies:g,selectedMCPServers:u,mcpServers:d,mcpServerToolRestrictions:m,selectedVoice:f,endpointType:_,selectedModel:h,selectedSdk:b,proxySettings:A}=e,v="session"===a?i:n,O=window.location.origin,I=A?.LITELLM_UI_API_DOC_BASE_URL;I&&I.trim()?O=I:A?.PROXY_BASE_URL&&(O=A.PROXY_BASE_URL);let $=o||"Your prompt here",E=$.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n"),C=l.filter(e=>!e.isImage).map(({role:e,content:t})=>({role:e,content:t})),y={};s.length>0&&(y.tags=s),p.length>0&&(y.vector_stores=p),c.length>0&&(y.guardrails=c),g.length>0&&(y.policies=g);let x=h||"your-model-name",T="azure"===b?`import openai | ||
| `]:Object.assign({},{background:e.skeletonLoadingBackground,backgroundSize:"400% 100%",animationName:c,animationDuration:e.skeletonLoadingMotionDuration,animationTimingFunction:"ease",animationIterationCount:"infinite"})}}})((0,p.mergeToken)(e,{skeletonAvatarCls:`${t}-avatar`,skeletonTitleCls:`${t}-title`,skeletonParagraphCls:`${t}-paragraph`,skeletonButtonCls:`${t}-button`,skeletonInputCls:`${t}-input`,skeletonImageCls:`${t}-image`,imageSizeBase:a(e.controlHeight).mul(1.5).equal(),borderRadius:100,skeletonLoadingBackground:`linear-gradient(90deg, ${e.gradientFromColor} 25%, ${e.gradientToColor} 37%, ${e.gradientFromColor} 63%)`,skeletonLoadingMotionDuration:"1.4s"}))},e=>{let{colorFillContent:t,colorFill:a}=e;return{color:t,colorGradientEnd:a,gradientFromColor:t,gradientToColor:a,titleHeight:e.controlHeight/2,blockRadius:e.borderRadiusSM,paragraphMarginTop:e.marginLG+e.marginXXS,paragraphLiHeight:e.controlHeight/2}},{deprecatedTokens:[["color","gradientFromColor"],["colorGradientEnd","gradientToColor"]]}),b=e=>{let{prefixCls:i,className:r,style:n,rows:o=0}=e,l=Array.from({length:o}).map((a,i)=>t.createElement("li",{key:i,style:{width:((e,t)=>{let{width:a,rows:i=2}=t;return Array.isArray(a)?a[e]:i-1===e?a:void 0})(i,e)}}));return t.createElement("ul",{className:(0,a.default)(i,r),style:n},l)},A=({prefixCls:e,className:i,width:r,style:n})=>t.createElement("h3",{className:(0,a.default)(e,i),style:Object.assign({width:r},n)});function v(e){return e&&"object"==typeof e?e:{}}let O=e=>{let{prefixCls:r,loading:o,className:l,rootClassName:s,style:p,children:c,avatar:g=!1,title:u=!0,paragraph:d=!0,active:m,round:f}=e,{getPrefixCls:_,direction:O,className:I,style:$}=(0,i.useComponentConfig)("skeleton"),E=_("skeleton",r),[C,y,x]=h(E);if(o||!("loading"in e)){let e,i,r=!!g,o=!!u,c=!!d;if(r){let a=Object.assign(Object.assign({prefixCls:`${E}-avatar`},o&&!c?{size:"large",shape:"square"}:{size:"large",shape:"circle"}),v(g));e=t.createElement("div",{className:`${E}-header`},t.createElement(n,Object.assign({},a)))}if(o||c){let e,a;if(o){let a=Object.assign(Object.assign({prefixCls:`${E}-title`},!r&&c?{width:"38%"}:r&&c?{width:"50%"}:{}),v(u));e=t.createElement(A,Object.assign({},a))}if(c){let e,i=Object.assign(Object.assign({prefixCls:`${E}-paragraph`},(e={},r&&o||(e.width="61%"),!r&&o?e.rows=3:e.rows=2,e)),v(d));a=t.createElement(b,Object.assign({},i))}i=t.createElement("div",{className:`${E}-content`},e,a)}let _=(0,a.default)(E,{[`${E}-with-avatar`]:r,[`${E}-active`]:m,[`${E}-rtl`]:"rtl"===O,[`${E}-round`]:f},I,l,s,y,x);return C(t.createElement("div",{className:_,style:Object.assign(Object.assign({},$),p)},e,i))}return null!=c?c:null};O.Button=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,block:c=!1,size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p,[`${d}-block`]:c},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-button`,size:g},b))))},O.Avatar=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,shape:c="circle",size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls","className"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-avatar`,shape:c,size:g},b))))},O.Input=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,block:c,size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p,[`${d}-block`]:c},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-input`,size:g},b))))},O.Image=e=>{let{prefixCls:r,className:n,rootClassName:o,style:l,active:s}=e,{getPrefixCls:p}=t.useContext(i.ConfigContext),c=p("skeleton",r),[g,u,d]=h(c),m=(0,a.default)(c,`${c}-element`,{[`${c}-active`]:s},n,o,u,d);return g(t.createElement("div",{className:m},t.createElement("div",{className:(0,a.default)(`${c}-image`,n),style:l},t.createElement("svg",{viewBox:"0 0 1098 1024",xmlns:"http://www.w3.org/2000/svg",className:`${c}-image-svg`},t.createElement("title",null,"Image placeholder"),t.createElement("path",{d:"M365.714286 329.142857q0 45.714286-32.036571 77.677714t-77.677714 32.036571-77.677714-32.036571-32.036571-77.677714 32.036571-77.677714 77.677714-32.036571 77.677714 32.036571 32.036571 77.677714zM950.857143 548.571429l0 256-804.571429 0 0-109.714286 182.857143-182.857143 91.428571 91.428571 292.571429-292.571429zM1005.714286 146.285714l-914.285714 0q-7.460571 0-12.873143 5.412571t-5.412571 12.873143l0 694.857143q0 7.460571 5.412571 12.873143t12.873143 5.412571l914.285714 0q7.460571 0 12.873143-5.412571t5.412571-12.873143l0-694.857143q0-7.460571-5.412571-12.873143t-12.873143-5.412571zM1097.142857 164.571429l0 694.857143q0 37.741714-26.843429 64.585143t-64.585143 26.843429l-914.285714 0q-37.741714 0-64.585143-26.843429t-26.843429-64.585143l0-694.857143q0-37.741714 26.843429-64.585143t64.585143-26.843429l914.285714 0q37.741714 0 64.585143 26.843429t26.843429 64.585143z",className:`${c}-image-path`})))))},O.Node=e=>{let{prefixCls:r,className:n,rootClassName:o,style:l,active:s,children:p}=e,{getPrefixCls:c}=t.useContext(i.ConfigContext),g=c("skeleton",r),[u,d,m]=h(g),f=(0,a.default)(g,`${g}-element`,{[`${g}-active`]:s},d,n,o,m);return u(t.createElement("div",{className:f},t.createElement("div",{className:(0,a.default)(`${g}-image`,n),style:l},p)))},e.s(["default",0,O],185793)},959013,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"}},{tag:"path",attrs:{d:"M192 474h672q8 0 8 8v60q0 8-8 8H160q-8 0-8-8v-60q0-8 8-8z"}}]},name:"plus",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["default",0,n],959013)},282786,836938,310730,829672,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),i=e.i(914949),r=e.i(404948);let n=e=>e?"function"==typeof e?e():e:null;e.s(["getRenderPropValue",0,n],836938);var o=e.i(613541),l=e.i(763731),s=e.i(242064),p=e.i(491816);e.i(793154);var c=e.i(880476),g=e.i(183293),u=e.i(717356),d=e.i(320560),m=e.i(307358),f=e.i(246422),_=e.i(838378),h=e.i(617933);let b=(0,f.genStyleHooks)("Popover",e=>{let{colorBgElevated:t,colorText:a}=e,i=(0,_.mergeToken)(e,{popoverBg:t,popoverColor:a});return[(e=>{let{componentCls:t,popoverColor:a,titleMinWidth:i,fontWeightStrong:r,innerPadding:n,boxShadowSecondary:o,colorTextHeading:l,borderRadiusLG:s,zIndexPopup:p,titleMarginBottom:c,colorBgElevated:u,popoverBg:m,titleBorderBottom:f,innerContentPadding:_,titlePadding:h}=e;return[{[t]:Object.assign(Object.assign({},(0,g.resetComponent)(e)),{position:"absolute",top:0,left:{_skip_check_:!0,value:0},zIndex:p,fontWeight:"normal",whiteSpace:"normal",textAlign:"start",cursor:"auto",userSelect:"text","--valid-offset-x":"var(--arrow-offset-horizontal, var(--arrow-x))",transformOrigin:"var(--valid-offset-x, 50%) var(--arrow-y, 50%)","--antd-arrow-background-color":u,width:"max-content",maxWidth:"100vw","&-rtl":{direction:"rtl"},"&-hidden":{display:"none"},[`${t}-content`]:{position:"relative"},[`${t}-inner`]:{backgroundColor:m,backgroundClip:"padding-box",borderRadius:s,boxShadow:o,padding:n},[`${t}-title`]:{minWidth:i,marginBottom:c,color:l,fontWeight:r,borderBottom:f,padding:h},[`${t}-inner-content`]:{color:a,padding:_}})},(0,d.default)(e,"var(--antd-arrow-background-color)"),{[`${t}-pure`]:{position:"relative",maxWidth:"none",margin:e.sizePopupArrow,display:"inline-block",[`${t}-content`]:{display:"inline-block"}}}]})(i),(e=>{let{componentCls:t}=e;return{[t]:h.PresetColors.map(a=>{let i=e[`${a}6`];return{[`&${t}-${a}`]:{"--antd-arrow-background-color":i,[`${t}-inner`]:{backgroundColor:i},[`${t}-arrow`]:{background:"transparent"}}}})}})(i),(0,u.initZoomMotion)(i,"zoom-big")]},e=>{let{lineWidth:t,controlHeight:a,fontHeight:i,padding:r,wireframe:n,zIndexPopupBase:o,borderRadiusLG:l,marginXS:s,lineType:p,colorSplit:c,paddingSM:g}=e,u=a-i;return Object.assign(Object.assign(Object.assign({titleMinWidth:177,zIndexPopup:o+30},(0,m.getArrowToken)(e)),(0,d.getArrowOffsetToken)({contentRadius:l,limitVerticalRadius:!0})),{innerPadding:12*!n,titleMarginBottom:n?0:s,titlePadding:n?`${u/2}px ${r}px ${u/2-t}px`:0,titleBorderBottom:n?`${t}px ${p} ${c}`:"none",innerContentPadding:n?`${g}px ${r}px`:0})},{resetStyle:!1,deprecatedTokens:[["width","titleMinWidth"],["minWidth","titleMinWidth"]]});var A=function(e,t){var a={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(a[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,i=Object.getOwnPropertySymbols(e);r<i.length;r++)0>t.indexOf(i[r])&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(a[i[r]]=e[i[r]]);return a};let v=({title:e,content:a,prefixCls:i})=>e||a?t.createElement(t.Fragment,null,e&&t.createElement("div",{className:`${i}-title`},e),a&&t.createElement("div",{className:`${i}-inner-content`},a)):null,O=e=>{let{hashId:i,prefixCls:r,className:o,style:l,placement:s="top",title:p,content:g,children:u}=e,d=n(p),m=n(g),f=(0,a.default)(i,r,`${r}-pure`,`${r}-placement-${s}`,o);return t.createElement("div",{className:f,style:l},t.createElement("div",{className:`${r}-arrow`}),t.createElement(c.Popup,Object.assign({},e,{className:i,prefixCls:r}),u||t.createElement(v,{prefixCls:r,title:d,content:m})))},I=e=>{let{prefixCls:i,className:r}=e,n=A(e,["prefixCls","className"]),{getPrefixCls:o}=t.useContext(s.ConfigContext),l=o("popover",i),[p,c,g]=b(l);return p(t.createElement(O,Object.assign({},n,{prefixCls:l,hashId:c,className:(0,a.default)(r,g)})))};e.s(["Overlay",0,v,"default",0,I],310730);var $=function(e,t){var a={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(a[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,i=Object.getOwnPropertySymbols(e);r<i.length;r++)0>t.indexOf(i[r])&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(a[i[r]]=e[i[r]]);return a};let E=t.forwardRef((e,c)=>{var g,u;let{prefixCls:d,title:m,content:f,overlayClassName:_,placement:h="top",trigger:A="hover",children:O,mouseEnterDelay:I=.1,mouseLeaveDelay:E=.1,onOpenChange:C,overlayStyle:y={},styles:x,classNames:T}=e,k=$(e,["prefixCls","title","content","overlayClassName","placement","trigger","children","mouseEnterDelay","mouseLeaveDelay","onOpenChange","overlayStyle","styles","classNames"]),{getPrefixCls:w,className:L,style:S,classNames:M,styles:R}=(0,s.useComponentConfig)("popover"),j=w("popover",d),[N,P,D]=b(j),z=w(),H=(0,a.default)(_,P,D,L,M.root,null==T?void 0:T.root),B=(0,a.default)(M.body,null==T?void 0:T.body),[G,V]=(0,i.default)(!1,{value:null!=(g=e.open)?g:e.visible,defaultValue:null!=(u=e.defaultOpen)?u:e.defaultVisible}),F=(e,t)=>{V(e,!0),null==C||C(e,t)},q=n(m),U=n(f);return N(t.createElement(p.default,Object.assign({placement:h,trigger:A,mouseEnterDelay:I,mouseLeaveDelay:E},k,{prefixCls:j,classNames:{root:H,body:B},styles:{root:Object.assign(Object.assign(Object.assign(Object.assign({},R.root),S),y),null==x?void 0:x.root),body:Object.assign(Object.assign({},R.body),null==x?void 0:x.body)},ref:c,open:G,onOpenChange:e=>{F(e)},overlay:q||U?t.createElement(v,{prefixCls:j,title:q,content:U}):null,transitionName:(0,o.getTransitionName)(z,"zoom-big",k.transitionName),"data-popover-inject":!0}),(0,l.cloneElement)(O,{onKeyDown:e=>{var a,i;(0,t.isValidElement)(O)&&(null==(i=null==O?void 0:(a=O.props).onKeyDown)||i.call(a,e)),e.keyCode===r.default.ESC&&F(!1,e)}})))});E._InternalPanelDoNotUseOrYouWillBeFired=I,e.s(["default",0,E],829672),e.s(["Popover",0,E],282786)},166406,e=>{"use strict";var t=e.i(190144);e.s(["CopyOutlined",()=>t.default])},447566,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 000 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"}}]},name:"arrow-left",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["ArrowLeftOutlined",0,n],447566)},492030,e=>{"use strict";var t=e.i(121229);e.s(["CheckOutlined",()=>t.default])},596239,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M574 665.4a8.03 8.03 0 00-11.3 0L446.5 781.6c-53.8 53.8-144.6 59.5-204 0-59.5-59.5-53.8-150.2 0-204l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3l-39.8-39.8a8.03 8.03 0 00-11.3 0L191.4 526.5c-84.6 84.6-84.6 221.5 0 306s221.5 84.6 306 0l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3L574 665.4zm258.6-474c-84.6-84.6-221.5-84.6-306 0L410.3 307.6a8.03 8.03 0 000 11.3l39.7 39.7c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c53.8-53.8 144.6-59.5 204 0 59.5 59.5 53.8 150.2 0 204L665.3 562.6a8.03 8.03 0 000 11.3l39.8 39.8c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c84.5-84.6 84.5-221.5 0-306.1zM610.1 372.3a8.03 8.03 0 00-11.3 0L372.3 598.7a8.03 8.03 0 000 11.3l39.6 39.6c3.1 3.1 8.2 3.1 11.3 0l226.4-226.4c3.1-3.1 3.1-8.2 0-11.3l-39.5-39.6z"}}]},name:"link",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["LinkOutlined",0,n],596239)},326373,e=>{"use strict";var t=e.i(21539);e.s(["Dropdown",()=>t.default])},755151,e=>{"use strict";var t=e.i(247153);e.s(["DownOutlined",()=>t.default])},62478,e=>{"use strict";var t=e.i(602869);let a=async e=>{if(!e)return null;try{return await (0,t.getProxyUISettings)(e)}catch(e){return console.error("Error fetching proxy settings:",e),null}};e.s(["fetchProxySettings",0,a])},818581,(e,t,a)=>{"use strict";Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"useMergedRef",{enumerable:!0,get:function(){return r}});let i=e.r(271645);function r(e,t){let a=(0,i.useRef)(null),r=(0,i.useRef)(null);return(0,i.useCallback)(i=>{if(null===i){let e=a.current;e&&(a.current=null,e());let t=r.current;t&&(r.current=null,t())}else e&&(a.current=n(e,i)),t&&(r.current=n(t,i))},[e,t])}function n(e,t){if("function"!=typeof e)return e.current=t,()=>{e.current=null};{let a=e(t);return"function"==typeof a?a:()=>e(null)}}("function"==typeof a.default||"object"==typeof a.default&&null!==a.default)&&void 0===a.default.__esModule&&(Object.defineProperty(a.default,"__esModule",{value:!0}),Object.assign(a.default,a),t.exports=a.default)},602073,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64L128 192v384c0 212.1 171.9 384 384 384s384-171.9 384-384V192L512 64zm312 512c0 172.3-139.7 312-312 312S200 748.3 200 576V246l312-110 312 110v330z"}},{tag:"path",attrs:{d:"M378.4 475.1a35.91 35.91 0 00-50.9 0 35.91 35.91 0 000 50.9l129.4 129.4 2.1 2.1a33.98 33.98 0 0048.1 0L730.6 434a33.98 33.98 0 000-48.1l-2.8-2.8a33.98 33.98 0 00-48.1 0L483 579.7 378.4 475.1z"}}]},name:"safety",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["SafetyOutlined",0,n],602073)},44121,186515,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 000 13.8z"}}]},name:"menu-fold",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["MenuFoldOutlined",0,n],44121);let o={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 000-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0014.4 7z"}}]},name:"menu-unfold",theme:"outlined"};var l=a.forwardRef(function(e,i){return a.createElement(r.default,(0,t.default)({},e,{ref:i,icon:o}))});e.s(["MenuUnfoldOutlined",0,l],186515)},928685,e=>{"use strict";var t=e.i(38953);e.s(["SearchOutlined",()=>t.default])},283713,e=>{"use strict";var t=e.i(271645),a=e.i(602869),i=e.i(612256);let r="litellm_selected_worker_id";e.s(["useWorker",0,()=>{let{data:e}=(0,i.useUIConfig)(),n=e?.is_control_plane??!1,o=e?.workers??[],[l,s]=(0,t.useState)(()=>localStorage.getItem(r));(0,t.useEffect)(()=>{if(!l||0===o.length)return;let e=o.find(e=>e.worker_id===l);e&&(0,a.switchToWorkerUrl)(e.url)},[l,o]);let p=o.find(e=>e.worker_id===l)??null,c=(0,t.useCallback)(e=>{let t=o.find(t=>t.worker_id===e);t&&(s(e),localStorage.setItem(r,e),(0,a.switchToWorkerUrl)(t.url))},[o]);return{isControlPlane:n,workers:o,selectedWorkerId:l,selectedWorker:p,selectWorker:c,disconnectFromWorker:(0,t.useCallback)(()=>{s(null),localStorage.removeItem(r),(0,a.switchToWorkerUrl)(null)},[])}}])},295320,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M704 446H320c-4.4 0-8 3.6-8 8v402c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8V454c0-4.4-3.6-8-8-8zm-328 64h272v117H376V510zm272 290H376V683h272v117z"}},{tag:"path",attrs:{d:"M424 748a32 32 0 1064 0 32 32 0 10-64 0zm0-178a32 32 0 1064 0 32 32 0 10-64 0z"}},{tag:"path",attrs:{d:"M811.4 368.9C765.6 248 648.9 162 512.2 162S258.8 247.9 213 368.8C126.9 391.5 63.5 470.2 64 563.6 64.6 668 145.6 752.9 247.6 762c4.7.4 8.7-3.3 8.7-8v-60.4c0-4-3-7.4-7-7.9-27-3.4-52.5-15.2-72.1-34.5-24-23.5-37.2-55.1-37.2-88.6 0-28 9.1-54.4 26.2-76.4 16.7-21.4 40.2-36.9 66.1-43.7l37.9-10 13.9-36.7c8.6-22.8 20.6-44.2 35.7-63.5 14.9-19.2 32.6-36 52.4-50 41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.3c19.9 14 37.5 30.8 52.4 50 15.1 19.3 27.1 40.7 35.7 63.5l13.8 36.6 37.8 10c54.2 14.4 92.1 63.7 92.1 120 0 33.6-13.2 65.1-37.2 88.6-19.5 19.2-44.9 31.1-71.9 34.5-4 .5-6.9 3.9-6.9 7.9V754c0 4.7 4.1 8.4 8.8 8 101.7-9.2 182.5-94 183.2-198.2.6-93.4-62.7-172.1-148.6-194.9z"}}]},name:"cloud-server",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["CloudServerOutlined",0,n],295320)},190272,785913,e=>{"use strict";var t,a,i=((t={}).AUDIO_SPEECH="audio_speech",t.AUDIO_TRANSCRIPTION="audio_transcription",t.IMAGE_GENERATION="image_generation",t.VIDEO_GENERATION="video_generation",t.CHAT="chat",t.RESPONSES="responses",t.IMAGE_EDITS="image_edits",t.ANTHROPIC_MESSAGES="anthropic_messages",t.EMBEDDING="embedding",t),r=((a={}).IMAGE="image",a.VIDEO="video",a.CHAT="chat",a.RESPONSES="responses",a.IMAGE_EDITS="image_edits",a.ANTHROPIC_MESSAGES="anthropic_messages",a.EMBEDDINGS="embeddings",a.SPEECH="speech",a.TRANSCRIPTION="transcription",a.A2A_AGENTS="a2a_agents",a.MCP="mcp",a.REALTIME="realtime",a.INTERACTIONS="interactions",a);let n={image_generation:"image",video_generation:"video",chat:"chat",responses:"responses",image_edits:"image_edits",anthropic_messages:"anthropic_messages",audio_speech:"speech",audio_transcription:"transcription",embedding:"embeddings"};e.s(["EndpointType",()=>r,"getEndpointType",0,e=>{if(console.log("getEndpointType:",e),Object.values(i).includes(e)){let t=n[e];return console.log("endpointType:",t),t}return"chat"}],785913),e.s(["generateCodeSnippet",0,e=>{let t,{apiKeySource:a,accessToken:i,apiKey:n,inputMessage:o,chatHistory:l,selectedTags:s,selectedVectorStores:p,selectedGuardrails:c,selectedPolicies:g,selectedMCPServers:u,mcpServers:d,mcpServerToolRestrictions:m,selectedVoice:f,endpointType:_,selectedModel:h,selectedSdk:b,proxySettings:A}=e,v="session"===a?i:n,O=window.location.origin,I=A?.LITELLM_UI_API_DOC_BASE_URL;I&&I.trim()?O=I:A?.PROXY_BASE_URL&&(O=A.PROXY_BASE_URL);let $=o||"Your prompt here",E=$.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n"),C=l.filter(e=>!e.isImage).map(({role:e,content:t})=>({role:e,content:t})),y={};s.length>0&&(y.tags=s),p.length>0&&(y.vector_stores=p),c.length>0&&(y.guardrails=c),g.length>0&&(y.policies=g);let x=h||"your-model-name",T="azure"===b?`import openai |
| ${i}, | ||
| ${r} > li, | ||
| ${a}, | ||
| ${n}, | ||
| ${o}, | ||
| ${l} | ||
| `]:Object.assign({},{background:e.skeletonLoadingBackground,backgroundSize:"400% 100%",animationName:c,animationDuration:e.skeletonLoadingMotionDuration,animationTimingFunction:"ease",animationIterationCount:"infinite"})}}})((0,p.mergeToken)(e,{skeletonAvatarCls:`${t}-avatar`,skeletonTitleCls:`${t}-title`,skeletonParagraphCls:`${t}-paragraph`,skeletonButtonCls:`${t}-button`,skeletonInputCls:`${t}-input`,skeletonImageCls:`${t}-image`,imageSizeBase:a(e.controlHeight).mul(1.5).equal(),borderRadius:100,skeletonLoadingBackground:`linear-gradient(90deg, ${e.gradientFromColor} 25%, ${e.gradientToColor} 37%, ${e.gradientFromColor} 63%)`,skeletonLoadingMotionDuration:"1.4s"}))},e=>{let{colorFillContent:t,colorFill:a}=e;return{color:t,colorGradientEnd:a,gradientFromColor:t,gradientToColor:a,titleHeight:e.controlHeight/2,blockRadius:e.borderRadiusSM,paragraphMarginTop:e.marginLG+e.marginXXS,paragraphLiHeight:e.controlHeight/2}},{deprecatedTokens:[["color","gradientFromColor"],["colorGradientEnd","gradientToColor"]]}),b=e=>{let{prefixCls:i,className:r,style:n,rows:o=0}=e,l=Array.from({length:o}).map((a,i)=>t.createElement("li",{key:i,style:{width:((e,t)=>{let{width:a,rows:i=2}=t;return Array.isArray(a)?a[e]:i-1===e?a:void 0})(i,e)}}));return t.createElement("ul",{className:(0,a.default)(i,r),style:n},l)},A=({prefixCls:e,className:i,width:r,style:n})=>t.createElement("h3",{className:(0,a.default)(e,i),style:Object.assign({width:r},n)});function v(e){return e&&"object"==typeof e?e:{}}let O=e=>{let{prefixCls:r,loading:o,className:l,rootClassName:s,style:p,children:c,avatar:g=!1,title:u=!0,paragraph:d=!0,active:m,round:f}=e,{getPrefixCls:_,direction:O,className:I,style:$}=(0,i.useComponentConfig)("skeleton"),E=_("skeleton",r),[C,y,x]=h(E);if(o||!("loading"in e)){let e,i,r=!!g,o=!!u,c=!!d;if(r){let a=Object.assign(Object.assign({prefixCls:`${E}-avatar`},o&&!c?{size:"large",shape:"square"}:{size:"large",shape:"circle"}),v(g));e=t.createElement("div",{className:`${E}-header`},t.createElement(n,Object.assign({},a)))}if(o||c){let e,a;if(o){let a=Object.assign(Object.assign({prefixCls:`${E}-title`},!r&&c?{width:"38%"}:r&&c?{width:"50%"}:{}),v(u));e=t.createElement(A,Object.assign({},a))}if(c){let e,i=Object.assign(Object.assign({prefixCls:`${E}-paragraph`},(e={},r&&o||(e.width="61%"),!r&&o?e.rows=3:e.rows=2,e)),v(d));a=t.createElement(b,Object.assign({},i))}i=t.createElement("div",{className:`${E}-content`},e,a)}let _=(0,a.default)(E,{[`${E}-with-avatar`]:r,[`${E}-active`]:m,[`${E}-rtl`]:"rtl"===O,[`${E}-round`]:f},I,l,s,y,x);return C(t.createElement("div",{className:_,style:Object.assign(Object.assign({},$),p)},e,i))}return null!=c?c:null};O.Button=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,block:c=!1,size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p,[`${d}-block`]:c},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-button`,size:g},b))))},O.Avatar=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,shape:c="circle",size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls","className"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-avatar`,shape:c,size:g},b))))},O.Input=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,block:c,size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p,[`${d}-block`]:c},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-input`,size:g},b))))},O.Image=e=>{let{prefixCls:r,className:n,rootClassName:o,style:l,active:s}=e,{getPrefixCls:p}=t.useContext(i.ConfigContext),c=p("skeleton",r),[g,u,d]=h(c),m=(0,a.default)(c,`${c}-element`,{[`${c}-active`]:s},n,o,u,d);return g(t.createElement("div",{className:m},t.createElement("div",{className:(0,a.default)(`${c}-image`,n),style:l},t.createElement("svg",{viewBox:"0 0 1098 1024",xmlns:"http://www.w3.org/2000/svg",className:`${c}-image-svg`},t.createElement("title",null,"Image placeholder"),t.createElement("path",{d:"M365.714286 329.142857q0 45.714286-32.036571 77.677714t-77.677714 32.036571-77.677714-32.036571-32.036571-77.677714 32.036571-77.677714 77.677714-32.036571 77.677714 32.036571 32.036571 77.677714zM950.857143 548.571429l0 256-804.571429 0 0-109.714286 182.857143-182.857143 91.428571 91.428571 292.571429-292.571429zM1005.714286 146.285714l-914.285714 0q-7.460571 0-12.873143 5.412571t-5.412571 12.873143l0 694.857143q0 7.460571 5.412571 12.873143t12.873143 5.412571l914.285714 0q7.460571 0 12.873143-5.412571t5.412571-12.873143l0-694.857143q0-7.460571-5.412571-12.873143t-12.873143-5.412571zM1097.142857 164.571429l0 694.857143q0 37.741714-26.843429 64.585143t-64.585143 26.843429l-914.285714 0q-37.741714 0-64.585143-26.843429t-26.843429-64.585143l0-694.857143q0-37.741714 26.843429-64.585143t64.585143-26.843429l914.285714 0q37.741714 0 64.585143 26.843429t26.843429 64.585143z",className:`${c}-image-path`})))))},O.Node=e=>{let{prefixCls:r,className:n,rootClassName:o,style:l,active:s,children:p}=e,{getPrefixCls:c}=t.useContext(i.ConfigContext),g=c("skeleton",r),[u,d,m]=h(g),f=(0,a.default)(g,`${g}-element`,{[`${g}-active`]:s},d,n,o,m);return u(t.createElement("div",{className:f},t.createElement("div",{className:(0,a.default)(`${g}-image`,n),style:l},p)))},e.s(["default",0,O],185793)},959013,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"}},{tag:"path",attrs:{d:"M192 474h672q8 0 8 8v60q0 8-8 8H160q-8 0-8-8v-60q0-8 8-8z"}}]},name:"plus",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["default",0,n],959013)},282786,836938,310730,829672,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),i=e.i(914949),r=e.i(404948);let n=e=>e?"function"==typeof e?e():e:null;e.s(["getRenderPropValue",0,n],836938);var o=e.i(613541),l=e.i(763731),s=e.i(242064),p=e.i(491816);e.i(793154);var c=e.i(880476),g=e.i(183293),u=e.i(717356),d=e.i(320560),m=e.i(307358),f=e.i(246422),_=e.i(838378),h=e.i(617933);let b=(0,f.genStyleHooks)("Popover",e=>{let{colorBgElevated:t,colorText:a}=e,i=(0,_.mergeToken)(e,{popoverBg:t,popoverColor:a});return[(e=>{let{componentCls:t,popoverColor:a,titleMinWidth:i,fontWeightStrong:r,innerPadding:n,boxShadowSecondary:o,colorTextHeading:l,borderRadiusLG:s,zIndexPopup:p,titleMarginBottom:c,colorBgElevated:u,popoverBg:m,titleBorderBottom:f,innerContentPadding:_,titlePadding:h}=e;return[{[t]:Object.assign(Object.assign({},(0,g.resetComponent)(e)),{position:"absolute",top:0,left:{_skip_check_:!0,value:0},zIndex:p,fontWeight:"normal",whiteSpace:"normal",textAlign:"start",cursor:"auto",userSelect:"text","--valid-offset-x":"var(--arrow-offset-horizontal, var(--arrow-x))",transformOrigin:"var(--valid-offset-x, 50%) var(--arrow-y, 50%)","--antd-arrow-background-color":u,width:"max-content",maxWidth:"100vw","&-rtl":{direction:"rtl"},"&-hidden":{display:"none"},[`${t}-content`]:{position:"relative"},[`${t}-inner`]:{backgroundColor:m,backgroundClip:"padding-box",borderRadius:s,boxShadow:o,padding:n},[`${t}-title`]:{minWidth:i,marginBottom:c,color:l,fontWeight:r,borderBottom:f,padding:h},[`${t}-inner-content`]:{color:a,padding:_}})},(0,d.default)(e,"var(--antd-arrow-background-color)"),{[`${t}-pure`]:{position:"relative",maxWidth:"none",margin:e.sizePopupArrow,display:"inline-block",[`${t}-content`]:{display:"inline-block"}}}]})(i),(e=>{let{componentCls:t}=e;return{[t]:h.PresetColors.map(a=>{let i=e[`${a}6`];return{[`&${t}-${a}`]:{"--antd-arrow-background-color":i,[`${t}-inner`]:{backgroundColor:i},[`${t}-arrow`]:{background:"transparent"}}}})}})(i),(0,u.initZoomMotion)(i,"zoom-big")]},e=>{let{lineWidth:t,controlHeight:a,fontHeight:i,padding:r,wireframe:n,zIndexPopupBase:o,borderRadiusLG:l,marginXS:s,lineType:p,colorSplit:c,paddingSM:g}=e,u=a-i;return Object.assign(Object.assign(Object.assign({titleMinWidth:177,zIndexPopup:o+30},(0,m.getArrowToken)(e)),(0,d.getArrowOffsetToken)({contentRadius:l,limitVerticalRadius:!0})),{innerPadding:12*!n,titleMarginBottom:n?0:s,titlePadding:n?`${u/2}px ${r}px ${u/2-t}px`:0,titleBorderBottom:n?`${t}px ${p} ${c}`:"none",innerContentPadding:n?`${g}px ${r}px`:0})},{resetStyle:!1,deprecatedTokens:[["width","titleMinWidth"],["minWidth","titleMinWidth"]]});var A=function(e,t){var a={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(a[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,i=Object.getOwnPropertySymbols(e);r<i.length;r++)0>t.indexOf(i[r])&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(a[i[r]]=e[i[r]]);return a};let v=({title:e,content:a,prefixCls:i})=>e||a?t.createElement(t.Fragment,null,e&&t.createElement("div",{className:`${i}-title`},e),a&&t.createElement("div",{className:`${i}-inner-content`},a)):null,O=e=>{let{hashId:i,prefixCls:r,className:o,style:l,placement:s="top",title:p,content:g,children:u}=e,d=n(p),m=n(g),f=(0,a.default)(i,r,`${r}-pure`,`${r}-placement-${s}`,o);return t.createElement("div",{className:f,style:l},t.createElement("div",{className:`${r}-arrow`}),t.createElement(c.Popup,Object.assign({},e,{className:i,prefixCls:r}),u||t.createElement(v,{prefixCls:r,title:d,content:m})))},I=e=>{let{prefixCls:i,className:r}=e,n=A(e,["prefixCls","className"]),{getPrefixCls:o}=t.useContext(s.ConfigContext),l=o("popover",i),[p,c,g]=b(l);return p(t.createElement(O,Object.assign({},n,{prefixCls:l,hashId:c,className:(0,a.default)(r,g)})))};e.s(["Overlay",0,v,"default",0,I],310730);var $=function(e,t){var a={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(a[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,i=Object.getOwnPropertySymbols(e);r<i.length;r++)0>t.indexOf(i[r])&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(a[i[r]]=e[i[r]]);return a};let E=t.forwardRef((e,c)=>{var g,u;let{prefixCls:d,title:m,content:f,overlayClassName:_,placement:h="top",trigger:A="hover",children:O,mouseEnterDelay:I=.1,mouseLeaveDelay:E=.1,onOpenChange:C,overlayStyle:y={},styles:x,classNames:T}=e,k=$(e,["prefixCls","title","content","overlayClassName","placement","trigger","children","mouseEnterDelay","mouseLeaveDelay","onOpenChange","overlayStyle","styles","classNames"]),{getPrefixCls:w,className:L,style:S,classNames:M,styles:R}=(0,s.useComponentConfig)("popover"),j=w("popover",d),[N,P,D]=b(j),z=w(),H=(0,a.default)(_,P,D,L,M.root,null==T?void 0:T.root),B=(0,a.default)(M.body,null==T?void 0:T.body),[G,V]=(0,i.default)(!1,{value:null!=(g=e.open)?g:e.visible,defaultValue:null!=(u=e.defaultOpen)?u:e.defaultVisible}),F=(e,t)=>{V(e,!0),null==C||C(e,t)},q=n(m),U=n(f);return N(t.createElement(p.default,Object.assign({placement:h,trigger:A,mouseEnterDelay:I,mouseLeaveDelay:E},k,{prefixCls:j,classNames:{root:H,body:B},styles:{root:Object.assign(Object.assign(Object.assign(Object.assign({},R.root),S),y),null==x?void 0:x.root),body:Object.assign(Object.assign({},R.body),null==x?void 0:x.body)},ref:c,open:G,onOpenChange:e=>{F(e)},overlay:q||U?t.createElement(v,{prefixCls:j,title:q,content:U}):null,transitionName:(0,o.getTransitionName)(z,"zoom-big",k.transitionName),"data-popover-inject":!0}),(0,l.cloneElement)(O,{onKeyDown:e=>{var a,i;(0,t.isValidElement)(O)&&(null==(i=null==O?void 0:(a=O.props).onKeyDown)||i.call(a,e)),e.keyCode===r.default.ESC&&F(!1,e)}})))});E._InternalPanelDoNotUseOrYouWillBeFired=I,e.s(["default",0,E],829672),e.s(["Popover",0,E],282786)},166406,e=>{"use strict";var t=e.i(190144);e.s(["CopyOutlined",()=>t.default])},447566,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 000 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"}}]},name:"arrow-left",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["ArrowLeftOutlined",0,n],447566)},492030,e=>{"use strict";var t=e.i(121229);e.s(["CheckOutlined",()=>t.default])},596239,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M574 665.4a8.03 8.03 0 00-11.3 0L446.5 781.6c-53.8 53.8-144.6 59.5-204 0-59.5-59.5-53.8-150.2 0-204l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3l-39.8-39.8a8.03 8.03 0 00-11.3 0L191.4 526.5c-84.6 84.6-84.6 221.5 0 306s221.5 84.6 306 0l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3L574 665.4zm258.6-474c-84.6-84.6-221.5-84.6-306 0L410.3 307.6a8.03 8.03 0 000 11.3l39.7 39.7c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c53.8-53.8 144.6-59.5 204 0 59.5 59.5 53.8 150.2 0 204L665.3 562.6a8.03 8.03 0 000 11.3l39.8 39.8c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c84.5-84.6 84.5-221.5 0-306.1zM610.1 372.3a8.03 8.03 0 00-11.3 0L372.3 598.7a8.03 8.03 0 000 11.3l39.6 39.6c3.1 3.1 8.2 3.1 11.3 0l226.4-226.4c3.1-3.1 3.1-8.2 0-11.3l-39.5-39.6z"}}]},name:"link",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["LinkOutlined",0,n],596239)},326373,e=>{"use strict";var t=e.i(21539);e.s(["Dropdown",()=>t.default])},755151,e=>{"use strict";var t=e.i(247153);e.s(["DownOutlined",()=>t.default])},62478,e=>{"use strict";var t=e.i(764205);let a=async e=>{if(!e)return null;try{return await (0,t.getProxyUISettings)(e)}catch(e){return console.error("Error fetching proxy settings:",e),null}};e.s(["fetchProxySettings",0,a])},818581,(e,t,a)=>{"use strict";Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"useMergedRef",{enumerable:!0,get:function(){return r}});let i=e.r(271645);function r(e,t){let a=(0,i.useRef)(null),r=(0,i.useRef)(null);return(0,i.useCallback)(i=>{if(null===i){let e=a.current;e&&(a.current=null,e());let t=r.current;t&&(r.current=null,t())}else e&&(a.current=n(e,i)),t&&(r.current=n(t,i))},[e,t])}function n(e,t){if("function"!=typeof e)return e.current=t,()=>{e.current=null};{let a=e(t);return"function"==typeof a?a:()=>e(null)}}("function"==typeof a.default||"object"==typeof a.default&&null!==a.default)&&void 0===a.default.__esModule&&(Object.defineProperty(a.default,"__esModule",{value:!0}),Object.assign(a.default,a),t.exports=a.default)},602073,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64L128 192v384c0 212.1 171.9 384 384 384s384-171.9 384-384V192L512 64zm312 512c0 172.3-139.7 312-312 312S200 748.3 200 576V246l312-110 312 110v330z"}},{tag:"path",attrs:{d:"M378.4 475.1a35.91 35.91 0 00-50.9 0 35.91 35.91 0 000 50.9l129.4 129.4 2.1 2.1a33.98 33.98 0 0048.1 0L730.6 434a33.98 33.98 0 000-48.1l-2.8-2.8a33.98 33.98 0 00-48.1 0L483 579.7 378.4 475.1z"}}]},name:"safety",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["SafetyOutlined",0,n],602073)},44121,186515,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 000 13.8z"}}]},name:"menu-fold",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["MenuFoldOutlined",0,n],44121);let o={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 000-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0014.4 7z"}}]},name:"menu-unfold",theme:"outlined"};var l=a.forwardRef(function(e,i){return a.createElement(r.default,(0,t.default)({},e,{ref:i,icon:o}))});e.s(["MenuUnfoldOutlined",0,l],186515)},928685,e=>{"use strict";var t=e.i(38953);e.s(["SearchOutlined",()=>t.default])},283713,e=>{"use strict";var t=e.i(271645),a=e.i(764205),i=e.i(612256);let r="litellm_selected_worker_id";e.s(["useWorker",0,()=>{let{data:e}=(0,i.useUIConfig)(),n=e?.is_control_plane??!1,o=e?.workers??[],[l,s]=(0,t.useState)(()=>localStorage.getItem(r));(0,t.useEffect)(()=>{if(!l||0===o.length)return;let e=o.find(e=>e.worker_id===l);e&&(0,a.switchToWorkerUrl)(e.url)},[l,o]);let p=o.find(e=>e.worker_id===l)??null,c=(0,t.useCallback)(e=>{let t=o.find(t=>t.worker_id===e);t&&(s(e),localStorage.setItem(r,e),(0,a.switchToWorkerUrl)(t.url))},[o]);return{isControlPlane:n,workers:o,selectedWorkerId:l,selectedWorker:p,selectWorker:c,disconnectFromWorker:(0,t.useCallback)(()=>{s(null),localStorage.removeItem(r),(0,a.switchToWorkerUrl)(null)},[])}}])},295320,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M704 446H320c-4.4 0-8 3.6-8 8v402c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8V454c0-4.4-3.6-8-8-8zm-328 64h272v117H376V510zm272 290H376V683h272v117z"}},{tag:"path",attrs:{d:"M424 748a32 32 0 1064 0 32 32 0 10-64 0zm0-178a32 32 0 1064 0 32 32 0 10-64 0z"}},{tag:"path",attrs:{d:"M811.4 368.9C765.6 248 648.9 162 512.2 162S258.8 247.9 213 368.8C126.9 391.5 63.5 470.2 64 563.6 64.6 668 145.6 752.9 247.6 762c4.7.4 8.7-3.3 8.7-8v-60.4c0-4-3-7.4-7-7.9-27-3.4-52.5-15.2-72.1-34.5-24-23.5-37.2-55.1-37.2-88.6 0-28 9.1-54.4 26.2-76.4 16.7-21.4 40.2-36.9 66.1-43.7l37.9-10 13.9-36.7c8.6-22.8 20.6-44.2 35.7-63.5 14.9-19.2 32.6-36 52.4-50 41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.3c19.9 14 37.5 30.8 52.4 50 15.1 19.3 27.1 40.7 35.7 63.5l13.8 36.6 37.8 10c54.2 14.4 92.1 63.7 92.1 120 0 33.6-13.2 65.1-37.2 88.6-19.5 19.2-44.9 31.1-71.9 34.5-4 .5-6.9 3.9-6.9 7.9V754c0 4.7 4.1 8.4 8.8 8 101.7-9.2 182.5-94 183.2-198.2.6-93.4-62.7-172.1-148.6-194.9z"}}]},name:"cloud-server",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["CloudServerOutlined",0,n],295320)},190272,785913,e=>{"use strict";var t,a,i=((t={}).AUDIO_SPEECH="audio_speech",t.AUDIO_TRANSCRIPTION="audio_transcription",t.IMAGE_GENERATION="image_generation",t.VIDEO_GENERATION="video_generation",t.CHAT="chat",t.RESPONSES="responses",t.IMAGE_EDITS="image_edits",t.ANTHROPIC_MESSAGES="anthropic_messages",t.EMBEDDING="embedding",t),r=((a={}).IMAGE="image",a.VIDEO="video",a.CHAT="chat",a.RESPONSES="responses",a.IMAGE_EDITS="image_edits",a.ANTHROPIC_MESSAGES="anthropic_messages",a.EMBEDDINGS="embeddings",a.SPEECH="speech",a.TRANSCRIPTION="transcription",a.A2A_AGENTS="a2a_agents",a.MCP="mcp",a.REALTIME="realtime",a.INTERACTIONS="interactions",a);let n={image_generation:"image",video_generation:"video",chat:"chat",responses:"responses",image_edits:"image_edits",anthropic_messages:"anthropic_messages",audio_speech:"speech",audio_transcription:"transcription",embedding:"embeddings"};e.s(["EndpointType",()=>r,"getEndpointType",0,e=>{if(console.log("getEndpointType:",e),Object.values(i).includes(e)){let t=n[e];return console.log("endpointType:",t),t}return"chat"}],785913),e.s(["generateCodeSnippet",0,e=>{let t,{apiKeySource:a,accessToken:i,apiKey:n,inputMessage:o,chatHistory:l,selectedTags:s,selectedVectorStores:p,selectedGuardrails:c,selectedPolicies:g,selectedMCPServers:u,mcpServers:d,mcpServerToolRestrictions:m,selectedVoice:f,endpointType:_,selectedModel:h,selectedSdk:b,proxySettings:A}=e,v="session"===a?i:n,O=window.location.origin,I=A?.LITELLM_UI_API_DOC_BASE_URL;I&&I.trim()?O=I:A?.PROXY_BASE_URL&&(O=A.PROXY_BASE_URL);let $=o||"Your prompt here",E=$.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n"),C=l.filter(e=>!e.isImage).map(({role:e,content:t})=>({role:e,content:t})),y={};s.length>0&&(y.tags=s),p.length>0&&(y.vector_stores=p),c.length>0&&(y.guardrails=c),g.length>0&&(y.policies=g);let x=h||"your-model-name",T="azure"===b?`import openai | ||
| `]:Object.assign({},{background:e.skeletonLoadingBackground,backgroundSize:"400% 100%",animationName:c,animationDuration:e.skeletonLoadingMotionDuration,animationTimingFunction:"ease",animationIterationCount:"infinite"})}}})((0,p.mergeToken)(e,{skeletonAvatarCls:`${t}-avatar`,skeletonTitleCls:`${t}-title`,skeletonParagraphCls:`${t}-paragraph`,skeletonButtonCls:`${t}-button`,skeletonInputCls:`${t}-input`,skeletonImageCls:`${t}-image`,imageSizeBase:a(e.controlHeight).mul(1.5).equal(),borderRadius:100,skeletonLoadingBackground:`linear-gradient(90deg, ${e.gradientFromColor} 25%, ${e.gradientToColor} 37%, ${e.gradientFromColor} 63%)`,skeletonLoadingMotionDuration:"1.4s"}))},e=>{let{colorFillContent:t,colorFill:a}=e;return{color:t,colorGradientEnd:a,gradientFromColor:t,gradientToColor:a,titleHeight:e.controlHeight/2,blockRadius:e.borderRadiusSM,paragraphMarginTop:e.marginLG+e.marginXXS,paragraphLiHeight:e.controlHeight/2}},{deprecatedTokens:[["color","gradientFromColor"],["colorGradientEnd","gradientToColor"]]}),b=e=>{let{prefixCls:i,className:r,style:n,rows:o=0}=e,l=Array.from({length:o}).map((a,i)=>t.createElement("li",{key:i,style:{width:((e,t)=>{let{width:a,rows:i=2}=t;return Array.isArray(a)?a[e]:i-1===e?a:void 0})(i,e)}}));return t.createElement("ul",{className:(0,a.default)(i,r),style:n},l)},A=({prefixCls:e,className:i,width:r,style:n})=>t.createElement("h3",{className:(0,a.default)(e,i),style:Object.assign({width:r},n)});function v(e){return e&&"object"==typeof e?e:{}}let O=e=>{let{prefixCls:r,loading:o,className:l,rootClassName:s,style:p,children:c,avatar:g=!1,title:u=!0,paragraph:d=!0,active:m,round:f}=e,{getPrefixCls:_,direction:O,className:I,style:$}=(0,i.useComponentConfig)("skeleton"),E=_("skeleton",r),[C,y,x]=h(E);if(o||!("loading"in e)){let e,i,r=!!g,o=!!u,c=!!d;if(r){let a=Object.assign(Object.assign({prefixCls:`${E}-avatar`},o&&!c?{size:"large",shape:"square"}:{size:"large",shape:"circle"}),v(g));e=t.createElement("div",{className:`${E}-header`},t.createElement(n,Object.assign({},a)))}if(o||c){let e,a;if(o){let a=Object.assign(Object.assign({prefixCls:`${E}-title`},!r&&c?{width:"38%"}:r&&c?{width:"50%"}:{}),v(u));e=t.createElement(A,Object.assign({},a))}if(c){let e,i=Object.assign(Object.assign({prefixCls:`${E}-paragraph`},(e={},r&&o||(e.width="61%"),!r&&o?e.rows=3:e.rows=2,e)),v(d));a=t.createElement(b,Object.assign({},i))}i=t.createElement("div",{className:`${E}-content`},e,a)}let _=(0,a.default)(E,{[`${E}-with-avatar`]:r,[`${E}-active`]:m,[`${E}-rtl`]:"rtl"===O,[`${E}-round`]:f},I,l,s,y,x);return C(t.createElement("div",{className:_,style:Object.assign(Object.assign({},$),p)},e,i))}return null!=c?c:null};O.Button=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,block:c=!1,size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p,[`${d}-block`]:c},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-button`,size:g},b))))},O.Avatar=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,shape:c="circle",size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls","className"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-avatar`,shape:c,size:g},b))))},O.Input=e=>{let{prefixCls:o,className:l,rootClassName:s,active:p,block:c,size:g="default"}=e,{getPrefixCls:u}=t.useContext(i.ConfigContext),d=u("skeleton",o),[m,f,_]=h(d),b=(0,r.default)(e,["prefixCls"]),A=(0,a.default)(d,`${d}-element`,{[`${d}-active`]:p,[`${d}-block`]:c},l,s,f,_);return m(t.createElement("div",{className:A},t.createElement(n,Object.assign({prefixCls:`${d}-input`,size:g},b))))},O.Image=e=>{let{prefixCls:r,className:n,rootClassName:o,style:l,active:s}=e,{getPrefixCls:p}=t.useContext(i.ConfigContext),c=p("skeleton",r),[g,u,d]=h(c),m=(0,a.default)(c,`${c}-element`,{[`${c}-active`]:s},n,o,u,d);return g(t.createElement("div",{className:m},t.createElement("div",{className:(0,a.default)(`${c}-image`,n),style:l},t.createElement("svg",{viewBox:"0 0 1098 1024",xmlns:"http://www.w3.org/2000/svg",className:`${c}-image-svg`},t.createElement("title",null,"Image placeholder"),t.createElement("path",{d:"M365.714286 329.142857q0 45.714286-32.036571 77.677714t-77.677714 32.036571-77.677714-32.036571-32.036571-77.677714 32.036571-77.677714 77.677714-32.036571 77.677714 32.036571 32.036571 77.677714zM950.857143 548.571429l0 256-804.571429 0 0-109.714286 182.857143-182.857143 91.428571 91.428571 292.571429-292.571429zM1005.714286 146.285714l-914.285714 0q-7.460571 0-12.873143 5.412571t-5.412571 12.873143l0 694.857143q0 7.460571 5.412571 12.873143t12.873143 5.412571l914.285714 0q7.460571 0 12.873143-5.412571t5.412571-12.873143l0-694.857143q0-7.460571-5.412571-12.873143t-12.873143-5.412571zM1097.142857 164.571429l0 694.857143q0 37.741714-26.843429 64.585143t-64.585143 26.843429l-914.285714 0q-37.741714 0-64.585143-26.843429t-26.843429-64.585143l0-694.857143q0-37.741714 26.843429-64.585143t64.585143-26.843429l914.285714 0q37.741714 0 64.585143 26.843429t26.843429 64.585143z",className:`${c}-image-path`})))))},O.Node=e=>{let{prefixCls:r,className:n,rootClassName:o,style:l,active:s,children:p}=e,{getPrefixCls:c}=t.useContext(i.ConfigContext),g=c("skeleton",r),[u,d,m]=h(g),f=(0,a.default)(g,`${g}-element`,{[`${g}-active`]:s},d,n,o,m);return u(t.createElement("div",{className:f},t.createElement("div",{className:(0,a.default)(`${g}-image`,n),style:l},p)))},e.s(["default",0,O],185793)},959013,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"}},{tag:"path",attrs:{d:"M192 474h672q8 0 8 8v60q0 8-8 8H160q-8 0-8-8v-60q0-8 8-8z"}}]},name:"plus",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["default",0,n],959013)},282786,836938,310730,829672,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),i=e.i(914949),r=e.i(404948);let n=e=>e?"function"==typeof e?e():e:null;e.s(["getRenderPropValue",0,n],836938);var o=e.i(613541),l=e.i(763731),s=e.i(242064),p=e.i(491816);e.i(793154);var c=e.i(880476),g=e.i(183293),u=e.i(717356),d=e.i(320560),m=e.i(307358),f=e.i(246422),_=e.i(838378),h=e.i(617933);let b=(0,f.genStyleHooks)("Popover",e=>{let{colorBgElevated:t,colorText:a}=e,i=(0,_.mergeToken)(e,{popoverBg:t,popoverColor:a});return[(e=>{let{componentCls:t,popoverColor:a,titleMinWidth:i,fontWeightStrong:r,innerPadding:n,boxShadowSecondary:o,colorTextHeading:l,borderRadiusLG:s,zIndexPopup:p,titleMarginBottom:c,colorBgElevated:u,popoverBg:m,titleBorderBottom:f,innerContentPadding:_,titlePadding:h}=e;return[{[t]:Object.assign(Object.assign({},(0,g.resetComponent)(e)),{position:"absolute",top:0,left:{_skip_check_:!0,value:0},zIndex:p,fontWeight:"normal",whiteSpace:"normal",textAlign:"start",cursor:"auto",userSelect:"text","--valid-offset-x":"var(--arrow-offset-horizontal, var(--arrow-x))",transformOrigin:"var(--valid-offset-x, 50%) var(--arrow-y, 50%)","--antd-arrow-background-color":u,width:"max-content",maxWidth:"100vw","&-rtl":{direction:"rtl"},"&-hidden":{display:"none"},[`${t}-content`]:{position:"relative"},[`${t}-inner`]:{backgroundColor:m,backgroundClip:"padding-box",borderRadius:s,boxShadow:o,padding:n},[`${t}-title`]:{minWidth:i,marginBottom:c,color:l,fontWeight:r,borderBottom:f,padding:h},[`${t}-inner-content`]:{color:a,padding:_}})},(0,d.default)(e,"var(--antd-arrow-background-color)"),{[`${t}-pure`]:{position:"relative",maxWidth:"none",margin:e.sizePopupArrow,display:"inline-block",[`${t}-content`]:{display:"inline-block"}}}]})(i),(e=>{let{componentCls:t}=e;return{[t]:h.PresetColors.map(a=>{let i=e[`${a}6`];return{[`&${t}-${a}`]:{"--antd-arrow-background-color":i,[`${t}-inner`]:{backgroundColor:i},[`${t}-arrow`]:{background:"transparent"}}}})}})(i),(0,u.initZoomMotion)(i,"zoom-big")]},e=>{let{lineWidth:t,controlHeight:a,fontHeight:i,padding:r,wireframe:n,zIndexPopupBase:o,borderRadiusLG:l,marginXS:s,lineType:p,colorSplit:c,paddingSM:g}=e,u=a-i;return Object.assign(Object.assign(Object.assign({titleMinWidth:177,zIndexPopup:o+30},(0,m.getArrowToken)(e)),(0,d.getArrowOffsetToken)({contentRadius:l,limitVerticalRadius:!0})),{innerPadding:12*!n,titleMarginBottom:n?0:s,titlePadding:n?`${u/2}px ${r}px ${u/2-t}px`:0,titleBorderBottom:n?`${t}px ${p} ${c}`:"none",innerContentPadding:n?`${g}px ${r}px`:0})},{resetStyle:!1,deprecatedTokens:[["width","titleMinWidth"],["minWidth","titleMinWidth"]]});var A=function(e,t){var a={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(a[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,i=Object.getOwnPropertySymbols(e);r<i.length;r++)0>t.indexOf(i[r])&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(a[i[r]]=e[i[r]]);return a};let v=({title:e,content:a,prefixCls:i})=>e||a?t.createElement(t.Fragment,null,e&&t.createElement("div",{className:`${i}-title`},e),a&&t.createElement("div",{className:`${i}-inner-content`},a)):null,O=e=>{let{hashId:i,prefixCls:r,className:o,style:l,placement:s="top",title:p,content:g,children:u}=e,d=n(p),m=n(g),f=(0,a.default)(i,r,`${r}-pure`,`${r}-placement-${s}`,o);return t.createElement("div",{className:f,style:l},t.createElement("div",{className:`${r}-arrow`}),t.createElement(c.Popup,Object.assign({},e,{className:i,prefixCls:r}),u||t.createElement(v,{prefixCls:r,title:d,content:m})))},I=e=>{let{prefixCls:i,className:r}=e,n=A(e,["prefixCls","className"]),{getPrefixCls:o}=t.useContext(s.ConfigContext),l=o("popover",i),[p,c,g]=b(l);return p(t.createElement(O,Object.assign({},n,{prefixCls:l,hashId:c,className:(0,a.default)(r,g)})))};e.s(["Overlay",0,v,"default",0,I],310730);var $=function(e,t){var a={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(a[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,i=Object.getOwnPropertySymbols(e);r<i.length;r++)0>t.indexOf(i[r])&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(a[i[r]]=e[i[r]]);return a};let E=t.forwardRef((e,c)=>{var g,u;let{prefixCls:d,title:m,content:f,overlayClassName:_,placement:h="top",trigger:A="hover",children:O,mouseEnterDelay:I=.1,mouseLeaveDelay:E=.1,onOpenChange:C,overlayStyle:y={},styles:x,classNames:T}=e,k=$(e,["prefixCls","title","content","overlayClassName","placement","trigger","children","mouseEnterDelay","mouseLeaveDelay","onOpenChange","overlayStyle","styles","classNames"]),{getPrefixCls:w,className:L,style:S,classNames:M,styles:R}=(0,s.useComponentConfig)("popover"),j=w("popover",d),[N,P,D]=b(j),z=w(),H=(0,a.default)(_,P,D,L,M.root,null==T?void 0:T.root),B=(0,a.default)(M.body,null==T?void 0:T.body),[G,V]=(0,i.default)(!1,{value:null!=(g=e.open)?g:e.visible,defaultValue:null!=(u=e.defaultOpen)?u:e.defaultVisible}),F=(e,t)=>{V(e,!0),null==C||C(e,t)},q=n(m),U=n(f);return N(t.createElement(p.default,Object.assign({placement:h,trigger:A,mouseEnterDelay:I,mouseLeaveDelay:E},k,{prefixCls:j,classNames:{root:H,body:B},styles:{root:Object.assign(Object.assign(Object.assign(Object.assign({},R.root),S),y),null==x?void 0:x.root),body:Object.assign(Object.assign({},R.body),null==x?void 0:x.body)},ref:c,open:G,onOpenChange:e=>{F(e)},overlay:q||U?t.createElement(v,{prefixCls:j,title:q,content:U}):null,transitionName:(0,o.getTransitionName)(z,"zoom-big",k.transitionName),"data-popover-inject":!0}),(0,l.cloneElement)(O,{onKeyDown:e=>{var a,i;(0,t.isValidElement)(O)&&(null==(i=null==O?void 0:(a=O.props).onKeyDown)||i.call(a,e)),e.keyCode===r.default.ESC&&F(!1,e)}})))});E._InternalPanelDoNotUseOrYouWillBeFired=I,e.s(["default",0,E],829672),e.s(["Popover",0,E],282786)},166406,e=>{"use strict";var t=e.i(190144);e.s(["CopyOutlined",()=>t.default])},447566,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 000 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"}}]},name:"arrow-left",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["ArrowLeftOutlined",0,n],447566)},492030,e=>{"use strict";var t=e.i(121229);e.s(["CheckOutlined",()=>t.default])},596239,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M574 665.4a8.03 8.03 0 00-11.3 0L446.5 781.6c-53.8 53.8-144.6 59.5-204 0-59.5-59.5-53.8-150.2 0-204l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3l-39.8-39.8a8.03 8.03 0 00-11.3 0L191.4 526.5c-84.6 84.6-84.6 221.5 0 306s221.5 84.6 306 0l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3L574 665.4zm258.6-474c-84.6-84.6-221.5-84.6-306 0L410.3 307.6a8.03 8.03 0 000 11.3l39.7 39.7c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c53.8-53.8 144.6-59.5 204 0 59.5 59.5 53.8 150.2 0 204L665.3 562.6a8.03 8.03 0 000 11.3l39.8 39.8c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c84.5-84.6 84.5-221.5 0-306.1zM610.1 372.3a8.03 8.03 0 00-11.3 0L372.3 598.7a8.03 8.03 0 000 11.3l39.6 39.6c3.1 3.1 8.2 3.1 11.3 0l226.4-226.4c3.1-3.1 3.1-8.2 0-11.3l-39.5-39.6z"}}]},name:"link",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["LinkOutlined",0,n],596239)},326373,e=>{"use strict";var t=e.i(21539);e.s(["Dropdown",()=>t.default])},755151,e=>{"use strict";var t=e.i(247153);e.s(["DownOutlined",()=>t.default])},62478,e=>{"use strict";var t=e.i(602869);let a=async e=>{if(!e)return null;try{return await (0,t.getProxyUISettings)(e)}catch(e){return console.error("Error fetching proxy settings:",e),null}};e.s(["fetchProxySettings",0,a])},818581,(e,t,a)=>{"use strict";Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"useMergedRef",{enumerable:!0,get:function(){return r}});let i=e.r(271645);function r(e,t){let a=(0,i.useRef)(null),r=(0,i.useRef)(null);return(0,i.useCallback)(i=>{if(null===i){let e=a.current;e&&(a.current=null,e());let t=r.current;t&&(r.current=null,t())}else e&&(a.current=n(e,i)),t&&(r.current=n(t,i))},[e,t])}function n(e,t){if("function"!=typeof e)return e.current=t,()=>{e.current=null};{let a=e(t);return"function"==typeof a?a:()=>e(null)}}("function"==typeof a.default||"object"==typeof a.default&&null!==a.default)&&void 0===a.default.__esModule&&(Object.defineProperty(a.default,"__esModule",{value:!0}),Object.assign(a.default,a),t.exports=a.default)},602073,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64L128 192v384c0 212.1 171.9 384 384 384s384-171.9 384-384V192L512 64zm312 512c0 172.3-139.7 312-312 312S200 748.3 200 576V246l312-110 312 110v330z"}},{tag:"path",attrs:{d:"M378.4 475.1a35.91 35.91 0 00-50.9 0 35.91 35.91 0 000 50.9l129.4 129.4 2.1 2.1a33.98 33.98 0 0048.1 0L730.6 434a33.98 33.98 0 000-48.1l-2.8-2.8a33.98 33.98 0 00-48.1 0L483 579.7 378.4 475.1z"}}]},name:"safety",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["SafetyOutlined",0,n],602073)},44121,186515,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 000 13.8z"}}]},name:"menu-fold",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["MenuFoldOutlined",0,n],44121);let o={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 000-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0014.4 7z"}}]},name:"menu-unfold",theme:"outlined"};var l=a.forwardRef(function(e,i){return a.createElement(r.default,(0,t.default)({},e,{ref:i,icon:o}))});e.s(["MenuUnfoldOutlined",0,l],186515)},928685,e=>{"use strict";var t=e.i(38953);e.s(["SearchOutlined",()=>t.default])},283713,e=>{"use strict";var t=e.i(271645),a=e.i(602869),i=e.i(612256);let r="litellm_selected_worker_id";e.s(["useWorker",0,()=>{let{data:e}=(0,i.useUIConfig)(),n=e?.is_control_plane??!1,o=e?.workers??[],[l,s]=(0,t.useState)(()=>localStorage.getItem(r));(0,t.useEffect)(()=>{if(!l||0===o.length)return;let e=o.find(e=>e.worker_id===l);e&&(0,a.switchToWorkerUrl)(e.url)},[l,o]);let p=o.find(e=>e.worker_id===l)??null,c=(0,t.useCallback)(e=>{let t=o.find(t=>t.worker_id===e);t&&(s(e),localStorage.setItem(r,e),(0,a.switchToWorkerUrl)(t.url))},[o]);return{isControlPlane:n,workers:o,selectedWorkerId:l,selectedWorker:p,selectWorker:c,disconnectFromWorker:(0,t.useCallback)(()=>{s(null),localStorage.removeItem(r),(0,a.switchToWorkerUrl)(null)},[])}}])},295320,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M704 446H320c-4.4 0-8 3.6-8 8v402c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8V454c0-4.4-3.6-8-8-8zm-328 64h272v117H376V510zm272 290H376V683h272v117z"}},{tag:"path",attrs:{d:"M424 748a32 32 0 1064 0 32 32 0 10-64 0zm0-178a32 32 0 1064 0 32 32 0 10-64 0z"}},{tag:"path",attrs:{d:"M811.4 368.9C765.6 248 648.9 162 512.2 162S258.8 247.9 213 368.8C126.9 391.5 63.5 470.2 64 563.6 64.6 668 145.6 752.9 247.6 762c4.7.4 8.7-3.3 8.7-8v-60.4c0-4-3-7.4-7-7.9-27-3.4-52.5-15.2-72.1-34.5-24-23.5-37.2-55.1-37.2-88.6 0-28 9.1-54.4 26.2-76.4 16.7-21.4 40.2-36.9 66.1-43.7l37.9-10 13.9-36.7c8.6-22.8 20.6-44.2 35.7-63.5 14.9-19.2 32.6-36 52.4-50 41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.3c19.9 14 37.5 30.8 52.4 50 15.1 19.3 27.1 40.7 35.7 63.5l13.8 36.6 37.8 10c54.2 14.4 92.1 63.7 92.1 120 0 33.6-13.2 65.1-37.2 88.6-19.5 19.2-44.9 31.1-71.9 34.5-4 .5-6.9 3.9-6.9 7.9V754c0 4.7 4.1 8.4 8.8 8 101.7-9.2 182.5-94 183.2-198.2.6-93.4-62.7-172.1-148.6-194.9z"}}]},name:"cloud-server",theme:"outlined"};var r=e.i(9583),n=a.forwardRef(function(e,n){return a.createElement(r.default,(0,t.default)({},e,{ref:n,icon:i}))});e.s(["CloudServerOutlined",0,n],295320)},190272,785913,e=>{"use strict";var t,a,i=((t={}).AUDIO_SPEECH="audio_speech",t.AUDIO_TRANSCRIPTION="audio_transcription",t.IMAGE_GENERATION="image_generation",t.VIDEO_GENERATION="video_generation",t.CHAT="chat",t.RESPONSES="responses",t.IMAGE_EDITS="image_edits",t.ANTHROPIC_MESSAGES="anthropic_messages",t.EMBEDDING="embedding",t),r=((a={}).IMAGE="image",a.VIDEO="video",a.CHAT="chat",a.RESPONSES="responses",a.IMAGE_EDITS="image_edits",a.ANTHROPIC_MESSAGES="anthropic_messages",a.EMBEDDINGS="embeddings",a.SPEECH="speech",a.TRANSCRIPTION="transcription",a.A2A_AGENTS="a2a_agents",a.MCP="mcp",a.REALTIME="realtime",a.INTERACTIONS="interactions",a);let n={image_generation:"image",video_generation:"video",chat:"chat",responses:"responses",image_edits:"image_edits",anthropic_messages:"anthropic_messages",audio_speech:"speech",audio_transcription:"transcription",embedding:"embeddings"};e.s(["EndpointType",()=>r,"getEndpointType",0,e=>{if(console.log("getEndpointType:",e),Object.values(i).includes(e)){let t=n[e];return console.log("endpointType:",t),t}return"chat"}],785913),e.s(["generateCodeSnippet",0,e=>{let t,{apiKeySource:a,accessToken:i,apiKey:n,inputMessage:o,chatHistory:l,selectedTags:s,selectedVectorStores:p,selectedGuardrails:c,selectedPolicies:g,selectedMCPServers:u,mcpServers:d,mcpServerToolRestrictions:m,selectedVoice:f,endpointType:_,selectedModel:h,selectedSdk:b,proxySettings:A}=e,v="session"===a?i:n,O=window.location.origin,I=A?.LITELLM_UI_API_DOC_BASE_URL;I&&I.trim()?O=I:A?.PROXY_BASE_URL&&(O=A.PROXY_BASE_URL);let $=o||"Your prompt here",E=$.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n"),C=l.filter(e=>!e.isImage).map(({role:e,content:t})=>({role:e,content:t})),y={};s.length>0&&(y.tags=s),p.length>0&&(y.vector_stores=p),c.length>0&&(y.guardrails=c),g.length>0&&(y.policies=g);let x=h||"your-model-name",T="azure"===b?`import openai |
| @@ -1,11 +1,11 @@ | |||
| (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,916925,e=>{"use strict";var t,a=((t={}).A2A_Agent="A2A Agent",t.AI21="Ai21",t.AI21_CHAT="Ai21 Chat",t.AIML="AI/ML API",t.AIOHTTP_OPENAI="Aiohttp Openai",t.Anthropic="Anthropic",t.ANTHROPIC_TEXT="Anthropic Text",t.AssemblyAI="AssemblyAI",t.AUTO_ROUTER="Auto Router",t.Bedrock="Amazon Bedrock",t.BedrockMantle="Amazon Bedrock Mantle",t.SageMaker="AWS SageMaker",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Foundry (Studio)",t.AZURE_TEXT="Azure Text",t.BASETEN="Baseten",t.BYTEZ="Bytez",t.Cerebras="Cerebras",t.CLARIFAI="Clarifai",t.CLOUDFLARE="Cloudflare",t.CODESTRAL="Codestral",t.Cohere="Cohere",t.COHERE_CHAT="Cohere Chat",t.COMETAPI="Cometapi",t.COMPACTIFAI="Compactifai",t.Cursor="Cursor",t.Dashscope="Dashscope",t.Databricks="Databricks (Qwen API)",t.DATAROBOT="Datarobot",t.DeepInfra="DeepInfra",t.Deepgram="Deepgram",t.Deepseek="Deepseek",t.DOCKER_MODEL_RUNNER="Docker Model Runner",t.DOTPROMPT="Dotprompt",t.ElevenLabs="ElevenLabs",t.EMPOWER="Empower",t.FalAI="Fal AI",t.FEATHERLESS_AI="Featherless Ai",t.FireworksAI="Fireworks AI",t.FRIENDLIAI="Friendliai",t.GALADRIEL="Galadriel",t.GITHUB_COPILOT="Github Copilot",t.Google_AI_Studio="Google AI Studio",t.GradientAI="GradientAI",t.Groq="Groq",t.HEROKU="Heroku",t.Hosted_Vllm="vllm",t.HUGGINGFACE="Huggingface",t.HYPERBOLIC="Hyperbolic",t.Infinity="Infinity",t.JinaAI="Jina AI",t.LAMBDA_AI="Lambda Ai",t.LEMONADE="Lemonade",t.LLAMAFILE="Llamafile",t.LM_STUDIO="Lm Studio",t.LLAMA="Meta Llama",t.MARITALK="Maritalk",t.MiniMax="MiniMax",t.MistralAI="Mistral AI",t.MOONSHOT="Moonshot",t.MORPH="Morph",t.NEBIUS="Nebius",t.NLP_CLOUD="Nlp Cloud",t.NOVITA="Novita",t.NSCALE="Nscale",t.NVIDIA_NIM="Nvidia Nim",t.Ollama="Ollama",t.OLLAMA_CHAT="Ollama Chat",t.OOBABOOGA="Oobabooga",t.OpenAI="OpenAI",t.OPENAI_LIKE="Openai Like",t.OpenAI_Compatible="OpenAI-Compatible Endpoints (Together AI, etc.)",t.OpenAI_Text="OpenAI Text Completion",t.OpenAI_Text_Compatible="OpenAI-Compatible Text Completion Models (Together AI, etc.)",t.Openrouter="Openrouter",t.Oracle="Oracle Cloud Infrastructure (OCI)",t.OVHCLOUD="Ovhcloud",t.Perplexity="Perplexity",t.PETALS="Petals",t.PG_VECTOR="Pg Vector",t.PREDIBASE="Predibase",t.RECRAFT="Recraft",t.REPLICATE="Replicate",t.RunwayML="RunwayML",t.SAGEMAKER_LEGACY="Sagemaker",t.Sambanova="Sambanova",t.SAP="SAP Generative AI Hub",t.Snowflake="Snowflake",t.TEXT_COMPLETION_CODESTRAL="Text-Completion-Codestral",t.TogetherAI="TogetherAI",t.TOPAZ="Topaz",t.Triton="Triton",t.V0="V0",t.VERCEL_AI_GATEWAY="Vercel Ai Gateway",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.VERTEX_AI_BETA="Vertex Ai Beta",t.VLLM="Vllm",t.VolcEngine="VolcEngine",t.Voyage="Voyage AI",t.WANDB="Wandb",t.WATSONX="Watsonx",t.WATSONX_TEXT="Watsonx Text",t.xAI="xAI",t.XINFERENCE="Xinference",t.ZAI="Z.AI (Zhipu AI)",t);let i={A2A_Agent:"a2a_agent",AI21:"ai21",AI21_CHAT:"ai21_chat",AIML:"aiml",AIOHTTP_OPENAI:"aiohttp_openai",Anthropic:"anthropic",ANTHROPIC_TEXT:"anthropic_text",AssemblyAI:"assemblyai",AUTO_ROUTER:"auto_router",Azure:"azure",Azure_AI_Studio:"azure_ai",AZURE_TEXT:"azure_text",BASETEN:"baseten",Bedrock:"bedrock",BedrockMantle:"bedrock_mantle",BYTEZ:"bytez",Cerebras:"cerebras",CLARIFAI:"clarifai",CLOUDFLARE:"cloudflare",CODESTRAL:"codestral",Cohere:"cohere",COHERE_CHAT:"cohere_chat",COMETAPI:"cometapi",COMPACTIFAI:"compactifai",Cursor:"cursor",Dashscope:"dashscope",Databricks:"databricks",DATAROBOT:"datarobot",DeepInfra:"deepinfra",Deepgram:"deepgram",Deepseek:"deepseek",DOCKER_MODEL_RUNNER:"docker_model_runner",DOTPROMPT:"dotprompt",ElevenLabs:"elevenlabs",EMPOWER:"empower",FalAI:"fal_ai",FEATHERLESS_AI:"featherless_ai",FireworksAI:"fireworks_ai",FRIENDLIAI:"friendliai",GALADRIEL:"galadriel",GITHUB_COPILOT:"github_copilot",Google_AI_Studio:"gemini",GradientAI:"gradient_ai",Groq:"groq",HEROKU:"heroku",Hosted_Vllm:"hosted_vllm",HUGGINGFACE:"huggingface",HYPERBOLIC:"hyperbolic",Infinity:"infinity",JinaAI:"jina_ai",LAMBDA_AI:"lambda_ai",LEMONADE:"lemonade",LLAMAFILE:"llamafile",LLAMA:"meta_llama",LM_STUDIO:"lm_studio",MARITALK:"maritalk",MiniMax:"minimax",MistralAI:"mistral",MOONSHOT:"moonshot",MORPH:"morph",NEBIUS:"nebius",NLP_CLOUD:"nlp_cloud",NOVITA:"novita",NSCALE:"nscale",NVIDIA_NIM:"nvidia_nim",Ollama:"ollama",OLLAMA_CHAT:"ollama_chat",OOBABOOGA:"oobabooga",OpenAI:"openai",OPENAI_LIKE:"openai_like",OpenAI_Compatible:"openai",OpenAI_Text:"text-completion-openai",OpenAI_Text_Compatible:"text-completion-openai",Openrouter:"openrouter",Oracle:"oci",OVHCLOUD:"ovhcloud",Perplexity:"perplexity",PETALS:"petals",PG_VECTOR:"pg_vector",PREDIBASE:"predibase",RECRAFT:"recraft",REPLICATE:"replicate",RunwayML:"runwayml",SAGEMAKER_LEGACY:"sagemaker",SageMaker:"sagemaker_chat",Sambanova:"sambanova",SAP:"sap",Snowflake:"snowflake",TEXT_COMPLETION_CODESTRAL:"text-completion-codestral",TogetherAI:"together_ai",TOPAZ:"topaz",Triton:"triton",V0:"v0",VERCEL_AI_GATEWAY:"vercel_ai_gateway",Vertex_AI:"vertex_ai",VERTEX_AI_BETA:"vertex_ai_beta",VLLM:"vllm",VolcEngine:"volcengine",Voyage:"voyage",WANDB:"wandb",WATSONX:"watsonx",WATSONX_TEXT:"watsonx_text",xAI:"xai",XINFERENCE:"xinference",ZAI:"zai"},r="../ui/assets/logos/",n={"A2A Agent":`${r}a2a_agent.png`,Ai21:`${r}ai21.svg`,"Ai21 Chat":`${r}ai21.svg`,"AI/ML API":`${r}aiml_api.svg`,"Aiohttp Openai":`${r}openai_small.svg`,Anthropic:`${r}anthropic.svg`,"Anthropic Text":`${r}anthropic.svg`,AssemblyAI:`${r}assemblyai_small.png`,Azure:`${r}microsoft_azure.svg`,"Azure AI Foundry (Studio)":`${r}microsoft_azure.svg`,"Azure Text":`${r}microsoft_azure.svg`,Baseten:`${r}baseten.svg`,"Amazon Bedrock":`${r}bedrock.svg`,"Amazon Bedrock Mantle":`${r}bedrock.svg`,"AWS SageMaker":`${r}bedrock.svg`,Cerebras:`${r}cerebras.svg`,Cloudflare:`${r}cloudflare.svg`,Codestral:`${r}mistral.svg`,Cohere:`${r}cohere.svg`,"Cohere Chat":`${r}cohere.svg`,Cometapi:`${r}cometapi.svg`,Cursor:`${r}cursor.svg`,"Databricks (Qwen API)":`${r}databricks.svg`,Dashscope:`${r}dashscope.svg`,Deepseek:`${r}deepseek.svg`,Deepgram:`${r}deepgram.png`,DeepInfra:`${r}deepinfra.png`,ElevenLabs:`${r}elevenlabs.png`,"Fal AI":`${r}fal_ai.jpg`,"Featherless Ai":`${r}featherless.svg`,"Fireworks AI":`${r}fireworks.svg`,Friendliai:`${r}friendli.svg`,"Github Copilot":`${r}github_copilot.svg`,"Google AI Studio":`${r}google.svg`,GradientAI:`${r}gradientai.svg`,Groq:`${r}groq.svg`,vllm:`${r}vllm.png`,Huggingface:`${r}huggingface.svg`,Hyperbolic:`${r}hyperbolic.svg`,Infinity:`${r}infinity.png`,"Jina AI":`${r}jina.png`,"Lambda Ai":`${r}lambda.svg`,"Lm Studio":`${r}lmstudio.svg`,"Meta Llama":`${r}meta_llama.svg`,MiniMax:`${r}minimax.svg`,"Mistral AI":`${r}mistral.svg`,Moonshot:`${r}moonshot.svg`,Morph:`${r}morph.svg`,Nebius:`${r}nebius.svg`,Novita:`${r}novita.svg`,"Nvidia Nim":`${r}nvidia_nim.svg`,Ollama:`${r}ollama.svg`,"Ollama Chat":`${r}ollama.svg`,Oobabooga:`${r}openai_small.svg`,OpenAI:`${r}openai_small.svg`,"Openai Like":`${r}openai_small.svg`,"OpenAI Text Completion":`${r}openai_small.svg`,"OpenAI-Compatible Text Completion Models (Together AI, etc.)":`${r}openai_small.svg`,"OpenAI-Compatible Endpoints (Together AI, etc.)":`${r}openai_small.svg`,Openrouter:`${r}openrouter.svg`,"Oracle Cloud Infrastructure (OCI)":`${r}oracle.svg`,Perplexity:`${r}perplexity-ai.svg`,Recraft:`${r}recraft.svg`,Replicate:`${r}replicate.svg`,RunwayML:`${r}runwayml.png`,Sagemaker:`${r}bedrock.svg`,Sambanova:`${r}sambanova.svg`,"SAP Generative AI Hub":`${r}sap.png`,Snowflake:`${r}snowflake.svg`,"Text-Completion-Codestral":`${r}mistral.svg`,TogetherAI:`${r}togetherai.svg`,Topaz:`${r}topaz.svg`,Triton:`${r}nvidia_triton.png`,V0:`${r}v0.svg`,"Vercel Ai Gateway":`${r}vercel.svg`,"Vertex AI (Anthropic, Gemini, etc.)":`${r}google.svg`,"Vertex Ai Beta":`${r}google.svg`,Vllm:`${r}vllm.png`,VolcEngine:`${r}volcengine.png`,"Voyage AI":`${r}voyage.webp`,Watsonx:`${r}watsonx.svg`,"Watsonx Text":`${r}watsonx.svg`,xAI:`${r}xai.svg`,Xinference:`${r}xinference.svg`};e.s(["Providers",()=>a,"getPlaceholder",0,e=>{if("AI/ML API"===e)return"aiml/flux-pro/v1.1";if("Vertex AI (Anthropic, Gemini, etc.)"===e)return"gemini-pro";if("Anthropic"==e)return"claude-3-opus";if("Amazon Bedrock"==e)return"claude-3-opus";if("AWS SageMaker"==e)return"sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b";else if("Google AI Studio"==e)return"gemini-pro";else if("Azure AI Foundry (Studio)"==e)return"azure_ai/command-r-plus";else if("Azure"==e)return"my-deployment";else if("Oracle Cloud Infrastructure (OCI)"==e)return"oci/xai.grok-4";else if("Snowflake"==e)return"snowflake/mistral-7b";else if("Voyage AI"==e)return"voyage/";else if("Jina AI"==e)return"jina_ai/";else if("VolcEngine"==e)return"volcengine/<any-model-on-volcengine>";else if("DeepInfra"==e)return"deepinfra/<any-model-on-deepinfra>";else if("Fal AI"==e)return"fal_ai/fal-ai/flux-pro/v1.1-ultra";else if("RunwayML"==e)return"runwayml/gen4_turbo";else if("Watsonx"===e)return"watsonx/ibm/granite-3-3-8b-instruct";else if("Cursor"===e)return"cursor/claude-4-sonnet";else if("Z.AI (Zhipu AI)"===e)return"zai/glm-4.5";else return"gpt-3.5-turbo"},"getProviderLogoAndName",0,e=>{if(!e)return{logo:"",displayName:"-"};if("gemini"===e.toLowerCase()){let e="Google AI Studio";return{logo:n[e],displayName:e}}let t=Object.keys(i).find(t=>i[t].toLowerCase()===e.toLowerCase());if(!t)return{logo:"",displayName:e};let r=a[t];return{logo:n[r],displayName:r}},"getProviderModels",0,(e,t)=>{console.log(`Provider key: ${e}`);let a=i[e];console.log(`Provider mapped to: ${a}`);let r=[];return e&&"object"==typeof t&&(Object.entries(t).forEach(([e,t])=>{if(null!==t&&"object"==typeof t&&"litellm_provider"in t){let i=t.litellm_provider;(i===a||"string"==typeof i&&(i.startsWith(`${a}_`)||i.startsWith(`${a}-`)))&&r.push(e)}}),"Cohere"==e&&(console.log("Adding cohere chat models"),Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"cohere_chat"===t.litellm_provider&&r.push(e)})),"AWS SageMaker"==e&&(console.log("Adding sagemaker chat models"),Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"sagemaker_chat"===t.litellm_provider&&r.push(e)}))),r},"providerLogoMap",0,n,"provider_map",0,i])},185793,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),i=e.i(242064),r=e.i(529681);let n=e=>{let{prefixCls:i,className:r,style:n,size:o,shape:l}=e,s=(0,a.default)({[`${i}-lg`]:"large"===o,[`${i}-sm`]:"small"===o}),p=(0,a.default)({[`${i}-circle`]:"circle"===l,[`${i}-square`]:"square"===l,[`${i}-round`]:"round"===l}),c=t.useMemo(()=>"number"==typeof o?{width:o,height:o,lineHeight:`${o}px`}:{},[o]);return t.createElement("span",{className:(0,a.default)(i,s,p,r),style:Object.assign(Object.assign({},c),n)})};e.i(296059);var o=e.i(694758),l=e.i(915654),s=e.i(246422),p=e.i(838378);let c=new o.Keyframes("ant-skeleton-loading",{"0%":{backgroundPosition:"100% 50%"},"100%":{backgroundPosition:"0 50%"}}),g=e=>({height:e,lineHeight:(0,l.unit)(e)}),u=e=>Object.assign({width:e},g(e)),d=(e,t)=>Object.assign({width:t(e).mul(5).equal(),minWidth:t(e).mul(5).equal()},g(e)),m=e=>Object.assign({width:e},g(e)),f=(e,t,a)=>{let{skeletonButtonCls:i}=e;return{[`${a}${i}-circle`]:{width:t,minWidth:t,borderRadius:"50%"},[`${a}${i}-round`]:{borderRadius:t}}},_=(e,t)=>Object.assign({width:t(e).mul(2).equal(),minWidth:t(e).mul(2).equal()},g(e)),h=(0,s.genStyleHooks)("Skeleton",e=>{let{componentCls:t,calc:a}=e;return(e=>{let{componentCls:t,skeletonAvatarCls:a,skeletonTitleCls:i,skeletonParagraphCls:r,skeletonButtonCls:n,skeletonInputCls:o,skeletonImageCls:l,controlHeight:s,controlHeightLG:p,controlHeightSM:g,gradientFromColor:h,padding:b,marginSM:A,borderRadius:v,titleHeight:O,blockRadius:I,paragraphLiHeight:$,controlHeightXS:E,paragraphMarginTop:C}=e;return{[t]:{display:"table",width:"100%",[`${t}-header`]:{display:"table-cell",paddingInlineEnd:b,verticalAlign:"top",[a]:Object.assign({display:"inline-block",verticalAlign:"top",background:h},u(s)),[`${a}-circle`]:{borderRadius:"50%"},[`${a}-lg`]:Object.assign({},u(p)),[`${a}-sm`]:Object.assign({},u(g))},[`${t}-content`]:{display:"table-cell",width:"100%",verticalAlign:"top",[i]:{width:"100%",height:O,background:h,borderRadius:I,[`+ ${r}`]:{marginBlockStart:g}},[r]:{padding:0,"> li":{width:"100%",height:$,listStyle:"none",background:h,borderRadius:I,"+ li":{marginBlockStart:E}}},[`${r}> li:last-child:not(:first-child):not(:nth-child(2))`]:{width:"61%"}},[`&-round ${t}-content`]:{[`${i}, ${r} > li`]:{borderRadius:v}}},[`${t}-with-avatar ${t}-content`]:{[i]:{marginBlockStart:A,[`+ ${r}`]:{marginBlockStart:C}}},[`${t}${t}-element`]:Object.assign(Object.assign(Object.assign(Object.assign({display:"inline-block",width:"auto"},(e=>{let{borderRadiusSM:t,skeletonButtonCls:a,controlHeight:i,controlHeightLG:r,controlHeightSM:n,gradientFromColor:o,calc:l}=e;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({[a]:Object.assign({display:"inline-block",verticalAlign:"top",background:o,borderRadius:t,width:l(i).mul(2).equal(),minWidth:l(i).mul(2).equal()},_(i,l))},f(e,i,a)),{[`${a}-lg`]:Object.assign({},_(r,l))}),f(e,r,`${a}-lg`)),{[`${a}-sm`]:Object.assign({},_(n,l))}),f(e,n,`${a}-sm`))})(e)),(e=>{let{skeletonAvatarCls:t,gradientFromColor:a,controlHeight:i,controlHeightLG:r,controlHeightSM:n}=e;return{[t]:Object.assign({display:"inline-block",verticalAlign:"top",background:a},u(i)),[`${t}${t}-circle`]:{borderRadius:"50%"},[`${t}${t}-lg`]:Object.assign({},u(r)),[`${t}${t}-sm`]:Object.assign({},u(n))}})(e)),(e=>{let{controlHeight:t,borderRadiusSM:a,skeletonInputCls:i,controlHeightLG:r,controlHeightSM:n,gradientFromColor:o,calc:l}=e;return{[i]:Object.assign({display:"inline-block",verticalAlign:"top",background:o,borderRadius:a},d(t,l)),[`${i}-lg`]:Object.assign({},d(r,l)),[`${i}-sm`]:Object.assign({},d(n,l))}})(e)),(e=>{let{skeletonImageCls:t,imageSizeBase:a,gradientFromColor:i,borderRadiusSM:r,calc:n}=e;return{[t]:Object.assign(Object.assign({display:"inline-flex",alignItems:"center",justifyContent:"center",verticalAlign:"middle",background:i,borderRadius:r},m(n(a).mul(2).equal())),{[`${t}-path`]:{fill:"#bfbfbf"},[`${t}-svg`]:Object.assign(Object.assign({},m(a)),{maxWidth:n(a).mul(4).equal(),maxHeight:n(a).mul(4).equal()}),[`${t}-svg${t}-svg-circle`]:{borderRadius:"50%"}}),[`${t}${t}-circle`]:{borderRadius:"50%"}}})(e)),[`${t}${t}-block`]:{width:"100%",[n]:{width:"100%"},[o]:{width:"100%"}},[`${t}${t}-active`]:{[` | |||
| (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,916925,e=>{"use strict";var t,a=((t={}).A2A_Agent="A2A Agent",t.AI21="Ai21",t.AI21_CHAT="Ai21 Chat",t.AIML="AI/ML API",t.AIOHTTP_OPENAI="Aiohttp Openai",t.Anthropic="Anthropic",t.ANTHROPIC_TEXT="Anthropic Text",t.AssemblyAI="AssemblyAI",t.AUTO_ROUTER="Auto Router",t.Bedrock="Amazon Bedrock",t.BedrockMantle="Amazon Bedrock Mantle",t.SageMaker="AWS SageMaker",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Foundry (Studio)",t.AZURE_TEXT="Azure Text",t.BASETEN="Baseten",t.BYTEZ="Bytez",t.Cerebras="Cerebras",t.CLARIFAI="Clarifai",t.CLOUDFLARE="Cloudflare",t.CODESTRAL="Codestral",t.Cohere="Cohere",t.COHERE_CHAT="Cohere Chat",t.COMETAPI="Cometapi",t.COMPACTIFAI="Compactifai",t.Cursor="Cursor",t.Dashscope="Dashscope",t.Databricks="Databricks (Qwen API)",t.DATAROBOT="Datarobot",t.DeepInfra="DeepInfra",t.Deepgram="Deepgram",t.Deepseek="Deepseek",t.DOCKER_MODEL_RUNNER="Docker Model Runner",t.DOTPROMPT="Dotprompt",t.ElevenLabs="ElevenLabs",t.EMPOWER="Empower",t.FalAI="Fal AI",t.FEATHERLESS_AI="Featherless Ai",t.FireworksAI="Fireworks AI",t.FRIENDLIAI="Friendliai",t.GALADRIEL="Galadriel",t.GITHUB_COPILOT="Github Copilot",t.Google_AI_Studio="Google AI Studio",t.GradientAI="GradientAI",t.Groq="Groq",t.HEROKU="Heroku",t.Hosted_Vllm="vllm",t.HUGGINGFACE="Huggingface",t.HYPERBOLIC="Hyperbolic",t.Infinity="Infinity",t.JinaAI="Jina AI",t.LAMBDA_AI="Lambda Ai",t.LEMONADE="Lemonade",t.LLAMAFILE="Llamafile",t.LM_STUDIO="Lm Studio",t.LLAMA="Meta Llama",t.MARITALK="Maritalk",t.MiniMax="MiniMax",t.MistralAI="Mistral AI",t.MOONSHOT="Moonshot",t.MORPH="Morph",t.NEBIUS="Nebius",t.NLP_CLOUD="Nlp Cloud",t.NOVITA="Novita",t.NSCALE="Nscale",t.NVIDIA_NIM="Nvidia Nim",t.Ollama="Ollama",t.OLLAMA_CHAT="Ollama Chat",t.OOBABOOGA="Oobabooga",t.OpenAI="OpenAI",t.OPENAI_LIKE="Openai Like",t.OpenAI_Compatible="OpenAI-Compatible Endpoints (Together AI, etc.)",t.OpenAI_Text="OpenAI Text Completion",t.OpenAI_Text_Compatible="OpenAI-Compatible Text Completion Models (Together AI, etc.)",t.Openrouter="Openrouter",t.Oracle="Oracle Cloud Infrastructure (OCI)",t.OVHCLOUD="Ovhcloud",t.Perplexity="Perplexity",t.PETALS="Petals",t.PG_VECTOR="Pg Vector",t.PREDIBASE="Predibase",t.RECRAFT="Recraft",t.REPLICATE="Replicate",t.RunwayML="RunwayML",t.SAGEMAKER_LEGACY="Sagemaker",t.Sambanova="Sambanova",t.SAP="SAP Generative AI Hub",t.Snowflake="Snowflake",t.Soniox="Soniox",t.TEXT_COMPLETION_CODESTRAL="Text-Completion-Codestral",t.TogetherAI="TogetherAI",t.TOPAZ="Topaz",t.Triton="Triton",t.V0="V0",t.VERCEL_AI_GATEWAY="Vercel Ai Gateway",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.VERTEX_AI_BETA="Vertex Ai Beta",t.VLLM="Vllm",t.VolcEngine="VolcEngine",t.Voyage="Voyage AI",t.WANDB="Wandb",t.WATSONX="Watsonx",t.WATSONX_TEXT="Watsonx Text",t.xAI="xAI",t.XINFERENCE="Xinference",t.ZAI="Z.AI (Zhipu AI)",t);let i={A2A_Agent:"a2a_agent",AI21:"ai21",AI21_CHAT:"ai21_chat",AIML:"aiml",AIOHTTP_OPENAI:"aiohttp_openai",Anthropic:"anthropic",ANTHROPIC_TEXT:"anthropic_text",AssemblyAI:"assemblyai",AUTO_ROUTER:"auto_router",Azure:"azure",Azure_AI_Studio:"azure_ai",AZURE_TEXT:"azure_text",BASETEN:"baseten",Bedrock:"bedrock",BedrockMantle:"bedrock_mantle",BYTEZ:"bytez",Cerebras:"cerebras",CLARIFAI:"clarifai",CLOUDFLARE:"cloudflare",CODESTRAL:"codestral",Cohere:"cohere",COHERE_CHAT:"cohere_chat",COMETAPI:"cometapi",COMPACTIFAI:"compactifai",Cursor:"cursor",Dashscope:"dashscope",Databricks:"databricks",DATAROBOT:"datarobot",DeepInfra:"deepinfra",Deepgram:"deepgram",Deepseek:"deepseek",DOCKER_MODEL_RUNNER:"docker_model_runner",DOTPROMPT:"dotprompt",ElevenLabs:"elevenlabs",EMPOWER:"empower",FalAI:"fal_ai",FEATHERLESS_AI:"featherless_ai",FireworksAI:"fireworks_ai",FRIENDLIAI:"friendliai",GALADRIEL:"galadriel",GITHUB_COPILOT:"github_copilot",Google_AI_Studio:"gemini",GradientAI:"gradient_ai",Groq:"groq",HEROKU:"heroku",Hosted_Vllm:"hosted_vllm",HUGGINGFACE:"huggingface",HYPERBOLIC:"hyperbolic",Infinity:"infinity",JinaAI:"jina_ai",LAMBDA_AI:"lambda_ai",LEMONADE:"lemonade",LLAMAFILE:"llamafile",LLAMA:"meta_llama",LM_STUDIO:"lm_studio",MARITALK:"maritalk",MiniMax:"minimax",MistralAI:"mistral",MOONSHOT:"moonshot",MORPH:"morph",NEBIUS:"nebius",NLP_CLOUD:"nlp_cloud",NOVITA:"novita",NSCALE:"nscale",NVIDIA_NIM:"nvidia_nim",Ollama:"ollama",OLLAMA_CHAT:"ollama_chat",OOBABOOGA:"oobabooga",OpenAI:"openai",OPENAI_LIKE:"openai_like",OpenAI_Compatible:"openai",OpenAI_Text:"text-completion-openai",OpenAI_Text_Compatible:"text-completion-openai",Openrouter:"openrouter",Oracle:"oci",OVHCLOUD:"ovhcloud",Perplexity:"perplexity",PETALS:"petals",PG_VECTOR:"pg_vector",PREDIBASE:"predibase",RECRAFT:"recraft",REPLICATE:"replicate",RunwayML:"runwayml",SAGEMAKER_LEGACY:"sagemaker",SageMaker:"sagemaker_chat",Sambanova:"sambanova",SAP:"sap",Snowflake:"snowflake",Soniox:"soniox",TEXT_COMPLETION_CODESTRAL:"text-completion-codestral",TogetherAI:"together_ai",TOPAZ:"topaz",Triton:"triton",V0:"v0",VERCEL_AI_GATEWAY:"vercel_ai_gateway",Vertex_AI:"vertex_ai",VERTEX_AI_BETA:"vertex_ai_beta",VLLM:"vllm",VolcEngine:"volcengine",Voyage:"voyage",WANDB:"wandb",WATSONX:"watsonx",WATSONX_TEXT:"watsonx_text",xAI:"xai",XINFERENCE:"xinference",ZAI:"zai"},r="../ui/assets/logos/",n={"A2A Agent":`${r}a2a_agent.png`,Ai21:`${r}ai21.svg`,"Ai21 Chat":`${r}ai21.svg`,"AI/ML API":`${r}aiml_api.svg`,"Aiohttp Openai":`${r}openai_small.svg`,Anthropic:`${r}anthropic.svg`,"Anthropic Text":`${r}anthropic.svg`,AssemblyAI:`${r}assemblyai_small.png`,Azure:`${r}microsoft_azure.svg`,"Azure AI Foundry (Studio)":`${r}microsoft_azure.svg`,"Azure Text":`${r}microsoft_azure.svg`,Baseten:`${r}baseten.svg`,"Amazon Bedrock":`${r}bedrock.svg`,"Amazon Bedrock Mantle":`${r}bedrock.svg`,"AWS SageMaker":`${r}bedrock.svg`,Cerebras:`${r}cerebras.svg`,Cloudflare:`${r}cloudflare.svg`,Codestral:`${r}mistral.svg`,Cohere:`${r}cohere.svg`,"Cohere Chat":`${r}cohere.svg`,Cometapi:`${r}cometapi.svg`,Cursor:`${r}cursor.svg`,"Databricks (Qwen API)":`${r}databricks.svg`,Dashscope:`${r}dashscope.svg`,Deepseek:`${r}deepseek.svg`,Deepgram:`${r}deepgram.png`,DeepInfra:`${r}deepinfra.png`,ElevenLabs:`${r}elevenlabs.png`,"Fal AI":`${r}fal_ai.jpg`,"Featherless Ai":`${r}featherless.svg`,"Fireworks AI":`${r}fireworks.svg`,Friendliai:`${r}friendli.svg`,"Github Copilot":`${r}github_copilot.svg`,"Google AI Studio":`${r}google.svg`,GradientAI:`${r}gradientai.svg`,Groq:`${r}groq.svg`,vllm:`${r}vllm.png`,Huggingface:`${r}huggingface.svg`,Hyperbolic:`${r}hyperbolic.svg`,Infinity:`${r}infinity.png`,"Jina AI":`${r}jina.png`,"Lambda Ai":`${r}lambda.svg`,"Lm Studio":`${r}lmstudio.svg`,"Meta Llama":`${r}meta_llama.svg`,MiniMax:`${r}minimax.svg`,"Mistral AI":`${r}mistral.svg`,Moonshot:`${r}moonshot.svg`,Morph:`${r}morph.svg`,Nebius:`${r}nebius.svg`,Novita:`${r}novita.svg`,"Nvidia Nim":`${r}nvidia_nim.svg`,Ollama:`${r}ollama.svg`,"Ollama Chat":`${r}ollama.svg`,Oobabooga:`${r}openai_small.svg`,OpenAI:`${r}openai_small.svg`,"Openai Like":`${r}openai_small.svg`,"OpenAI Text Completion":`${r}openai_small.svg`,"OpenAI-Compatible Text Completion Models (Together AI, etc.)":`${r}openai_small.svg`,"OpenAI-Compatible Endpoints (Together AI, etc.)":`${r}openai_small.svg`,Openrouter:`${r}openrouter.svg`,"Oracle Cloud Infrastructure (OCI)":`${r}oracle.svg`,Perplexity:`${r}perplexity-ai.svg`,Recraft:`${r}recraft.svg`,Replicate:`${r}replicate.svg`,RunwayML:`${r}runwayml.png`,Sagemaker:`${r}bedrock.svg`,Sambanova:`${r}sambanova.svg`,"SAP Generative AI Hub":`${r}sap.png`,Snowflake:`${r}snowflake.svg`,Soniox:`${r}soniox.svg`,"Text-Completion-Codestral":`${r}mistral.svg`,TogetherAI:`${r}togetherai.svg`,Topaz:`${r}topaz.svg`,Triton:`${r}nvidia_triton.png`,V0:`${r}v0.svg`,"Vercel Ai Gateway":`${r}vercel.svg`,"Vertex AI (Anthropic, Gemini, etc.)":`${r}google.svg`,"Vertex Ai Beta":`${r}google.svg`,Vllm:`${r}vllm.png`,VolcEngine:`${r}volcengine.png`,"Voyage AI":`${r}voyage.webp`,Watsonx:`${r}watsonx.svg`,"Watsonx Text":`${r}watsonx.svg`,xAI:`${r}xai.svg`,Xinference:`${r}xinference.svg`};e.s(["Providers",()=>a,"getPlaceholder",0,e=>{if("AI/ML API"===e)return"aiml/flux-pro/v1.1";if("Vertex AI (Anthropic, Gemini, etc.)"===e)return"gemini-pro";if("Anthropic"==e)return"claude-3-opus";if("Amazon Bedrock"==e)return"claude-3-opus";if("AWS SageMaker"==e)return"sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b";else if("Google AI Studio"==e)return"gemini-pro";else if("Azure AI Foundry (Studio)"==e)return"azure_ai/command-r-plus";else if("Azure"==e)return"my-deployment";else if("Oracle Cloud Infrastructure (OCI)"==e)return"oci/xai.grok-4";else if("Snowflake"==e)return"snowflake/mistral-7b";else if("Voyage AI"==e)return"voyage/";else if("Jina AI"==e)return"jina_ai/";else if("VolcEngine"==e)return"volcengine/<any-model-on-volcengine>";else if("DeepInfra"==e)return"deepinfra/<any-model-on-deepinfra>";else if("Fal AI"==e)return"fal_ai/fal-ai/flux-pro/v1.1-ultra";else if("RunwayML"==e)return"runwayml/gen4_turbo";else if("Watsonx"===e)return"watsonx/ibm/granite-3-3-8b-instruct";else if("Cursor"===e)return"cursor/claude-4-sonnet";else if("Z.AI (Zhipu AI)"===e)return"zai/glm-4.5";else return"gpt-3.5-turbo"},"getProviderLogoAndName",0,e=>{if(!e)return{logo:"",displayName:"-"};if("gemini"===e.toLowerCase()){let e="Google AI Studio";return{logo:n[e],displayName:e}}let t=Object.keys(i).find(t=>i[t].toLowerCase()===e.toLowerCase());if(!t)return{logo:"",displayName:e};let r=a[t];return{logo:n[r],displayName:r}},"getProviderModels",0,(e,t)=>{console.log(`Provider key: ${e}`);let a=i[e];console.log(`Provider mapped to: ${a}`);let r=[];return e&&"object"==typeof t&&(Object.entries(t).forEach(([e,t])=>{if(null!==t&&"object"==typeof t&&"litellm_provider"in t){let i=t.litellm_provider;(i===a||"string"==typeof i&&(i.startsWith(`${a}_`)||i.startsWith(`${a}-`)))&&r.push(e)}}),"Cohere"==e&&(console.log("Adding cohere chat models"),Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"cohere_chat"===t.litellm_provider&&r.push(e)})),"AWS SageMaker"==e&&(console.log("Adding sagemaker chat models"),Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"sagemaker_chat"===t.litellm_provider&&r.push(e)}))),r},"providerLogoMap",0,n,"provider_map",0,i])},185793,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),i=e.i(242064),r=e.i(529681);let n=e=>{let{prefixCls:i,className:r,style:n,size:o,shape:l}=e,s=(0,a.default)({[`${i}-lg`]:"large"===o,[`${i}-sm`]:"small"===o}),p=(0,a.default)({[`${i}-circle`]:"circle"===l,[`${i}-square`]:"square"===l,[`${i}-round`]:"round"===l}),c=t.useMemo(()=>"number"==typeof o?{width:o,height:o,lineHeight:`${o}px`}:{},[o]);return t.createElement("span",{className:(0,a.default)(i,s,p,r),style:Object.assign(Object.assign({},c),n)})};e.i(296059);var o=e.i(694758),l=e.i(915654),s=e.i(246422),p=e.i(838378);let c=new o.Keyframes("ant-skeleton-loading",{"0%":{backgroundPosition:"100% 50%"},"100%":{backgroundPosition:"0 50%"}}),g=e=>({height:e,lineHeight:(0,l.unit)(e)}),u=e=>Object.assign({width:e},g(e)),d=(e,t)=>Object.assign({width:t(e).mul(5).equal(),minWidth:t(e).mul(5).equal()},g(e)),m=e=>Object.assign({width:e},g(e)),f=(e,t,a)=>{let{skeletonButtonCls:i}=e;return{[`${a}${i}-circle`]:{width:t,minWidth:t,borderRadius:"50%"},[`${a}${i}-round`]:{borderRadius:t}}},_=(e,t)=>Object.assign({width:t(e).mul(2).equal(),minWidth:t(e).mul(2).equal()},g(e)),h=(0,s.genStyleHooks)("Skeleton",e=>{let{componentCls:t,calc:a}=e;return(e=>{let{componentCls:t,skeletonAvatarCls:a,skeletonTitleCls:i,skeletonParagraphCls:r,skeletonButtonCls:n,skeletonInputCls:o,skeletonImageCls:l,controlHeight:s,controlHeightLG:p,controlHeightSM:g,gradientFromColor:h,padding:b,marginSM:A,borderRadius:v,titleHeight:O,blockRadius:I,paragraphLiHeight:$,controlHeightXS:E,paragraphMarginTop:C}=e;return{[t]:{display:"table",width:"100%",[`${t}-header`]:{display:"table-cell",paddingInlineEnd:b,verticalAlign:"top",[a]:Object.assign({display:"inline-block",verticalAlign:"top",background:h},u(s)),[`${a}-circle`]:{borderRadius:"50%"},[`${a}-lg`]:Object.assign({},u(p)),[`${a}-sm`]:Object.assign({},u(g))},[`${t}-content`]:{display:"table-cell",width:"100%",verticalAlign:"top",[i]:{width:"100%",height:O,background:h,borderRadius:I,[`+ ${r}`]:{marginBlockStart:g}},[r]:{padding:0,"> li":{width:"100%",height:$,listStyle:"none",background:h,borderRadius:I,"+ li":{marginBlockStart:E}}},[`${r}> li:last-child:not(:first-child):not(:nth-child(2))`]:{width:"61%"}},[`&-round ${t}-content`]:{[`${i}, ${r} > li`]:{borderRadius:v}}},[`${t}-with-avatar ${t}-content`]:{[i]:{marginBlockStart:A,[`+ ${r}`]:{marginBlockStart:C}}},[`${t}${t}-element`]:Object.assign(Object.assign(Object.assign(Object.assign({display:"inline-block",width:"auto"},(e=>{let{borderRadiusSM:t,skeletonButtonCls:a,controlHeight:i,controlHeightLG:r,controlHeightSM:n,gradientFromColor:o,calc:l}=e;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({[a]:Object.assign({display:"inline-block",verticalAlign:"top",background:o,borderRadius:t,width:l(i).mul(2).equal(),minWidth:l(i).mul(2).equal()},_(i,l))},f(e,i,a)),{[`${a}-lg`]:Object.assign({},_(r,l))}),f(e,r,`${a}-lg`)),{[`${a}-sm`]:Object.assign({},_(n,l))}),f(e,n,`${a}-sm`))})(e)),(e=>{let{skeletonAvatarCls:t,gradientFromColor:a,controlHeight:i,controlHeightLG:r,controlHeightSM:n}=e;return{[t]:Object.assign({display:"inline-block",verticalAlign:"top",background:a},u(i)),[`${t}${t}-circle`]:{borderRadius:"50%"},[`${t}${t}-lg`]:Object.assign({},u(r)),[`${t}${t}-sm`]:Object.assign({},u(n))}})(e)),(e=>{let{controlHeight:t,borderRadiusSM:a,skeletonInputCls:i,controlHeightLG:r,controlHeightSM:n,gradientFromColor:o,calc:l}=e;return{[i]:Object.assign({display:"inline-block",verticalAlign:"top",background:o,borderRadius:a},d(t,l)),[`${i}-lg`]:Object.assign({},d(r,l)),[`${i}-sm`]:Object.assign({},d(n,l))}})(e)),(e=>{let{skeletonImageCls:t,imageSizeBase:a,gradientFromColor:i,borderRadiusSM:r,calc:n}=e;return{[t]:Object.assign(Object.assign({display:"inline-flex",alignItems:"center",justifyContent:"center",verticalAlign:"middle",background:i,borderRadius:r},m(n(a).mul(2).equal())),{[`${t}-path`]:{fill:"#bfbfbf"},[`${t}-svg`]:Object.assign(Object.assign({},m(a)),{maxWidth:n(a).mul(4).equal(),maxHeight:n(a).mul(4).equal()}),[`${t}-svg${t}-svg-circle`]:{borderRadius:"50%"}}),[`${t}${t}-circle`]:{borderRadius:"50%"}}})(e)),[`${t}${t}-block`]:{width:"100%",[n]:{width:"100%"},[o]:{width:"100%"}},[`${t}${t}-active`]:{[` | |||
| const [showSurveyModal, setShowSurveyModal] = useState(false); | ||
|
|
||
| // Claude Code feedback state | ||
| const [isClaudeCode, setIsClaudeCode] = useState(false); |
Contributor
|
Too many files changed for review. ( |
|
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Relevant issues
Linear ticket
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
make test-unit@greptileaiand received a Confidence Score of at least 4/5 before requesting a maintainer reviewDelays 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)
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