diff --git a/litellm/__init__.py b/litellm/__init__.py index 3b67d9e0021..ee177876825 100644 --- a/litellm/__init__.py +++ b/litellm/__init__.py @@ -148,6 +148,7 @@ _custom_logger_compatible_callbacks_literal = Literal[ "vantage", "posthog", "levo", + "aliyun_sls", ] cold_storage_custom_logger: Optional[_custom_logger_compatible_callbacks_literal] = None logged_real_time_event_types: Optional[Union[List[str], Literal["*"]]] = None @@ -168,12 +169,12 @@ prometheus_latency_buckets: Optional[List[float]] = None require_auth_for_metrics_endpoint: Optional[bool] = False argilla_batch_size: Optional[int] = None datadog_use_v1: Optional[bool] = False # if you want to use v1 datadog logged payload. -gcs_pub_sub_use_v1: Optional[ - bool -] = False # if you want to use v1 gcs pubsub logged payload -generic_api_use_v1: Optional[ - bool -] = False # if you want to use v1 generic api logged payload +gcs_pub_sub_use_v1: Optional[bool] = ( + False # if you want to use v1 gcs pubsub logged payload +) +generic_api_use_v1: Optional[bool] = ( + False # if you want to use v1 generic api logged payload +) argilla_transformation_object: Optional[Dict[str, Any]] = None _async_input_callback: List[ Union[str, Callable, "CustomLogger"] @@ -193,26 +194,26 @@ _async_failure_callback: List[ pre_call_rules: List[Callable] = [] post_call_rules: List[Callable] = [] turn_off_message_logging: Optional[bool] = False -standard_logging_payload_excluded_fields: Optional[ - List[str] -] = None # Fields to exclude from StandardLoggingPayload before callbacks receive it +standard_logging_payload_excluded_fields: Optional[List[str]] = ( + None # Fields to exclude from StandardLoggingPayload before callbacks receive it +) log_raw_request_response: bool = False redact_messages_in_exceptions: Optional[bool] = False redact_user_api_key_info: Optional[bool] = False filter_invalid_headers: Optional[bool] = False -add_user_information_to_llm_headers: Optional[ - bool -] = None # adds user_id, team_id, token hash (params from StandardLoggingMetadata) to request headers +add_user_information_to_llm_headers: Optional[bool] = ( + None # adds user_id, team_id, token hash (params from StandardLoggingMetadata) to request headers +) store_audit_logs = False # Enterprise feature, allow users to see audit logs skip_system_message_in_guardrail: bool = False ### end of callbacks ############# -email: Optional[ - str -] = None # Not used anymore, will be removed in next MAJOR release - https://github.com/BerriAI/litellm/discussions/648 -token: Optional[ - str -] = None # Not used anymore, will be removed in next MAJOR release - https://github.com/BerriAI/litellm/discussions/648 +email: Optional[str] = ( + None # Not used anymore, will be removed in next MAJOR release - https://github.com/BerriAI/litellm/discussions/648 +) +token: Optional[str] = ( + None # Not used anymore, will be removed in next MAJOR release - https://github.com/BerriAI/litellm/discussions/648 +) telemetry = True max_tokens: int = DEFAULT_MAX_TOKENS # OpenAI Defaults drop_params = bool(os.getenv("LITELLM_DROP_PARAMS", False)) @@ -274,9 +275,9 @@ use_client: bool = False ssl_verify: Union[str, bool] = True ssl_security_level: Optional[str] = None ssl_certificate: Optional[str] = None -ssl_ecdh_curve: Optional[ - str -] = None # Set to 'X25519' to disable PQC and improve performance +ssl_ecdh_curve: Optional[str] = ( + None # Set to 'X25519' to disable PQC and improve performance +) disable_streaming_logging: bool = False disable_token_counter: bool = False disable_add_transform_inline_image_block: bool = False @@ -330,20 +331,24 @@ enable_loadbalancing_on_batch_endpoints: Optional[bool] = None enable_caching_on_provider_specific_optional_params: bool = ( False # feature-flag for caching on optional params - e.g. 'top_k' ) -caching: bool = False # Not used anymore, will be removed in next MAJOR release - https://github.com/BerriAI/litellm/discussions/648 -caching_with_models: bool = False # # Not used anymore, will be removed in next MAJOR release - https://github.com/BerriAI/litellm/discussions/648 -cache: Optional[ - "Cache" -] = None # cache object <- use this - https://docs.litellm.ai/docs/caching +caching: bool = ( + False # Not used anymore, will be removed in next MAJOR release - https://github.com/BerriAI/litellm/discussions/648 +) +caching_with_models: bool = ( + False # # Not used anymore, will be removed in next MAJOR release - https://github.com/BerriAI/litellm/discussions/648 +) +cache: Optional["Cache"] = ( + None # cache object <- use this - https://docs.litellm.ai/docs/caching +) default_in_memory_ttl: Optional[float] = None default_redis_ttl: Optional[float] = None default_redis_batch_cache_expiry: Optional[float] = None model_alias_map: Dict[str, str] = {} model_group_settings: Optional["ModelGroupSettings"] = None max_budget: float = 0.0 # set the max budget across all providers -budget_duration: Optional[ - str -] = None # proxy only - resets budget after fixed duration. You can set duration as seconds ("30s"), minutes ("30m"), hours ("30h"), days ("30d"). +budget_duration: Optional[str] = ( + None # proxy only - resets budget after fixed duration. You can set duration as seconds ("30s"), minutes ("30m"), hours ("30h"), days ("30d"). +) default_soft_budget: float = ( DEFAULT_SOFT_BUDGET # by default all litellm proxy keys have a soft budget of 50.0 ) @@ -352,7 +357,9 @@ forward_traceparent_to_llm_provider: bool = False _current_cost = 0.0 # private variable, used if max budget is set error_logs: Dict = {} -add_function_to_prompt: bool = False # if function calling not supported by api, append function call details to system prompt +add_function_to_prompt: bool = ( + False # if function calling not supported by api, append function call details to system prompt +) client_session: Optional[httpx.Client] = None aclient_session: Optional[httpx.AsyncClient] = None model_fallbacks: Optional[List] = None # Deprecated for 'litellm.fallbacks' @@ -371,6 +378,7 @@ anthropic_beta_headers_url: str = os.getenv( suppress_debug_info = False dynamodb_table_name: Optional[str] = None s3_callback_params: Optional[Dict] = None +aliyun_sls_callback_params: Optional[Dict] = None datadog_llm_observability_params: Optional[Union[DatadogLLMObsInitParams, Dict]] = None datadog_params: Optional[Union[DatadogInitParams, Dict]] = None aws_sqs_callback_params: Optional[Dict] = None @@ -399,7 +407,9 @@ prometheus_emit_stream_label: bool = False disable_add_prefix_to_prompt: bool = ( False # used by anthropic, to disable adding prefix to prompt ) -disable_copilot_system_to_assistant: bool = False # If false (default), converts all 'system' role messages to 'assistant' for GitHub Copilot compatibility. Set to true to disable this behavior. +disable_copilot_system_to_assistant: bool = ( + False # If false (default), converts all 'system' role messages to 'assistant' for GitHub Copilot compatibility. Set to true to disable this behavior. +) public_mcp_servers: Optional[List[str]] = None public_model_groups: Optional[List[str]] = None public_agent_groups: Optional[List[str]] = None @@ -408,9 +418,9 @@ public_agent_groups: Optional[List[str]] = None # Old format: { "displayName": "url" } (for backward compatibility) public_model_groups_links: Dict[str, Union[str, Dict[str, Any]]] = {} #### REQUEST PRIORITIZATION ####### -priority_reservation: Optional[ - Dict[str, Union[float, "PriorityReservationDict"]] -] = None +priority_reservation: Optional[Dict[str, Union[float, "PriorityReservationDict"]]] = ( + None +) # priority_reservation_settings is lazy-loaded via __getattr__ # Only declare for type checking - at runtime __getattr__ handles it if TYPE_CHECKING: @@ -418,13 +428,17 @@ if TYPE_CHECKING: ######## Networking Settings ######## -use_aiohttp_transport: bool = True # Older variable, aiohttp is now the default. use disable_aiohttp_transport instead. +use_aiohttp_transport: bool = ( + True # Older variable, aiohttp is now the default. use disable_aiohttp_transport instead. +) aiohttp_trust_env: bool = False # set to true to use HTTP_ Proxy settings disable_aiohttp_transport: bool = False # Set this to true to use httpx instead disable_aiohttp_trust_env: bool = ( False # When False, aiohttp will respect HTTP(S)_PROXY env vars ) -force_ipv4: bool = False # when True, litellm will force ipv4 for all LLM requests. Some users have seen httpx ConnectionError when using ipv6. +force_ipv4: bool = ( + False # when True, litellm will force ipv4 for all LLM requests. Some users have seen httpx ConnectionError when using ipv6. +) network_mock: bool = False # When True, use mock transport — no real network calls ####### STOP SEQUENCE LIMIT ####### @@ -439,13 +453,13 @@ context_window_fallbacks: Optional[List] = None content_policy_fallbacks: Optional[List] = None allowed_fails: int = 3 allow_dynamic_callback_disabling: bool = True -num_retries_per_request: Optional[ - int -] = None # for the request overall (incl. fallbacks + model retries) +num_retries_per_request: Optional[int] = ( + None # for the request overall (incl. fallbacks + model retries) +) ####### SECRET MANAGERS ##################### -secret_manager_client: Optional[ - Any -] = None # list of instantiated key management clients - e.g. azure kv, infisical, etc. +secret_manager_client: Optional[Any] = ( + None # list of instantiated key management clients - e.g. azure kv, infisical, etc. +) _google_kms_resource_name: Optional[str] = None _key_management_system: Optional["KeyManagementSystem"] = None # Note: KeyManagementSettings must be eagerly imported because _key_management_settings @@ -458,12 +472,12 @@ output_parse_pii: bool = False from litellm.litellm_core_utils.get_model_cost_map import get_model_cost_map model_cost = get_model_cost_map(url=model_cost_map_url) -cost_discount_config: Dict[ - str, float -] = {} # Provider-specific cost discounts {"vertex_ai": 0.05} = 5% discount -cost_margin_config: Dict[ - str, Union[float, Dict[str, float]] -] = {} # Provider-specific or global cost margins. Examples: +cost_discount_config: Dict[str, float] = ( + {} +) # Provider-specific cost discounts {"vertex_ai": 0.05} = 5% discount +cost_margin_config: Dict[str, Union[float, Dict[str, float]]] = ( + {} +) # Provider-specific or global cost margins. Examples: # Percentage: {"openai": 0.10} = 10% margin # Fixed: {"openai": {"fixed_amount": 0.001}} = $0.001 per request # Global: {"global": 0.05} = 5% global margin on all providers @@ -1313,12 +1327,12 @@ from . import rag from .types.llms.custom_llm import CustomLLMItem custom_provider_map: List[CustomLLMItem] = [] -_custom_providers: List[ - str -] = [] # internal helper util, used to track names of custom providers -disable_hf_tokenizer_download: Optional[ - bool -] = None # disable huggingface tokenizer download. Defaults to openai clk100 +_custom_providers: List[str] = ( + [] +) # internal helper util, used to track names of custom providers +disable_hf_tokenizer_download: Optional[bool] = ( + None # disable huggingface tokenizer download. Defaults to openai clk100 +) global_disable_no_log_param: bool = False ### CLI UTILITIES ### diff --git a/litellm/integrations/aliyun_sls.py b/litellm/integrations/aliyun_sls.py new file mode 100644 index 00000000000..144f57ace01 --- /dev/null +++ b/litellm/integrations/aliyun_sls.py @@ -0,0 +1,143 @@ +""" +Aliyun SLS (Simple Log Service) logging integration. + +Configuration via litellm.aliyun_sls_callback_params or environment variables: + aliyun_sls_region - Region ID, e.g. cn-hangzhou + aliyun_sls_project - SLS project name + aliyun_sls_logstore - SLS logstore name + aliyun_sls_access_key_id - Alibaba Cloud AccessKey ID + aliyun_sls_access_key_secret - Alibaba Cloud AccessKey Secret + aliyun_sls_endpoint - Custom endpoint (optional), overrides region-derived endpoint +""" + +import asyncio +import time +from typing import Any, Dict, Optional + +from aliyun.log import LogClient, LogItem, PutLogsRequest + +import litellm +from litellm._logging import verbose_logger +from litellm.integrations.custom_logger import CustomLogger +from litellm.types.utils import StandardLoggingPayload + + +class AliyunSLSLogger(CustomLogger): + def __init__(self) -> None: + super().__init__() + params: Dict[str, Any] = {} + if litellm.aliyun_sls_callback_params is not None: + for key, value in litellm.aliyun_sls_callback_params.items(): + if isinstance(value, str) and value.startswith("os.environ/"): + params[key] = litellm.get_secret(value) + else: + params[key] = value + + region = params.get("aliyun_sls_region") or "" + self.project = params.get("aliyun_sls_project") or "" + self.logstore = params.get("aliyun_sls_logstore") or "" + access_key_id = params.get("aliyun_sls_access_key_id") or "" + access_key_secret = params.get("aliyun_sls_access_key_secret") or "" + custom_endpoint = params.get("aliyun_sls_endpoint") or "" + + if not region and not custom_endpoint: + raise ValueError("aliyun_sls_region is required") + if not self.project: + raise ValueError("aliyun_sls_project is required") + if not self.logstore: + raise ValueError("aliyun_sls_logstore is required") + + endpoint = custom_endpoint or f"{region}.log.aliyuncs.com" + self.client = LogClient(endpoint, access_key_id, access_key_secret) + verbose_logger.debug( + "AliyunSLSLogger initialized: endpoint=%s project=%s logstore=%s", + endpoint, + self.project, + self.logstore, + ) + + def _put_logs(self, contents: list) -> None: + log_item = LogItem(timestamp=int(time.time()), contents=contents) + request = PutLogsRequest( + project=self.project, + logstore=self.logstore, + topic="", + source="litellm", + logitems=[log_item], + ) + self.client.put_logs(request) + + def _build_contents( + self, + kwargs: Dict[str, Any], + response_obj: Any, + start_time: Any, + end_time: Any, + status: str, + ) -> list: + payload: Optional[StandardLoggingPayload] = kwargs.get( + "standard_logging_object" + ) + if payload is None: + return [("status", status)] + + contents = [ + ("status", status), + ("model", str(payload.get("model") or "")), + ("call_type", str(payload.get("call_type") or "")), + ("response_id", str(payload.get("id") or "")), + ("api_base", str(payload.get("api_base") or "")), + ("response_time_ms", str(payload.get("response_time") or "")), + ("prompt_tokens", str(payload.get("prompt_tokens") or 0)), + ("completion_tokens", str(payload.get("completion_tokens") or 0)), + ("total_tokens", str(payload.get("total_tokens") or 0)), + ("total_cost", str(payload.get("response_cost") or 0)), + ( + "user", + str(payload.get("metadata", {}).get("user_api_key_user_id") or ""), + ), + ( + "team_id", + str(payload.get("metadata", {}).get("user_api_key_team_id") or ""), + ), + ( + "key_alias", + str(payload.get("metadata", {}).get("user_api_key_alias") or ""), + ), + ] + + error_str = payload.get("error_str") + if error_str: + contents.append(("error", str(error_str))) + + return contents + + async def async_log_success_event( + self, kwargs: Dict[str, Any], response_obj: Any, start_time: Any, end_time: Any + ) -> None: + try: + contents = self._build_contents( + kwargs, response_obj, start_time, end_time, "success" + ) + await asyncio.get_event_loop().run_in_executor( + None, self._put_logs, contents + ) + except Exception as e: + verbose_logger.exception( + "AliyunSLSLogger: failed to log success event: %s", e + ) + + async def async_log_failure_event( + self, kwargs: Dict[str, Any], response_obj: Any, start_time: Any, end_time: Any + ) -> None: + try: + contents = self._build_contents( + kwargs, response_obj, start_time, end_time, "failure" + ) + await asyncio.get_event_loop().run_in_executor( + None, self._put_logs, contents + ) + except Exception as e: + verbose_logger.exception( + "AliyunSLSLogger: failed to log failure event: %s", e + ) diff --git a/litellm/integrations/callback_configs.json b/litellm/integrations/callback_configs.json index c2b0c4ddce9..aaa6f54a86d 100644 --- a/litellm/integrations/callback_configs.json +++ b/litellm/integrations/callback_configs.json @@ -454,5 +454,50 @@ } }, "description": "SQS Queue (AWS) Logging Integration" + }, + { + "id": "aliyun_sls", + "displayName": "Aliyun SLS", + "logo": "aliyun.svg", + "supports_key_team_logging": false, + "dynamic_params": { + "aliyun_sls_region": { + "type": "text", + "ui_name": "Region", + "description": "Aliyun region ID, e.g. cn-hangzhou", + "required": true + }, + "aliyun_sls_project": { + "type": "text", + "ui_name": "Project", + "description": "SLS project name", + "required": true + }, + "aliyun_sls_logstore": { + "type": "text", + "ui_name": "Logstore", + "description": "SLS logstore name", + "required": true + }, + "aliyun_sls_access_key_id": { + "type": "password", + "ui_name": "Access Key ID", + "description": "Alibaba Cloud AccessKey ID", + "required": true + }, + "aliyun_sls_access_key_secret": { + "type": "password", + "ui_name": "Access Key Secret", + "description": "Alibaba Cloud AccessKey Secret", + "required": true + }, + "aliyun_sls_endpoint": { + "type": "text", + "ui_name": "Endpoint (optional)", + "description": "Custom SLS endpoint, e.g. cn-hangzhou.log.aliyuncs.com. Defaults to {region}.log.aliyuncs.com", + "required": false + } + }, + "description": "Aliyun SLS (Simple Log Service) Logging Integration" } ] diff --git a/litellm/litellm_core_utils/custom_logger_registry.py b/litellm/litellm_core_utils/custom_logger_registry.py index f873bfeece5..b8d3fd78a28 100644 --- a/litellm/litellm_core_utils/custom_logger_registry.py +++ b/litellm/litellm_core_utils/custom_logger_registry.py @@ -41,6 +41,7 @@ from litellm.integrations.mlflow import MlflowLogger from litellm.integrations.openmeter import OpenMeterLogger from litellm.integrations.opentelemetry import OpenTelemetry from litellm.integrations.opik.opik import OpikLogger +from litellm.integrations.aliyun_sls import AliyunSLSLogger from litellm.integrations.posthog import PostHogLogger from litellm.integrations.prometheus import PrometheusLogger from litellm.integrations.s3_v2 import S3Logger @@ -102,6 +103,7 @@ class CustomLoggerRegistry: "focus": FocusLogger, "vantage": VantageLogger, "posthog": PostHogLogger, + "aliyun_sls": AliyunSLSLogger, } try: diff --git a/litellm/litellm_core_utils/litellm_logging.py b/litellm/litellm_core_utils/litellm_logging.py index a9d3679210f..658ac0bc02d 100644 --- a/litellm/litellm_core_utils/litellm_logging.py +++ b/litellm/litellm_core_utils/litellm_logging.py @@ -4275,6 +4275,16 @@ def _init_custom_logger_compatible_class( # noqa: PLR0915 gitlab_logger = GitLabPromptManager(gitlab_config=gitlab_config) _in_memory_loggers.append(gitlab_logger) return gitlab_logger # type: ignore + elif logging_integration == "aliyun_sls": + from litellm.integrations.aliyun_sls import AliyunSLSLogger + + for callback in _in_memory_loggers: + if isinstance(callback, AliyunSLSLogger): + return callback + + aliyun_sls_logger = AliyunSLSLogger() + _in_memory_loggers.append(aliyun_sls_logger) + return aliyun_sls_logger # type: ignore return None except Exception as e: verbose_logger.exception( diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000000..65b3d93882c --- /dev/null +++ b/requirements.txt @@ -0,0 +1,89 @@ +# LITELLM PROXY DEPENDENCIES # +# Security: explicit pins for transitive deps (CVE fixes) +urllib3==2.6.3 # CVE-2025-66471, CVE-2025-66418, CVE-2026-21441 +tornado==6.5.5 # CVE-2025-67725, CVE-2025-67726, CVE-2025-67724, CVE-2026-31958, GHSA-78cv-mqj4-43f7 +filelock==3.25.2 # CVE-2025-68146 +h11==0.16.0 # CVE-2025-43859, GHSA-vqfr-h8mv-ghfj — HTTP request smuggling +wheel==0.46.3 # CVE-2026-24049 — path traversal +Pillow==12.1.1 #GHSA-cfh3-3jmp-rvhc +cryptography==46.0.5 #GHSA-r6ph-v2qm-q3c2 + +anyio==4.8.0 # openai + http req. +httpx==0.28.1 +openai==2.30.0 # openai req. +fastapi==0.124.4 # server dep +starlette==0.49.1 # starlette fastapi dep +backoff==2.2.1 # server dep +pyyaml==6.0.3 # server dep +uvicorn==0.33.0 # server dep +gunicorn==23.0.0 # server dep +fastuuid==0.14.0 # for uuid4 +uvloop==0.21.0 # uvicorn dep, gives us much better performance under load +boto3==1.42.80 # aws bedrock/sagemaker calls +redis==5.2.1 # redis caching +redisvl==0.4.1 ## redis semantic caching +prisma==0.11.0 # for db +nodejs-wheel-binaries==24.13.1 ## required by prisma for migrations, prevents runtime download (updated from nodejs-bin for security fixes) +mangum==0.17.0 # for aws lambda functions +pynacl==1.6.2 # for encrypting keys +google-cloud-aiplatform==1.133.0 # for vertex ai calls +google-cloud-iam==2.19.1 # for GCP IAM Redis authentication +google-genai==1.37.0 +anthropic[vertex]==0.54.0 +mcp==1.26.0 ; python_version >= "3.10" # for MCP server +# google-generativeai removed - deprecated, replaced by google-genai (line 21) +async_generator==1.10.0 # for async ollama calls +langfuse==2.59.7 # for langfuse self-hosted logging +prometheus_client==0.20.0 # for /metrics endpoint on proxy +aliyun-log-python-sdk==0.9.44 # for Aliyun SLS logging integration +ddtrace==2.19.0 # for advanced DD tracing / profiling +orjson==3.10.15 # fast /embedding responses +polars==1.39.3 # for data processing +apscheduler==3.11.2 # for resetting budget in background +fastapi-sso==0.16.0 # admin UI, SSO +pyjwt[crypto]==2.12.1 ; python_version >= "3.9" +python-multipart==0.0.20 # admin UI +jaraco.context==6.1.2 +azure-ai-contentsafety==1.0.0 # for azure content safety +azure-identity==1.25.3 ; python_version >= "3.9" # for azure content safety +azure-keyvault==4.2.0 # for azure KMS integration +azure-storage-file-datalake==12.20.0 # for azure buck storage logging +opentelemetry-api==1.28.0 +opentelemetry-sdk==1.28.0 +opentelemetry-exporter-otlp==1.28.0 +a2a-sdk==0.3.25 ; python_version >= "3.10" +# grpcio: pinned to 1.80.0 (past reconnect bug #38290 in 1.68.x, has Python 3.14 wheels) +grpcio==1.80.0 +sentry_sdk==2.21.0 # for sentry error handling +detect-secrets==1.5.0 # Enterprise - secret detection / masking in LLM requests +tzdata==2025.1 # IANA time zone database +litellm-proxy-extras==0.4.65 # for proxy extras - e.g. prisma migrations +llm-sandbox==0.3.31 # for skill execution in sandbox +### LITELLM PACKAGE DEPENDENCIES +python-dotenv==1.0.1 # for env +tiktoken==0.12.0 # for calculating usage +importlib-metadata==8.5.0 # for random utils +tokenizers==0.22.2 # for calculating usage +click==8.1.8 # for proxy cli +rich==13.9.4 # for litellm proxy cli +jinja2==3.1.6 # for prompt templates +aiohttp==3.13.5 # for network calls +tenacity==8.5.0 # for retrying requests, when litellm.num_retries set +pydantic==2.12.5 # proxy + openai req. + mcp +jsonschema==4.23.0 # validating json schema - aligned with openapi-core + mcp +websockets==15.0.1 # for realtime API +soundfile==0.12.1 # for audio file processing +openapi-core==0.21.0 # for OpenAPI compliance tests +pypdf==6.9.2 # for PDF text extraction in RAG ingestion (CVE-2026-27888) + +# Transitive deps pinned to prevent floating between builds +aiofiles==24.1.0 # transitive dep (langfuse) +colorlog==6.10.1 # transitive dep (ddtrace) +grpc-google-iam-v1==0.14.3 # transitive dep (google-cloud-iam) +hf-xet==1.4.2 # transitive dep (huggingface_hub) +requests-toolbelt==1.0.0 # transitive dep (langfuse) + +######################## +# LITELLM ENTERPRISE DEPENDENCIES +######################## +litellm-enterprise==0.1.37 diff --git a/ui/litellm-dashboard/src/components/callback_info_helpers.tsx b/ui/litellm-dashboard/src/components/callback_info_helpers.tsx index 187c05a468d..303c6b8ca6a 100644 --- a/ui/litellm-dashboard/src/components/callback_info_helpers.tsx +++ b/ui/litellm-dashboard/src/components/callback_info_helpers.tsx @@ -150,6 +150,21 @@ export const CALLBACK_CONFIGS: CallbackConfig[] = [ }, description: "SQS Queue (AWS) Logging Integration", }, + { + id: "aliyun_sls", + displayName: "Aliyun SLS", + logo: `${asset_logos_folder}aliyun.svg`, + supports_key_team_logging: false, + dynamic_params: { + aliyun_sls_region: "text", + aliyun_sls_project: "text", + aliyun_sls_logstore: "text", + aliyun_sls_access_key_id: "password", + aliyun_sls_access_key_secret: "password", + aliyun_sls_endpoint: "text", + }, + description: "Aliyun SLS (Simple Log Service) Logging Integration", + }, ]; // Create callbackInfo object mapping display names to config objects