Merge PR #19596: perf: skip redundant redaction when global redaction enabled

This commit is contained in:
Alexsander Hamir 2026-02-07 11:56:59 -08:00
commit 7960cd7bc9
659 changed files with 8998 additions and 771 deletions

Binary file not shown.

View file

@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "LiteLLM_MCPServerTable" ADD COLUMN "available_on_public_internet" BOOLEAN NOT NULL DEFAULT false;

View file

@ -1,6 +1,6 @@
[tool.poetry]
name = "litellm-proxy-extras"
version = "0.4.31"
version = "0.4.32"
description = "Additional files for the LiteLLM Proxy. Reduces the size of the main litellm package."
authors = ["BerriAI"]
readme = "README.md"
@ -22,7 +22,7 @@ requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.commitizen]
version = "0.4.31"
version = "0.4.32"
version_files = [
"pyproject.toml:version",
"../requirements.txt:litellm-proxy-extras==",

View file

@ -1418,37 +1418,47 @@ def completion_cost( # noqa: PLR0915
# Apply discount from module-level config if configured
original_cost = _final_cost
_final_cost, discount_percent, discount_amount = _apply_cost_discount(
base_cost=_final_cost,
custom_llm_provider=custom_llm_provider,
)
if litellm.cost_discount_config:
_final_cost, discount_percent, discount_amount = _apply_cost_discount(
base_cost=_final_cost,
custom_llm_provider=custom_llm_provider,
)
else:
discount_percent = 0.0
discount_amount = 0.0
# Apply margin from module-level config if configured
(
_final_cost,
margin_percent,
margin_fixed_amount,
margin_total_amount,
) = _apply_cost_margin(
base_cost=_final_cost,
custom_llm_provider=custom_llm_provider,
)
if litellm.cost_margin_config:
(
_final_cost,
margin_percent,
margin_fixed_amount,
margin_total_amount,
) = _apply_cost_margin(
base_cost=_final_cost,
custom_llm_provider=custom_llm_provider,
)
else:
margin_percent = 0.0
margin_fixed_amount = 0.0
margin_total_amount = 0.0
# Store cost breakdown in logging object if available
_store_cost_breakdown_in_logging_obj(
litellm_logging_obj=litellm_logging_obj,
prompt_tokens_cost_usd_dollar=prompt_tokens_cost_usd_dollar,
completion_tokens_cost_usd_dollar=completion_tokens_cost_usd_dollar,
cost_for_built_in_tools_cost_usd_dollar=cost_for_built_in_tools,
total_cost_usd_dollar=_final_cost,
additional_costs=additional_costs,
original_cost=original_cost,
discount_percent=discount_percent,
discount_amount=discount_amount,
margin_percent=margin_percent,
margin_fixed_amount=margin_fixed_amount,
margin_total_amount=margin_total_amount,
)
if litellm_logging_obj is not None:
_store_cost_breakdown_in_logging_obj(
litellm_logging_obj=litellm_logging_obj,
prompt_tokens_cost_usd_dollar=prompt_tokens_cost_usd_dollar,
completion_tokens_cost_usd_dollar=completion_tokens_cost_usd_dollar,
cost_for_built_in_tools_cost_usd_dollar=cost_for_built_in_tools,
total_cost_usd_dollar=_final_cost,
original_cost=original_cost,
additional_costs=additional_costs,
discount_percent=discount_percent,
discount_amount=discount_amount,
margin_percent=margin_percent,
margin_fixed_amount=margin_fixed_amount,
margin_total_amount=margin_total_amount,
)
return _final_cost
except Exception as e:

View file

@ -740,7 +740,9 @@ class CustomLogger: # https://docs.litellm.ai/docs/observability/custom_callbac
return OLD_LITELLM_METADATA_FIELD
def redact_standard_logging_payload_from_model_call_details(
self, model_call_details: Dict
self,
model_call_details: Dict,
global_redaction_applied: bool = False,
) -> Dict:
"""
Only redacts messages and responses when self.turn_off_message_logging is True
@ -752,6 +754,17 @@ class CustomLogger: # https://docs.litellm.ai/docs/observability/custom_callbac
This is useful for logging payloads that contain sensitive information.
"""
# Only skip if global redaction applied AND method is not overridden
if global_redaction_applied:
# Check if method was overridden anywhere in the inheritance chain (walks full MRO)
method_name = "redact_standard_logging_payload_from_model_call_details"
is_overridden = getattr(type(self), method_name) is not getattr(CustomLogger, method_name)
if not is_overridden:
# Safe to skip - using default implementation
return model_call_details
# Method was overridden - might do additional redaction, so proceed
from copy import copy
from litellm import Choices, Message, ModelResponse

View file

@ -68,6 +68,7 @@ from litellm.litellm_core_utils.model_param_helper import ModelParamHelper
from litellm.litellm_core_utils.redact_messages import (
redact_message_input_output_from_custom_logger,
redact_message_input_output_from_logging,
should_redact_message_logging,
)
from litellm.llms.base_llm.ocr.transformation import OCRResponse
from litellm.llms.base_llm.search.transformation import SearchResponse
@ -203,6 +204,10 @@ except Exception as e:
EnterpriseStandardLoggingPayloadSetupVAR = None
_in_memory_loggers: List[Any] = []
_STANDARD_LOGGING_METADATA_KEYS: frozenset = frozenset(
StandardLoggingMetadata.__annotations__.keys()
)
### GLOBAL VARIABLES ###
# Cache custom pricing keys as frozenset for O(1) lookups instead of looping through 49 keys
@ -2492,11 +2497,12 @@ class Logging(LiteLLMLoggingBaseClass):
global_callbacks=litellm._async_success_callback,
)
_model_call_details = self.model_call_details if hasattr(self, "model_call_details") else {}
global_redaction_applied = should_redact_message_logging(_model_call_details)
result = redact_message_input_output_from_logging(
model_call_details=(
self.model_call_details if hasattr(self, "model_call_details") else {}
),
model_call_details=_model_call_details,
result=result,
should_redact=global_redaction_applied,
)
## LOGGING HOOK ##
@ -2521,7 +2527,10 @@ class Logging(LiteLLMLoggingBaseClass):
)
elif isinstance(callback, CustomLogger):
result = redact_message_input_output_from_custom_logger(
result=result, litellm_logging_obj=self, custom_logger=callback
result=result,
litellm_logging_obj=self,
custom_logger=callback,
global_redaction_applied=global_redaction_applied,
)
self.model_call_details, result = await callback.async_logging_hook(
kwargs=self.model_call_details,
@ -2576,7 +2585,8 @@ class Logging(LiteLLMLoggingBaseClass):
##################################
# call redaction hook for custom logger
model_call_details = callback.redact_standard_logging_payload_from_model_call_details(
model_call_details=model_call_details
model_call_details=model_call_details,
global_redaction_applied=global_redaction_applied,
)
##################################
if self.stream is True:
@ -4530,17 +4540,12 @@ class StandardLoggingPayloadSetup:
user_api_key_auth_metadata=None,
)
if isinstance(metadata, dict):
# Filter the metadata dictionary to include only the specified keys
supported_keys = StandardLoggingMetadata.__annotations__.keys()
for key in supported_keys:
if key in metadata:
clean_metadata[key] = metadata[key] # type: ignore
for key in metadata.keys() & _STANDARD_LOGGING_METADATA_KEYS:
clean_metadata[key] = metadata[key] # type: ignore
if metadata.get("user_api_key") is not None:
if is_valid_sha256_hash(str(metadata.get("user_api_key"))):
clean_metadata["user_api_key_hash"] = metadata.get(
"user_api_key"
) # this is the hash
user_api_key = metadata.get("user_api_key")
if user_api_key and isinstance(user_api_key, str) and is_valid_sha256_hash(user_api_key):
clean_metadata["user_api_key_hash"] = user_api_key
_potential_requester_metadata = metadata.get(
"metadata", None
) # check if user passed metadata in the sdk request - e.g. metadata for langsmith logging - https://docs.litellm.ai/docs/observability/langsmith_integration#set-langsmith-fields

View file

@ -30,8 +30,15 @@ else:
def redact_message_input_output_from_custom_logger(
litellm_logging_obj: LiteLLMLoggingObject, result, custom_logger: CustomLogger
litellm_logging_obj: LiteLLMLoggingObject,
result,
custom_logger: CustomLogger,
global_redaction_applied: bool = False,
):
# skip redundant redaction if global redaction was already applied
if global_redaction_applied:
return result
if (
hasattr(custom_logger, "message_logging")
and custom_logger.message_logging is not True
@ -72,6 +79,44 @@ def _redact_responses_api_output(output_items):
summary_item.text = "redacted-by-litellm"
def _redact_standard_logging_object(model_call_details: dict):
"""Redact messages and response inside standard_logging_object if present."""
standard_logging_object = model_call_details.get("standard_logging_object")
if standard_logging_object is None:
return
redacted_str = "redacted-by-litellm"
if standard_logging_object.get("messages") is not None:
standard_logging_object["messages"] = [
{"role": "user", "content": redacted_str}
]
response = standard_logging_object.get("response")
if response is not None:
if isinstance(response, dict) and "output" in response:
# ResponsesAPIResponse format - redact content in output items
if isinstance(response.get("output"), list):
for output_item in response["output"]:
if isinstance(output_item, dict) and "content" in output_item:
if isinstance(output_item["content"], list):
for content_item in output_item["content"]:
if (
isinstance(content_item, dict)
and "text" in content_item
):
content_item["text"] = redacted_str
elif isinstance(response, str):
standard_logging_object["response"] = redacted_str
else:
# Standard ModelResponse dict format
standard_logging_object["response"] = {
"choices": [
{"message": {"content": redacted_str}}
]
}
def perform_redaction(model_call_details: dict, result):
"""
Performs the actual redaction on the logging object and result.
@ -83,6 +128,9 @@ def perform_redaction(model_call_details: dict, result):
model_call_details["prompt"] = ""
model_call_details["input"] = ""
# Redact standard_logging_object if present
_redact_standard_logging_object(model_call_details)
# Redact streaming response
if (
model_call_details.get("stream", False) is True
@ -177,13 +225,18 @@ def should_redact_message_logging(model_call_details: dict) -> bool:
def redact_message_input_output_from_logging(
model_call_details: dict, result, input: Optional[Any] = None
model_call_details: dict,
result,
input: Optional[Any] = None,
should_redact: Optional[bool] = None,
) -> Any:
"""
Removes messages, prompts, input, response from logging. This modifies the data in-place
only redacts when litellm.turn_off_message_logging == True
"""
if should_redact_message_logging(model_call_details):
if should_redact is None:
should_redact = should_redact_message_logging(model_call_details)
if should_redact:
return perform_redaction(model_call_details, result)
return result

View file

@ -99,6 +99,62 @@ if MCP_AVAILABLE:
)
return mcp_auth_header, mcp_server_auth_headers, raw_headers
async def _resolve_allowed_mcp_servers_with_ip_filter(
request: Request,
user_api_key_dict: UserAPIKeyAuth,
server_id: str,
) -> List[MCPServer]:
"""
Resolve allowed MCP servers for a tool call with IP filtering.
Args:
request: The HTTP request object
user_api_key_dict: The user's API key auth object
server_id: The server ID to validate access for
Returns:
List of allowed MCPServer objects
Raises:
HTTPException: If the server_id is not allowed
"""
# Get all auth contexts
auth_contexts = await build_effective_auth_contexts(user_api_key_dict)
# Collect allowed server IDs from all contexts, then apply IP filtering
_rest_client_ip = IPAddressUtils.get_mcp_client_ip(request)
allowed_server_ids_set = set()
for auth_context in auth_contexts:
servers = await global_mcp_server_manager.get_allowed_mcp_servers(
user_api_key_auth=auth_context,
)
allowed_server_ids_set.update(servers)
allowed_server_ids_set = set(
global_mcp_server_manager.filter_server_ids_by_ip(
list(allowed_server_ids_set), _rest_client_ip
)
)
# Check if the specified server_id is allowed
if server_id not in allowed_server_ids_set:
raise HTTPException(
status_code=403,
detail={
"error": "access_denied",
"message": f"The key is not allowed to access server {server_id}",
},
)
# Build allowed_mcp_servers list (only include allowed servers)
allowed_mcp_servers: List[MCPServer] = []
for allowed_server_id in allowed_server_ids_set:
server = global_mcp_server_manager.get_mcp_server_by_id(allowed_server_id)
if server is not None:
allowed_mcp_servers.append(server)
return allowed_mcp_servers
async def _get_tools_for_single_server(
server,
server_auth_header,
@ -381,43 +437,11 @@ if MCP_AVAILABLE:
if "metadata" in data and "user_api_key_auth" in data["metadata"]:
data["user_api_key_auth"] = data["metadata"]["user_api_key_auth"]
# Get all auth contexts
auth_contexts = await build_effective_auth_contexts(user_api_key_dict)
# Collect allowed server IDs from all contexts, then apply IP filtering
_rest_client_ip = IPAddressUtils.get_mcp_client_ip(request)
allowed_server_ids_set = set()
for auth_context in auth_contexts:
servers = await global_mcp_server_manager.get_allowed_mcp_servers(
user_api_key_auth=auth_context,
)
allowed_server_ids_set.update(servers)
allowed_server_ids_set = set(
global_mcp_server_manager.filter_server_ids_by_ip(
list(allowed_server_ids_set), _rest_client_ip
)
# Resolve allowed MCP servers with IP filtering
allowed_mcp_servers = await _resolve_allowed_mcp_servers_with_ip_filter(
request, user_api_key_dict, server_id
)
# Check if the specified server_id is allowed
if server_id not in allowed_server_ids_set:
raise HTTPException(
status_code=403,
detail={
"error": "access_denied",
"message": f"The key is not allowed to access server {server_id}",
},
)
# Build allowed_mcp_servers list (only include allowed servers)
allowed_mcp_servers: List[MCPServer] = []
for allowed_server_id in allowed_server_ids_set:
server = global_mcp_server_manager.get_mcp_server_by_id(
allowed_server_id
)
if server is not None:
allowed_mcp_servers.append(server)
# Call execute_mcp_tool directly (permission checks already done)
result = await execute_mcp_tool(
name=tool_name,

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,30 @@
1:"$Sreact.fragment"
2:I[347257,["/litellm-asset-prefix/_next/static/chunks/d96012bcfc98706a.js","/litellm-asset-prefix/_next/static/chunks/dbca964212122d58.js"],"ClientPageRoot"]
3:I[952683,["/litellm-asset-prefix/_next/static/chunks/26adfa4e8ffc85c7.js","/litellm-asset-prefix/_next/static/chunks/e8ed72789c2b42ff.js","/litellm-asset-prefix/_next/static/chunks/0a6c418370a8c183.js","/litellm-asset-prefix/_next/static/chunks/4cd6ff0dfce62b8e.js","/litellm-asset-prefix/_next/static/chunks/4a4dedb94a06b61d.js","/litellm-asset-prefix/_next/static/chunks/1b1b0930772e484a.js","/litellm-asset-prefix/_next/static/chunks/fbc296c4562eeddc.js","/litellm-asset-prefix/_next/static/chunks/e99e2eb6c969ac42.js","/litellm-asset-prefix/_next/static/chunks/5f9c3b92a016f382.js","/litellm-asset-prefix/_next/static/chunks/e04f5de552319954.js","/litellm-asset-prefix/_next/static/chunks/f56edde1dfbfa5c2.js","/litellm-asset-prefix/_next/static/chunks/403c4d96324c23a6.js","/litellm-asset-prefix/_next/static/chunks/4a74699f9b25ffd8.js","/litellm-asset-prefix/_next/static/chunks/0a671fedee641c02.js","/litellm-asset-prefix/_next/static/chunks/3b30ab8eaa03bc21.js","/litellm-asset-prefix/_next/static/chunks/fe750aa0bf04912c.js","/litellm-asset-prefix/_next/static/chunks/7b788dd93ad868b3.js","/litellm-asset-prefix/_next/static/chunks/d64d74932cb225a3.js","/litellm-asset-prefix/_next/static/chunks/6930557cf99ba2ed.js","/litellm-asset-prefix/_next/static/chunks/95015f87c824f421.js","/litellm-asset-prefix/_next/static/chunks/64f1a2ef9113d86f.js","/litellm-asset-prefix/_next/static/chunks/87a251aeda49f573.js","/litellm-asset-prefix/_next/static/chunks/33b32c9f63756046.js","/litellm-asset-prefix/_next/static/chunks/88c74f8b4b20d25a.js","/litellm-asset-prefix/_next/static/chunks/c52ccee83fcf13d9.js","/litellm-asset-prefix/_next/static/chunks/acb2890475c0e12c.js","/litellm-asset-prefix/_next/static/chunks/18268b188d85d0d8.js","/litellm-asset-prefix/_next/static/chunks/b720ff808b5789ef.js","/litellm-asset-prefix/_next/static/chunks/008c46047ca6ae0a.js","/litellm-asset-prefix/_next/static/chunks/3754e5316d782fdf.js","/litellm-asset-prefix/_next/static/chunks/c4452a79c69324a6.js","/litellm-asset-prefix/_next/static/chunks/7e417dd24c8becd0.js","/litellm-asset-prefix/_next/static/chunks/c7b74067c01ee971.js","/litellm-asset-prefix/_next/static/chunks/e9a81ef6cd35a613.js","/litellm-asset-prefix/_next/static/chunks/4980372eaa37b78b.js","/litellm-asset-prefix/_next/static/chunks/ba3f0517ce70ce68.js","/litellm-asset-prefix/_next/static/chunks/79738bf720f4be4d.js","/litellm-asset-prefix/_next/static/chunks/a5b66d8611aefbcd.js","/litellm-asset-prefix/_next/static/chunks/00ff280cdb7d7ee5.js","/litellm-asset-prefix/_next/static/chunks/0a65da2cd24e2ab6.js","/litellm-asset-prefix/_next/static/chunks/554b4994eea1cb97.js","/litellm-asset-prefix/_next/static/chunks/b32c07bb80491ab6.js","/litellm-asset-prefix/_next/static/chunks/a382857dbbcea5d1.js","/litellm-asset-prefix/_next/static/chunks/0b27adb95e5b531e.js","/litellm-asset-prefix/_next/static/chunks/df9bbd7990a5fafe.js","/litellm-asset-prefix/_next/static/chunks/496b84010c33cf69.js","/litellm-asset-prefix/_next/static/chunks/2971c4658f1bcd7d.js","/litellm-asset-prefix/_next/static/chunks/6c4c97f1ea6e7d77.js","/litellm-asset-prefix/_next/static/chunks/8e1e9d99970e681d.js","/litellm-asset-prefix/_next/static/chunks/8354d717e34ebd6f.js","/litellm-asset-prefix/_next/static/chunks/8927d9c0b6434f68.js","/litellm-asset-prefix/_next/static/chunks/368fa3a0a47b3cb5.js","/litellm-asset-prefix/_next/static/chunks/8fb6b3333e6465c3.js","/litellm-asset-prefix/_next/static/chunks/450ebd094f4fa24d.js","/litellm-asset-prefix/_next/static/chunks/e8aec000aaa33bd3.js"],"default"]
1a:I[897367,["/litellm-asset-prefix/_next/static/chunks/d96012bcfc98706a.js","/litellm-asset-prefix/_next/static/chunks/dbca964212122d58.js"],"OutletBoundary"]
1b:"$Sreact.suspense"
:HL["/litellm-asset-prefix/_next/static/chunks/3f3fa56b5786d58c.css","style"]
0:{"buildId":"5d4yNl8wNnid2iuIZ_SiS","rsc":["$","$1","c",{"children":[["$","$L2",null,{"Component":"$3","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@4","$@5"]}}],[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/3f3fa56b5786d58c.css","precedence":"next"}],["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/0a6c418370a8c183.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/4cd6ff0dfce62b8e.js","async":true}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/4a4dedb94a06b61d.js","async":true}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/1b1b0930772e484a.js","async":true}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/fbc296c4562eeddc.js","async":true}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/e99e2eb6c969ac42.js","async":true}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/5f9c3b92a016f382.js","async":true}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/e04f5de552319954.js","async":true}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/f56edde1dfbfa5c2.js","async":true}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/403c4d96324c23a6.js","async":true}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/4a74699f9b25ffd8.js","async":true}],["$","script","script-11",{"src":"/litellm-asset-prefix/_next/static/chunks/0a671fedee641c02.js","async":true}],["$","script","script-12",{"src":"/litellm-asset-prefix/_next/static/chunks/3b30ab8eaa03bc21.js","async":true}],["$","script","script-13",{"src":"/litellm-asset-prefix/_next/static/chunks/fe750aa0bf04912c.js","async":true}],["$","script","script-14",{"src":"/litellm-asset-prefix/_next/static/chunks/7b788dd93ad868b3.js","async":true}],["$","script","script-15",{"src":"/litellm-asset-prefix/_next/static/chunks/d64d74932cb225a3.js","async":true}],["$","script","script-16",{"src":"/litellm-asset-prefix/_next/static/chunks/6930557cf99ba2ed.js","async":true}],["$","script","script-17",{"src":"/litellm-asset-prefix/_next/static/chunks/95015f87c824f421.js","async":true}],["$","script","script-18",{"src":"/litellm-asset-prefix/_next/static/chunks/64f1a2ef9113d86f.js","async":true}],["$","script","script-19",{"src":"/litellm-asset-prefix/_next/static/chunks/87a251aeda49f573.js","async":true}],["$","script","script-20",{"src":"/litellm-asset-prefix/_next/static/chunks/33b32c9f63756046.js","async":true}],["$","script","script-21",{"src":"/litellm-asset-prefix/_next/static/chunks/88c74f8b4b20d25a.js","async":true}],["$","script","script-22",{"src":"/litellm-asset-prefix/_next/static/chunks/c52ccee83fcf13d9.js","async":true}],["$","script","script-23",{"src":"/litellm-asset-prefix/_next/static/chunks/acb2890475c0e12c.js","async":true}],["$","script","script-24",{"src":"/litellm-asset-prefix/_next/static/chunks/18268b188d85d0d8.js","async":true}],["$","script","script-25",{"src":"/litellm-asset-prefix/_next/static/chunks/b720ff808b5789ef.js","async":true}],["$","script","script-26",{"src":"/litellm-asset-prefix/_next/static/chunks/008c46047ca6ae0a.js","async":true}],["$","script","script-27",{"src":"/litellm-asset-prefix/_next/static/chunks/3754e5316d782fdf.js","async":true}],["$","script","script-28",{"src":"/litellm-asset-prefix/_next/static/chunks/c4452a79c69324a6.js","async":true}],["$","script","script-29",{"src":"/litellm-asset-prefix/_next/static/chunks/7e417dd24c8becd0.js","async":true}],["$","script","script-30",{"src":"/litellm-asset-prefix/_next/static/chunks/c7b74067c01ee971.js","async":true}],["$","script","script-31",{"src":"/litellm-asset-prefix/_next/static/chunks/e9a81ef6cd35a613.js","async":true}],["$","script","script-32",{"src":"/litellm-asset-prefix/_next/static/chunks/4980372eaa37b78b.js","async":true}],["$","script","script-33",{"src":"/litellm-asset-prefix/_next/static/chunks/ba3f0517ce70ce68.js","async":true}],"$L6","$L7","$L8","$L9","$La","$Lb","$Lc","$Ld","$Le","$Lf","$L10","$L11","$L12","$L13","$L14","$L15","$L16","$L17","$L18"],"$L19"]}],"loading":null,"isPartial":false}
4:{}
5:"$0:rsc:props:children:0:props:serverProvidedParams:params"
6:["$","script","script-34",{"src":"/litellm-asset-prefix/_next/static/chunks/79738bf720f4be4d.js","async":true}]
7:["$","script","script-35",{"src":"/litellm-asset-prefix/_next/static/chunks/a5b66d8611aefbcd.js","async":true}]
8:["$","script","script-36",{"src":"/litellm-asset-prefix/_next/static/chunks/00ff280cdb7d7ee5.js","async":true}]
9:["$","script","script-37",{"src":"/litellm-asset-prefix/_next/static/chunks/0a65da2cd24e2ab6.js","async":true}]
a:["$","script","script-38",{"src":"/litellm-asset-prefix/_next/static/chunks/554b4994eea1cb97.js","async":true}]
b:["$","script","script-39",{"src":"/litellm-asset-prefix/_next/static/chunks/b32c07bb80491ab6.js","async":true}]
c:["$","script","script-40",{"src":"/litellm-asset-prefix/_next/static/chunks/a382857dbbcea5d1.js","async":true}]
d:["$","script","script-41",{"src":"/litellm-asset-prefix/_next/static/chunks/0b27adb95e5b531e.js","async":true}]
e:["$","script","script-42",{"src":"/litellm-asset-prefix/_next/static/chunks/df9bbd7990a5fafe.js","async":true}]
f:["$","script","script-43",{"src":"/litellm-asset-prefix/_next/static/chunks/496b84010c33cf69.js","async":true}]
10:["$","script","script-44",{"src":"/litellm-asset-prefix/_next/static/chunks/2971c4658f1bcd7d.js","async":true}]
11:["$","script","script-45",{"src":"/litellm-asset-prefix/_next/static/chunks/6c4c97f1ea6e7d77.js","async":true}]
12:["$","script","script-46",{"src":"/litellm-asset-prefix/_next/static/chunks/8e1e9d99970e681d.js","async":true}]
13:["$","script","script-47",{"src":"/litellm-asset-prefix/_next/static/chunks/8354d717e34ebd6f.js","async":true}]
14:["$","script","script-48",{"src":"/litellm-asset-prefix/_next/static/chunks/8927d9c0b6434f68.js","async":true}]
15:["$","script","script-49",{"src":"/litellm-asset-prefix/_next/static/chunks/368fa3a0a47b3cb5.js","async":true}]
16:["$","script","script-50",{"src":"/litellm-asset-prefix/_next/static/chunks/8fb6b3333e6465c3.js","async":true}]
17:["$","script","script-51",{"src":"/litellm-asset-prefix/_next/static/chunks/450ebd094f4fa24d.js","async":true}]
18:["$","script","script-52",{"src":"/litellm-asset-prefix/_next/static/chunks/e8aec000aaa33bd3.js","async":true}]
19:["$","$L1a",null,{"children":["$","$1b",null,{"name":"Next.MetadataOutlet","children":"$@1c"}]}]
1c:null

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,6 @@
1:"$Sreact.fragment"
2:I[897367,["/litellm-asset-prefix/_next/static/chunks/d96012bcfc98706a.js","/litellm-asset-prefix/_next/static/chunks/dbca964212122d58.js"],"ViewportBoundary"]
3:I[897367,["/litellm-asset-prefix/_next/static/chunks/d96012bcfc98706a.js","/litellm-asset-prefix/_next/static/chunks/dbca964212122d58.js"],"MetadataBoundary"]
4:"$Sreact.suspense"
5:I[27201,["/litellm-asset-prefix/_next/static/chunks/d96012bcfc98706a.js","/litellm-asset-prefix/_next/static/chunks/dbca964212122d58.js"],"IconMark"]
0:{"buildId":"5d4yNl8wNnid2iuIZ_SiS","rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"LiteLLM Dashboard"}],["$","meta","1",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","2",{"rel":"icon","href":"/favicon.ico?favicon.1d32c690.ico","sizes":"48x48","type":"image/x-icon"}],["$","link","3",{"rel":"icon","href":"./favicon.ico"}],["$","$L5","4",{}]]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"loading":null,"isPartial":false}

View file

@ -0,0 +1,7 @@
1:"$Sreact.fragment"
2:I[71195,["/litellm-asset-prefix/_next/static/chunks/26adfa4e8ffc85c7.js","/litellm-asset-prefix/_next/static/chunks/e8ed72789c2b42ff.js"],"default"]
3:I[339756,["/litellm-asset-prefix/_next/static/chunks/d96012bcfc98706a.js","/litellm-asset-prefix/_next/static/chunks/dbca964212122d58.js"],"default"]
4:I[837457,["/litellm-asset-prefix/_next/static/chunks/d96012bcfc98706a.js","/litellm-asset-prefix/_next/static/chunks/dbca964212122d58.js"],"default"]
:HL["/litellm-asset-prefix/_next/static/chunks/4e20891f2fd03463.css","style"]
:HL["/litellm-asset-prefix/_next/static/chunks/da873dd93f7630eb.css","style"]
0:{"buildId":"5d4yNl8wNnid2iuIZ_SiS","rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/4e20891f2fd03463.css","precedence":"next"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/da873dd93f7630eb.css","precedence":"next"}],["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/26adfa4e8ffc85c7.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/e8ed72789c2b42ff.js","async":true}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"inter_5972bc34-module__OU16Qa__className","children":["$","$L2",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","template":["$","$L4",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}]}]}]]}],"loading":null,"isPartial":false}

View file

@ -0,0 +1,5 @@
:HL["/litellm-asset-prefix/_next/static/chunks/4e20891f2fd03463.css","style"]
:HL["/litellm-asset-prefix/_next/static/chunks/da873dd93f7630eb.css","style"]
:HL["/litellm-asset-prefix/_next/static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
:HL["/litellm-asset-prefix/_next/static/chunks/3f3fa56b5786d58c.css","style"]
0:{"buildId":"5d4yNl8wNnid2iuIZ_SiS","tree":{"name":"","paramType":null,"paramKey":"","hasRuntimePrefetch":false,"slots":{"children":{"name":"__PAGE__","paramType":null,"paramKey":"__PAGE__","hasRuntimePrefetch":false,"slots":null,"isRootLayout":false}},"isRootLayout":true},"staleTime":300}

View file

@ -0,0 +1,16 @@
self.__BUILD_MANIFEST = {
"__rewrites": {
"afterFiles": [],
"beforeFiles": [
{
"source": "/litellm-asset-prefix/_next/:path+",
"destination": "/_next/:path+"
}
],
"fallback": []
},
"sortedPages": [
"/_app",
"/_error"
]
};self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,618566,(e,t,s)=>{t.exports=e.r(976562)},346328,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(618566);let a=()=>{let e=(0,l.useSearchParams)(),a=(0,s.useMemo)(()=>e?{type:"litellm-mcp-oauth",code:e.get("code"),state:e.get("state")}:null,[e]);return(0,s.useEffect)(()=>{if(!a)return;try{window.sessionStorage.setItem("litellm-mcp-oauth-result",JSON.stringify(a))}catch(e){console.error("Failed to persist OAuth callback payload",e)}let e=window.sessionStorage.getItem("litellm-mcp-oauth-return-url");console.info("[MCP OAuth callback] returnUrl",e);let t=e||(()=>{let e=window.location.pathname||"",t=e.indexOf("/ui");if(t>=0){let s=e.slice(0,t+3);return s.endsWith("/")?s:`${s}`}return"/"})();window.location.replace(t)},[a]),(0,t.jsx)("div",{className:"min-h-screen flex items-center justify-center bg-slate-50 p-6",children:(0,t.jsxs)("div",{className:"max-w-lg w-full rounded-lg bg-white shadow-md p-8 text-center space-y-4",children:[(0,t.jsx)("h1",{className:"text-xl font-semibold text-slate-900",children:"LiteLLM MCP OAuth"}),(0,t.jsx)("p",{className:"text-sm text-slate-700",children:"Authorization complete. You may close this window and return to the LiteLLM dashboard."}),(0,t.jsx)("p",{className:"text-xs text-slate-500",children:"If the window does not close automatically, everything is still saved—you can close it manually."})]})})};e.s(["default",0,()=>(0,t.jsx)(s.Suspense,{fallback:(0,t.jsx)("div",{className:"min-h-screen flex items-center justify-center",children:"Loading..."}),children:(0,t.jsx)(a,{})})])}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,949616,t=>{"use strict";function r(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=Array(r);e<r;e++)n[e]=t[e];return n}t.s(["default",()=>r])},713882,t=>{"use strict";var r=t.i(949616);function e(t,e){if(t){if("string"==typeof t)return(0,r.default)(t,e);var n=({}).toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?(0,r.default)(t,e):void 0}}t.s(["default",()=>e])},410160,t=>{"use strict";function r(t){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}t.s(["default",()=>r])},211577,394257,t=>{"use strict";var r=t.i(410160);function e(t){var e=function(t,e){if("object"!=(0,r.default)(t)||!t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var i=n.call(t,e||"default");if("object"!=(0,r.default)(i))return i;throw TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==(0,r.default)(e)?e:e+""}function n(t,r,n){return(r=e(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}t.s(["default",()=>e],394257),t.s(["default",()=>n],211577)},308665,962837,t=>{"use strict";var r=t.i(949616);function e(t){if(Array.isArray(t))return(0,r.default)(t)}function n(t){if("u">typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}t.s(["default",()=>e],308665),t.s(["default",()=>n],962837)},8211,t=>{"use strict";var r=t.i(308665),e=t.i(962837),n=t.i(713882);function i(t){return(0,r.default)(t)||(0,e.default)(t)||(0,n.default)(t)||function(){throw TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}t.s(["default",()=>i],8211)},915874,t=>{"use strict";function r(t,r){if(null==t)return{};var e={};for(var n in t)if(({}).hasOwnProperty.call(t,n)){if(-1!==r.indexOf(n))continue;e[n]=t[n]}return e}t.s(["default",()=>r])},703923,t=>{"use strict";var r=t.i(915874);function e(t,e){if(null==t)return{};var n,i,u=(0,r.default)(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(i=0;i<o.length;i++)n=o[i],-1===e.indexOf(n)&&({}).propertyIsEnumerable.call(t,n)&&(u[n]=t[n])}return u}t.s(["default",()=>e])},931067,t=>{"use strict";function r(){return(r=Object.assign.bind()).apply(null,arguments)}t.s(["default",()=>r])},71195,t=>{"use strict";var r=t.i(843476),e=t.i(271645),n=t.i(698173),i=t.i(727749);function u({children:t}){let[u,o]=n.notification.useNotification(),a=(0,e.useRef)(!1);return(0,e.useEffect)(()=>{a.current||((0,i.setNotificationInstance)(u),a.current=!0)},[u]),(0,r.jsxs)(r.Fragment,{children:[o,t]})}t.s(["default",()=>u])}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,526612,e=>{"use strict";var t=e.i(843476),s=e.i(846835),i=e.i(135214),r=e.i(271645),o=e.i(702597);e.s(["default",0,()=>{let{userId:e,accessToken:u,userRole:a,premiumUser:n}=(0,i.default)(),[c,l]=(0,r.useState)([]),[f,d]=(0,r.useState)([]);return(0,r.useEffect)(()=>{(0,s.fetchOrganizations)(u,l).then(()=>{})},[u]),(0,r.useEffect)(()=>{(0,o.fetchUserModels)(e,a,u,d).then(()=>{})},[e,a,u]),(0,t.jsx)(s.default,{organizations:c,userRole:a,userModels:f,accessToken:u,setOrganizations:l,premiumUser:n})}])},601236,e=>{e.v(e=>Promise.resolve().then(()=>e(764205)))}]);

View file

@ -0,0 +1 @@
._GzYRV{white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word;line-height:1.2}._3eOF8{margin-right:5px;font-weight:700}._3eOF8+._3eOF8{margin-left:-5px}._1MFti{cursor:pointer}._f10Tu{-webkit-user-select:none;user-select:none;margin-right:5px;font-size:1.2em}._1UmXx:after{content:"▸"}._1LId0:after{content:"▾"}._1pNG9{margin-right:5px}._1pNG9:after{content:"...";font-size:.8em}._2IvMF{background:#eee}._2bkNM{margin:0;padding:0 10px}._1BXBN{margin:0;padding:0}._1MGIk{color:#000;margin-right:5px;font-weight:600}._3uHL6{color:#000}._2T6PJ,._1Gho6{color:#df113a}._vGjyY{color:#2a3f3c}._1bQdo{color:#0b75f5}._3zQKs{color:#469038}._1xvuR{color:#43413d}._oLqym,._2AXVT,._2KJWg{color:#000}._11RoI{background:#002b36}._17H2C,._3QHg2,._3fDAz{color:#fdf6e3}._2bSDX{color:#fdf6e3;margin-right:5px;font-weight:bolder}._gsbQL{color:#fdf6e3}._LaAZe,._GTKgm{color:#81b5ac}._Chy1W{color:#cb4b16}._2bveF{color:#d33682}._2vRm-{color:#ae81ff}._1prJR{color:#268bd2}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show more