diff --git a/Dockerfile b/Dockerfile index 6e9c2e6d1a6..7a549efc5fc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ # syntax=docker/dockerfile:1.7 # Base image for building -ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:1d95114038f76513a9ace6fca107d5582b08c65981f81f61cb56bf7fd2ef216d +ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:81211e15a86ea1d5357f284482af45730c51de45eaf10ad9ce205d6bfc2df323 # Runtime image -ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:1d95114038f76513a9ace6fca107d5582b08c65981f81f61cb56bf7fd2ef216d +ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:81211e15a86ea1d5357f284482af45730c51de45eaf10ad9ce205d6bfc2df323 ARG UV_IMAGE=ghcr.io/astral-sh/uv:0.11.7@sha256:240fb85ab0f263ef12f492d8476aa3a2e4e1e333f7d67fbdd923d00a506a516a # Pinned by digest like the other base images; bump explicitly on Node upgrades. ARG UI_BUILD_IMAGE=node:24.19-alpine3.24@sha256:d32cdf619f63fe0471182d08996dd516c6275bb5fd31ae06e55a570bd9e1ad43 @@ -60,6 +60,7 @@ RUN apk add --no-cache \ python-3.13-dev \ rust \ openssl \ + libssl3 \ openssl-dev \ nodejs \ npm \ @@ -126,7 +127,7 @@ USER root RUN echo "https://packages.wolfi.dev/os" >> /etc/apk/repositories # node (without npm) is required by the prisma CLI at runtime -RUN apk add --no-cache bash openssl tzdata nodejs python-3.13 libsndfile libevent +RUN apk add --no-cache bash openssl libssl3 tzdata nodejs python-3.13 libsndfile libevent COPY --from=pgbouncer-builder /usr/local/bin/pgbouncer /usr/local/bin/pgbouncer WORKDIR /app diff --git a/backend/Dockerfile b/backend/Dockerfile index 59f836b55f8..31b770e792a 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,5 +1,5 @@ -ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:1d95114038f76513a9ace6fca107d5582b08c65981f81f61cb56bf7fd2ef216d -ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:1d95114038f76513a9ace6fca107d5582b08c65981f81f61cb56bf7fd2ef216d +ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:81211e15a86ea1d5357f284482af45730c51de45eaf10ad9ce205d6bfc2df323 +ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:81211e15a86ea1d5357f284482af45730c51de45eaf10ad9ce205d6bfc2df323 ARG UV_IMAGE=ghcr.io/astral-sh/uv:0.11.7@sha256:240fb85ab0f263ef12f492d8476aa3a2e4e1e333f7d67fbdd923d00a506a516a FROM $UV_IMAGE AS uvbin @@ -16,7 +16,7 @@ COPY --from=uvbin /uv /uvx /usr/local/bin/ # instead of nodeenv downloading one whose dynamic deps may not be in Wolfi # (e.g. Node 26.2.0 needs libatomic). Retry for transient apk.cgr.dev flakes. RUN for i in 1 2 3; do \ - apk add --no-cache bash gcc python-3.13 python-3.13-dev openssl openssl-dev libsndfile nodejs npm && break; \ + apk add --no-cache bash gcc python-3.13 python-3.13-dev openssl libssl3 openssl-dev libsndfile nodejs npm && break; \ [ $i = 3 ] && { echo "apk add failed after 3 retries" >&2; exit 1; }; \ sleep 5; \ done @@ -75,7 +75,7 @@ FROM $LITELLM_RUNTIME_IMAGE AS runtime USER root RUN for i in 1 2 3; do \ - apk add --no-cache bash openssl tzdata python-3.13 libsndfile libatomic && break; \ + apk add --no-cache bash openssl libssl3 tzdata python-3.13 libsndfile libatomic && break; \ [ $i = 3 ] && { echo "apk add failed after 3 retries" >&2; exit 1; }; \ sleep 5; \ done diff --git a/cosign.pub b/cosign.pub index 2c2a555ab09..7603d69641f 100644 --- a/cosign.pub +++ b/cosign.pub @@ -1,4 +1,4 @@ -----BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKi4ivqGpE231OGH50PKbqy1Y1Kkb -POJC8+i2Wko82gBOUCe3M0Vw86H/4rhUhfoYEti4gdJ9wZbYmK0I2EE96g== +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG06dpKM+vEDnmp2zcjyXgVCXxzRg +JA5H2LnmwBKQafZGka6OOrWujCEWATQewiAgyD4WQdJ0pvU9RC4mvNAjvQ== -----END PUBLIC KEY----- diff --git a/docker/Dockerfile.database b/docker/Dockerfile.database index b5459eb857a..cc529a5c796 100644 --- a/docker/Dockerfile.database +++ b/docker/Dockerfile.database @@ -1,10 +1,10 @@ # syntax=docker/dockerfile:1.7 # Base image for building -ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:1d95114038f76513a9ace6fca107d5582b08c65981f81f61cb56bf7fd2ef216d +ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:81211e15a86ea1d5357f284482af45730c51de45eaf10ad9ce205d6bfc2df323 # Runtime image -ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:1d95114038f76513a9ace6fca107d5582b08c65981f81f61cb56bf7fd2ef216d +ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:81211e15a86ea1d5357f284482af45730c51de45eaf10ad9ce205d6bfc2df323 ARG UV_IMAGE=ghcr.io/astral-sh/uv:0.11.7@sha256:240fb85ab0f263ef12f492d8476aa3a2e4e1e333f7d67fbdd923d00a506a516a # Pinned by digest like the other base images; bump explicitly on Node upgrades. ARG UI_BUILD_IMAGE=node:24.19-alpine3.24@sha256:d32cdf619f63fe0471182d08996dd516c6275bb5fd31ae06e55a570bd9e1ad43 @@ -58,6 +58,7 @@ RUN apk add --no-cache \ python-3.13 \ python-3.13-dev \ openssl \ + libssl3 \ openssl-dev \ nodejs \ npm \ @@ -117,7 +118,7 @@ FROM $LITELLM_RUNTIME_IMAGE AS runtime USER root # node (without npm) is required by the prisma CLI at runtime -RUN apk add --no-cache bash openssl tzdata nodejs python-3.13 libsndfile libevent +RUN apk add --no-cache bash openssl libssl3 tzdata nodejs python-3.13 libsndfile libevent COPY --from=pgbouncer-builder /usr/local/bin/pgbouncer /usr/local/bin/pgbouncer WORKDIR /app diff --git a/docker/Dockerfile.non_root b/docker/Dockerfile.non_root index cd987cc6e6d..3b59800a492 100644 --- a/docker/Dockerfile.non_root +++ b/docker/Dockerfile.non_root @@ -1,8 +1,8 @@ # syntax=docker/dockerfile:1.7 # Base images -ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:1d95114038f76513a9ace6fca107d5582b08c65981f81f61cb56bf7fd2ef216d -ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:1d95114038f76513a9ace6fca107d5582b08c65981f81f61cb56bf7fd2ef216d +ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:81211e15a86ea1d5357f284482af45730c51de45eaf10ad9ce205d6bfc2df323 +ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:81211e15a86ea1d5357f284482af45730c51de45eaf10ad9ce205d6bfc2df323 ARG UV_IMAGE=ghcr.io/astral-sh/uv:0.11.7@sha256:240fb85ab0f263ef12f492d8476aa3a2e4e1e333f7d67fbdd923d00a506a516a # Pinned by digest like the other base images; bump explicitly on Node upgrades. ARG UI_BUILD_IMAGE=node:24.19-alpine3.24@sha256:d32cdf619f63fe0471182d08996dd516c6275bb5fd31ae06e55a570bd9e1ad43 @@ -59,6 +59,7 @@ RUN for i in 1 2 3; do \ coreutils \ curl \ openssl \ + libssl3 \ libsndfile \ nodejs \ npm && break || sleep 5; \ @@ -129,7 +130,7 @@ RUN for i in 1 2 3; do \ apk upgrade --no-cache && break || sleep 5; \ done && \ for i in 1 2 3; do \ - apk add --no-cache python-3.13 bash openssl tzdata libsndfile nodejs libevent && break || sleep 5; \ + apk add --no-cache python-3.13 bash openssl libssl3 tzdata libsndfile nodejs libevent && break || sleep 5; \ done COPY --from=pgbouncer-builder /usr/local/bin/pgbouncer /usr/local/bin/pgbouncer diff --git a/docker/build_from_pip/Dockerfile.build_from_pip b/docker/build_from_pip/Dockerfile.build_from_pip index a5733f0e1a0..25a7ed2fa97 100644 --- a/docker/build_from_pip/Dockerfile.build_from_pip +++ b/docker/build_from_pip/Dockerfile.build_from_pip @@ -30,7 +30,7 @@ RUN uv venv --python python && \ "google-cloud-aiplatform==1.133.0" \ "google-genai==1.37.0" \ "anthropic[vertex]==0.84.0" \ - "grpcio==1.78.0" \ + "grpcio==1.84.1" \ "prometheus-client==0.20.0" \ "langfuse==2.59.7" \ "opentelemetry-api==1.28.0" \ diff --git a/gateway/Dockerfile b/gateway/Dockerfile index be6d26963e5..592401f451f 100644 --- a/gateway/Dockerfile +++ b/gateway/Dockerfile @@ -1,5 +1,5 @@ -ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:1d95114038f76513a9ace6fca107d5582b08c65981f81f61cb56bf7fd2ef216d -ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:1d95114038f76513a9ace6fca107d5582b08c65981f81f61cb56bf7fd2ef216d +ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:81211e15a86ea1d5357f284482af45730c51de45eaf10ad9ce205d6bfc2df323 +ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:81211e15a86ea1d5357f284482af45730c51de45eaf10ad9ce205d6bfc2df323 ARG UV_IMAGE=ghcr.io/astral-sh/uv:0.11.7@sha256:240fb85ab0f263ef12f492d8476aa3a2e4e1e333f7d67fbdd923d00a506a516a # Checksum from https://www.pgbouncer.org/downloads/ (the Wolfi repo only carries 1.24.x) ARG PGBOUNCER_VERSION=1.26.0 @@ -32,7 +32,7 @@ COPY --from=uvbin /uv /uvx /usr/local/bin/ # instead of nodeenv downloading one whose dynamic deps may not be in Wolfi # (e.g. Node 26.2.0 needs libatomic). Retry for transient apk.cgr.dev flakes. RUN for i in 1 2 3; do \ - apk add --no-cache bash gcc python-3.13 python-3.13-dev openssl openssl-dev libsndfile nodejs npm && break; \ + apk add --no-cache bash gcc python-3.13 python-3.13-dev openssl libssl3 openssl-dev libsndfile nodejs npm && break; \ [ $i = 3 ] && { echo "apk add failed after 3 retries" >&2; exit 1; }; \ sleep 5; \ done @@ -93,7 +93,7 @@ FROM $LITELLM_RUNTIME_IMAGE AS runtime USER root RUN for i in 1 2 3; do \ - apk add --no-cache bash openssl tzdata python-3.13 libsndfile libatomic libevent && break; \ + apk add --no-cache bash openssl libssl3 tzdata python-3.13 libsndfile libatomic libevent && break; \ [ $i = 3 ] && { echo "apk add failed after 3 retries" >&2; exit 1; }; \ sleep 5; \ done diff --git a/litellm-rust/Cargo.lock b/litellm-rust/Cargo.lock index 40552b19e43..5c9a68bd1bc 100644 --- a/litellm-rust/Cargo.lock +++ b/litellm-rust/Cargo.lock @@ -8167,18 +8167,18 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" +checksum = "58ec80e73fd8baf57bf0d9615554c75348bda990d6d5bbeab964dd068319fecb" dependencies = [ "rustls-pki-types", ] [[package]] name = "webpki-roots" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" +checksum = "1c1c8e20c8a38fc7d65abfe74eb7280e4aa667e8eec8bc84996d2874810748d9" dependencies = [ "rustls-pki-types", ] diff --git a/litellm-rust/Cargo.toml b/litellm-rust/Cargo.toml index f4cb2ecbe59..286593fe15b 100644 --- a/litellm-rust/Cargo.toml +++ b/litellm-rust/Cargo.toml @@ -118,7 +118,7 @@ moka = { version = "0.12.16", features = ["future"] } strum = { version = "0.28.0", features = ["derive"] } url = "2.5.8" percent-encoding = "2.3" -webpki-roots = "1" +webpki-roots = "1.0.10" time = { version = "0.3.53", features = ["parsing"] } criterion = "0.8.2" fancy-regex = "0.19.2" diff --git a/litellm/integrations/otel/mount.py b/litellm/integrations/otel/mount.py index 9340f6e9e15..3c770b219b5 100644 --- a/litellm/integrations/otel/mount.py +++ b/litellm/integrations/otel/mount.py @@ -104,8 +104,8 @@ def instrument_fastapi_app(app: "FastAPI") -> None: Safe no-op when the V2 gate is off or ``opentelemetry-instrumentation-fastapi`` is unavailable. This MUST be called at app-creation time — once the lifespan - runs, the middleware stack is frozen and ``instrument_app`` raises "Cannot add - middleware after an application has started". + runs, the middleware stack is frozen and middleware added later never runs, so + a late call is skipped without registering anything. No ``TracerProvider`` is passed, so the instrumentation binds to the OTel global ``ProxyTracerProvider``; the proxy publishes the real provider as the global @@ -115,6 +115,9 @@ def instrument_fastapi_app(app: "FastAPI") -> None: try: if not is_otel_v2_enabled(): return + if app.middleware_stack is not None: + verbose_logger.debug("Skipping OTel V2 FastAPI instrumentation: the app has already started") + return # Lazy: only the V2-enabled path needs the optional # ``opentelemetry-instrumentation-fastapi`` package, which is not part of the diff --git a/litellm/integrations/otel/plumbing/otlp_json.py b/litellm/integrations/otel/plumbing/otlp_json.py index bc6d7d435b0..fc0351d5049 100644 --- a/litellm/integrations/otel/plumbing/otlp_json.py +++ b/litellm/integrations/otel/plumbing/otlp_json.py @@ -6,6 +6,7 @@ retry loop and swaps the payload for OTLP/JSON (enums as integers, ids as hex). import base64 import json +import logging from collections.abc import Mapping, Sequence from types import MappingProxyType from typing import Final, TypeAlias @@ -13,9 +14,13 @@ from typing import Final, TypeAlias import requests from google.protobuf.json_format import MessageToDict from opentelemetry.exporter.otlp.proto.common.trace_encoder import encode_spans +from opentelemetry.exporter.otlp.proto.http._common import RequestPayloadTooLargeError from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter from opentelemetry.sdk.trace import ReadableSpan +from opentelemetry.sdk.trace.export import SpanExportResult +from opentelemetry.semconv.attributes.http_attributes import HTTP_RESPONSE_STATUS_CODE +_logger: Final = logging.getLogger(__name__) JSON_CONTENT_TYPE: Final = "application/json" _HEX_ID_KEYS: Final = frozenset({"traceId", "spanId", "parentSpanId"}) @@ -66,12 +71,49 @@ class OTLPJsonSpanExporter(OTLPSpanExporter): def __init__( self, endpoint: str | None, - headers: dict[str, str], # mutable-ok: SDK __init__ takes Dict + headers: Mapping[str, str], certificate_file: str | None = None, session: "requests.Session | None" = None, + *, + max_request_size: int | None = None, ) -> None: - super().__init__(endpoint=endpoint, headers=headers, certificate_file=certificate_file, session=session) - self._session.headers["Content-Type"] = JSON_CONTENT_TYPE + super().__init__( + endpoint=endpoint, + headers={**{key.lower(): value for key, value in headers.items()}, "content-type": JSON_CONTENT_TYPE}, + certificate_file=certificate_file, + session=session, + max_request_size=max_request_size, + ) - def _serialize_spans(self, spans: Sequence[ReadableSpan]) -> bytes: - return encode_spans_json(spans) + def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult: + if self._shutdown: + _logger.warning("Exporter already shutdown, ignoring batch") + return SpanExportResult.FAILURE + + with self._metrics.export_operation(len(spans)) as result: + try: + serialized_data: Final = encode_spans_json(spans) + except Exception as error: # noqa: BLE001 # SDK export contract reports encoding failures as results + _logger.error("Failed to encode span batch: %s", error) + result.error = error + return SpanExportResult.FAILURE + + if 0 < self._max_request_size < len(serialized_data): + result.error = RequestPayloadTooLargeError( + f"Serialized span request size {len(serialized_data)} bytes " + f"exceeds max_request_size {self._max_request_size} bytes." + ) + _logger.warning("Dropping span batch: %s", result.error) + return SpanExportResult.FAILURE + + export_result: Final = self._client.export(serialized_data) + if not export_result.success: + result.error = export_result.error + result.error_attrs = ( + {HTTP_RESPONSE_STATUS_CODE: export_result.status_code} + if export_result.status_code is not None + else None + ) + return SpanExportResult.FAILURE + + return SpanExportResult.SUCCESS diff --git a/litellm/integrations/otel/presets/agentops.py b/litellm/integrations/otel/presets/agentops.py index 58123656caa..de8e1405339 100644 --- a/litellm/integrations/otel/presets/agentops.py +++ b/litellm/integrations/otel/presets/agentops.py @@ -76,6 +76,7 @@ def agentops_preset( def _build_agentops_exporter(spec: ExporterSpec) -> SpanExporter: """Factory for the ``agentops`` exporter kind: a lazy-auth OTLP/HTTP exporter.""" + import requests from opentelemetry.exporter.otlp.proto.http.trace_exporter import ( OTLPSpanExporter, ) @@ -89,7 +90,8 @@ def _build_agentops_exporter(spec: ExporterSpec) -> SpanExporter: """ def __init__(self, *, endpoint: str | None, api_key: str | None) -> None: - super().__init__(endpoint=endpoint) + self._agentops_session = requests.Session() + super().__init__(endpoint=endpoint, session=self._agentops_session) self._agentops_api_key = api_key self._auth_resolved = False @@ -102,10 +104,7 @@ def _build_agentops_exporter(spec: ExporterSpec) -> SpanExporter: try: token: Final = _fetch_agentops_jwt(self._agentops_api_key).get("token") if token: - # ``_session`` is the requests.Session the base exporter - # POSTs through; updating its Authorization header is how the - # minted JWT reaches every subsequent export. - self._session.headers["Authorization"] = f"Bearer {token}" + self._agentops_session.headers["Authorization"] = f"Bearer {token}" except Exception as e: verbose_logger.debug("AgentOps JWT fetch failed: %s", e) diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html index 9366c0b55f3..f66f3b7706e 100644 --- a/litellm/proxy/_experimental/out/404.html +++ b/litellm/proxy/_experimental/out/404.html @@ -1 +1 @@ -
e&&T());){var o=m.callback;if("function"==typeof o){m.callback=null,h=m.priorityLevel;var u=o(m.expirationTime<=e);if(e=n.unstable_now(),"function"==typeof u){m.callback=u,E(e),t=!0;break t}m===l(f)&&a(f),E(e)}else a(f);m=l(f)}if(null!==m)t=!0;else{var s=l(d);null!==s&&M(x,s.startTime-e),t=!1}}break e}finally{m=null,h=r,g=!1}}}finally{t?i():_=!1}}}if("function"==typeof k)i=function(){k(z)};else if("u">typeof MessageChannel){var O=new MessageChannel,L=O.port2;O.port1.onmessage=z,i=function(){L.postMessage(null)}}else i=function(){w(z,0)};function M(e,t){N=w(function(){e(n.unstable_now())},t)}n.unstable_IdlePriority=5,n.unstable_ImmediatePriority=1,n.unstable_LowPriority=4,n.unstable_NormalPriority=3,n.unstable_Profiling=null,n.unstable_UserBlockingPriority=2,n.unstable_cancelCallback=function(e){e.callback=null},n.unstable_forceFrameRate=function(e){0>e||125 e.project_id||String(t),sortingMode:"client",sorting:n,onSortingChange:o,paginationMode:"client",pagination:{pageIndex:j,pageSize:u},pageSizeOptions:eW,paginationSlot:()=>(0,t.jsx)(eH.f,{page:j,pageSize:u,rowCount:e.length,onPageChange:e=>m({pageIndex:e,pageSize:u}),onPageSizeChange:e=>m({pageIndex:0,pageSize:e}),pageSizeOptions:eW,isLoading:a}),isLoading:a,loadingMessage:"Loading projects…",noDataMessage:(0,t.jsx)(e0,{isFiltered:s}),size:"compact"})}function e2(){let{data:e,isLoading:x}=(0,a.O)(),{data:p,isLoading:j}=(0,s.n)(),[g,h]=(0,o.o)("project",o.d.withOptions({history:"push"})),f=function(){let{setSearch:e,onSortingChange:t,onColumnFiltersChange:a,onPaginationChange:s}=eD();return(0,d.useCallback)(()=>{e(""),t([]),a([]),s({pageIndex:0,pageSize:5})},[e,t,a,s])}(),{search:v,setSearch:b}=e$(),[y,N]=(0,d.useState)(!1),_=(0,d.useMemo)(()=>{let e=new Map;for(let t of p??[])e.set(t.team_id,t.team_alias??t.team_id);return e},[p]),k=(0,d.useMemo)(()=>{let t=e??[];if(!v)return t;let a=v.toLowerCase();return t.filter(e=>{let t=_.get(e.team_id??"")??"";return(e.project_alias??"").toLowerCase().includes(a)||e.project_id.toLowerCase().includes(a)||(e.description??"").toLowerCase().includes(a)||t.toLowerCase().includes(a)})},[e,v,_]);return g?(0,t.jsx)(eU,{projectId:g,onBack:()=>{h(null,{history:"replace"}),f()}}):(0,t.jsxs)("div",{className:"p-8",children:[(0,t.jsx)(c.f,{icon:(0,t.jsx)(i.f,{}),title:"Projects",subtitle:"Manage projects within your teams",primaryAction:(0,t.jsxs)(m.K,{onClick:()=>N(!0),children:[(0,t.jsx)(l.f,{className:"size-4"}),"Create Project"]})}),(0,t.jsx)("div",{className:"mt-6 mb-3 flex items-center",children:(0,t.jsxs)(u.H,{className:"max-w-[400px]",children:[(0,t.jsx)(u.B,{children:(0,t.jsx)(r.f,{className:"size-4 text-muted-foreground"})}),(0,t.jsx)(u.M,{placeholder:"Search projects by name, ID, description, or team...",value:v,onChange:e=>b(e.target.value)}),v&&(0,t.jsx)(u.B,{align:"inline-end",children:(0,t.jsx)(u.w,{size:"icon-xs","aria-label":"Clear search",onClick:()=>b(""),children:(0,t.jsx)(n.X,{})})})]})}),(0,t.jsx)(e1,{projects:k,isLoading:x,isFiltered:v.trim().length>0,onProjectClick:e=>void h(e),teamAliasMap:_,isTeamsLoading:j}),(0,t.jsx)(ei,{isOpen:y,onClose:()=>N(!1)})]})}e.s(["default",0,function(){return(0,N.f)(),(0,t.jsx)(e2,{})}],454587)}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0d_vbz467grpc.js b/litellm/proxy/_experimental/out/_next/static/chunks/0d_vbz467grpc.js
deleted file mode 100644
index df1088d9e95..00000000000
--- a/litellm/proxy/_experimental/out/_next/static/chunks/0d_vbz467grpc.js
+++ /dev/null
@@ -1 +0,0 @@
-(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,118366,e=>{"use strict";var t=e.i(991124);e.s(["CopyIcon",()=>t.default])},440160,e=>{"use strict";let t=(0,e.i(475254).default)("download",[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]]);e.s(["Download",0,t],440160)},541071,373488,e=>{"use strict";let t=(0,e.i(475254).default)("ellipsis",[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"19",cy:"12",r:"1",key:"1wjl8i"}],["circle",{cx:"5",cy:"12",r:"1",key:"1pcz8c"}]]);e.s(["default",0,t],373488),e.s(["MoreHorizontal",0,t],541071)},332102,e=>{"use strict";let t=(0,e.i(475254).default)("inbox",[["polyline",{points:"22 12 16 12 14 15 10 15 8 12 2 12",key:"o97t9d"}],["path",{d:"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z",key:"oot6mr"}]]);e.s(["Inbox",0,t],332102)},569074,e=>{"use strict";let t=(0,e.i(475254).default)("upload",[["path",{d:"M12 3v12",key:"1x0j5s"}],["path",{d:"m17 8-5-5-5 5",key:"7q97r8"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}]]);e.s(["Upload",0,t],569074)},59935,(e,t,i)=>{var r;let n;e.e,r=function e(){var t,i="u">typeof self?self:"u">typeof window?window:void 0!==i?i:{},r=!i.document&&!!i.postMessage,n=i.IS_PAPA_WORKER||!1,s={},a=0,o={};function l(e){this._handle=null,this._finished=!1,this._completed=!1,this._halted=!1,this._input=null,this._baseIndex=0,this._partialLine="",this._rowCount=0,this._start=0,this._nextChunk=null,this.isFirstChunk=!0,this._completeResults={data:[],errors:[],meta:{}},(function(e){var t=b(e);t.chunkSize=parseInt(t.chunkSize),e.step||e.chunk||(t.chunkSize=null),this._handle=new f(t),(this._handle.streamer=this)._config=t}).call(this,e),this.parseChunk=function(e,t){var r=parseInt(this._config.skipFirstNLines)||0;if(this.isFirstChunk&&00)for(n=0;n=0&&C.test(e);)e=e.replace(C,s),C.lastIndex=0,n-=1;return e}var G,E,A,j=/\d/,I=/\d\d/,z=/\d{3}/,Z=/\d{4}/,$=/[+-]?\d{6}/,q=/\d\d?/,B=/\d\d\d\d?/,J=/\d\d\d\d\d\d?/,Q=/\d{1,3}/,X=/\d{1,4}/,K=/[+-]?\d{1,6}/,ee=/\d+/,et=/[+-]?\d+/,en=/Z|[+-]\d\d:?\d\d/gi,es=/Z|[+-]\d\d(?::?\d\d)?/gi,ei=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,er=/^[1-9]\d?/,ea=/^([1-9]\d|\d)/;function eo(e,t,n){A[e]=b(t)?t:function(e,s){return e&&n?n:t}}function eu(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function el(e){return e<0?Math.ceil(e)||0:Math.floor(e)}function eh(e){var t=+e,n=0;return 0!==t&&isFinite(t)&&(n=el(t)),n}A={};var ed={};function ec(e,t){var n,s,i=t;for("string"==typeof e&&(e=[e]),u(t)&&(i=function(e,n){n[t]=eh(e)}),s=e.length,n=0;n68?1900:2e3)};var ey=eg("FullYear",!0);function eg(e,t){return function(s){return null!=s?(ep(this,e,s),n.updateOffset(this,t),this):ew(this,e)}}function ew(e,t){if(!e.isValid())return 0/0;var n=e._d,s=e._isUTC;switch(t){case"Milliseconds":return s?n.getUTCMilliseconds():n.getMilliseconds();case"Seconds":return s?n.getUTCSeconds():n.getSeconds();case"Minutes":return s?n.getUTCMinutes():n.getMinutes();case"Hours":return s?n.getUTCHours():n.getHours();case"Date":return s?n.getUTCDate():n.getDate();case"Day":return s?n.getUTCDay():n.getDay();case"Month":return s?n.getUTCMonth():n.getMonth();case"FullYear":return s?n.getUTCFullYear():n.getFullYear();default:return 0/0}}function ep(e,t,n){var s,i,r,a;if(!(!e.isValid()||isNaN(n))){switch(s=e._d,i=e._isUTC,t){case"Milliseconds":return void(i?s.setUTCMilliseconds(n):s.setMilliseconds(n));case"Seconds":return void(i?s.setUTCSeconds(n):s.setSeconds(n));case"Minutes":return void(i?s.setUTCMinutes(n):s.setMinutes(n));case"Hours":return void(i?s.setUTCHours(n):s.setHours(n));case"Date":return void(i?s.setUTCDate(n):s.setDate(n));case"FullYear":break;default:return}r=e.month(),a=29!==(a=e.date())||1!==r||em(n)?a:28,i?s.setUTCFullYear(n,r,a):s.setFullYear(n,r,a)}}function ek(e,t){if(isNaN(e)||isNaN(t))return 0/0;var n=(t%12+12)%12;return e+=(t-n)/12,1===n?em(e)?29:28:31-n%7%2}eq=Array.prototype.indexOf?Array.prototype.indexOf:function(e){var t;for(t=0;t=t-1)break;t--}r++}return eJ}(e)}function e5(e){var t,n=e._a;return n&&-2===f(e).overflow&&(t=n[1]<0||n[1]>11?1:n[2]<1||n[2]>ek(n[0],n[1])?2:n[3]<0||n[3]>24||24===n[3]&&(0!==n[4]||0!==n[5]||0!==n[6])?3:n[4]<0||n[4]>59?4:n[5]<0||n[5]>59?5:n[6]<0||n[6]>999?6:-1,f(e)._overflowDayOfYear&&(t<0||t>2)&&(t=2),f(e)._overflowWeeks&&-1===t&&(t=7),f(e)._overflowWeekday&&-1===t&&(t=8),f(e).overflow=t),e}var e9=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,e7=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,e8=/Z|[+-]\d\d(?::?\d\d)?/,te=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/],["YYYYMM",/\d{6}/,!1],["YYYY",/\d{4}/,!1]],tt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],tn=/^\/?Date\((-?\d+)/i,ts=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/,ti={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function tr(e){var t,n,s,i,r,a,o=e._i,u=e9.exec(o)||e7.exec(o),l=te.length,h=tt.length;if(u){for(f(e).iso=!0,t=0,n=l;t0):this._isDSTShifted=!1,this._isDSTShifted});var t0=eC.prototype;function t1(e,t,n,s){var i=e3(),r=c().set(s,t);return i[n](r,e)}function t2(e,t,n){if(u(e)&&(t=e,e=void 0),e=e||"",null!=t)return t1(e,t,n,"month");var s,i=[];for(s=0;s<12;s++)i[s]=t1(e,s,n,"month");return i}function t4(e,t,n,s){"boolean"==typeof e||(n=t=e,e=!1),u(t)&&(n=t,t=void 0),t=t||"";var i,r=e3(),a=e?r._week.dow:0,o=[];if(null!=n)return t1(t,(n+a)%7,s,"day");for(i=0;i<7;i++)o[i]=t1(t,(i+a)%7,s,"day");return o}t0.calendar=function(e,t,n){var s=this._calendar[e]||this._calendar.sameElse;return b(s)?s.call(t,n):s},t0.longDateFormat=function(e){var t=this._longDateFormat[e],n=this._longDateFormat[e.toUpperCase()],s=this._longDateFormatCache;return t||!n?t:s&&s[e]&&s[e].formatUpper===n?s[e].format:(t=n.match(N).map(function(e){return"MMMM"===e||"MM"===e||"DD"===e||"dddd"===e?e.slice(1):e}).join(""),s||(s=this._longDateFormatCache={}),s[e]={formatUpper:n,format:t},t)},t0.invalidDate=function(){return this._invalidDate},t0.ordinal=function(e){return this._ordinal.replace("%d",e)},t0.preparse=tK,t0.postformat=tK,t0.relativeTime=function(e,t,n,s){return this.postformat(eH.call(this,e,t,n,s))},t0.pastFuture=function(e,t){return this.postformat(eU.call(this,e,t))},t0.set=function(e){var t,n,s,i,a,o;for(s=0;s{this.options={...this.options,...e},this.#m()||this.cancel()},this.#b=e=>{this.store.setState(t=>{let i={...t,...e},{isPending:n}=i;return{...i,status:this.#m()?n?"pending":"idle":"disabled"}}),((e,t)=>{let i=t.key;if(i){var n,s;d.set(i,t),f.emit(e,{key:(n={...t,key:i}).key,store:{state:c("function"==typeof(s=n.store).get?s.get():s.state)},options:c(n.options)})}})("Debouncer",this)},this.#m=()=>!!l(this.options.enabled,this),this.#_=()=>l(this.options.wait,this),this.maybeExecute=(...e)=>{if(!this.#m())return;this.#b({maybeExecuteCount:this.store.state.maybeExecuteCount+1});let t=!1;this.options.leading&&this.store.state.canLeadingExecute&&(this.#b({canLeadingExecute:!1}),t=!0,this.#y(...e)),this.options.trailing&&this.#b({isPending:!0,lastArgs:e}),this.#v&&clearTimeout(this.#v),this.#v=setTimeout(()=>{this.#b({canLeadingExecute:!0}),this.options.trailing&&!t&&this.#y(...e)},this.#_())},this.#y=(...e)=>{this.#m()&&(this.fn(...e),this.#b({executionCount:this.store.state.executionCount+1,isPending:!1,lastArgs:void 0}),this.options.onExecute?.(e,this))},this.flush=()=>{this.store.state.isPending&&this.store.state.lastArgs&&(this.#E(),this.#y(...this.store.state.lastArgs))},this.#E=()=>{this.#v&&(clearTimeout(this.#v),this.#v=void 0)},this.cancel=()=>{this.#E(),this.#b({canLeadingExecute:!0,isPending:!1})},this.reset=()=>{this.#b(C())},this.key=t.key,this.options={...w,...t},this.#b(this.options.initialState??{}),this.key&&f.on("d-Debouncer",e=>{e.payload.key===this.key&&(this.#b(e.payload.store.state),this.setOptions(e.payload.options))})}#b;#m;#_;#y;#E};e.s(["f",0,function(e,t,r=()=>({})){let o={...((0,i.useContext)(n)?.defaultOptions??{}).debouncer,...t},[a]=(0,i.useState)(()=>{let t=new L(e,o);return t.Subscribe=function(e){let i=u(t.store,e.selector,{compare:s});return"function"==typeof e.children?e.children(i):e.children},t});a.fn=e,a.setOptions(o),(0,i.useEffect)(()=>()=>{o.onUnmount?o.onUnmount(a):a.cancel()},[]);let l=u(a.store,r,{compare:s});return(0,i.useMemo)(()=>({...a,state:l}),[a,l])}],540626)},180127,e=>{let t=(0,e.i(475254).f)("arrow-left",[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]]);e.s(["f",0,t])},871689,e=>{var t=e.i(180127);e.s(["f",()=>t.f])},440160,e=>{let t=(0,e.i(475254).f)("download",[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]]);e.s(["f",0,t],440160)},864261,e=>{var t=e.i(751247),i=e.i(135214),n=e.i(441228);e.s(["f",0,e=>{let{userRole:s}=(0,i.f)(),r=(0,n.f)();return(0,t.q)(s,e,r)}])},891547,e=>{var t=e.i(843476),i=e.i(271645),n=e.i(602869),s=e.i(845150);e.s(["f",0,({onChange:e,value:r,className:o,accessToken:a,disabled:u})=>{let[l,h]=(0,i.useState)([]),[d,c]=(0,i.useState)(!1);return(0,i.useEffect)(()=>{(async()=>{if(a){c(!0);try{let e=await (0,n.gx)(a);e.guardrails&&h(e.guardrails)}catch(e){console.error("Error fetching guardrails:",e)}finally{c(!1)}}})()},[a]),(0,t.jsx)("div",{className:"min-w-0",children:(0,t.jsx)(s.f,{disabled:u,placeholder:u?"Setting guardrails is a premium feature.":"Select guardrails",onValueChange:t=>{e(t)},value:r,loading:d,className:o,options:l.flatMap(e=>{let t=e.guardrail_name;return null==t||""===t?[]:[{label:t,value:t}]})})})}])},921511,e=>{var t=e.i(843476),i=e.i(271645),n=e.i(864261),s=e.i(602869),r=e.i(845150);function o(e){return e.filter(e=>(e.version_status??"draft")!=="draft").map(e=>{var t;let i=e.version_number??1,n=e.version_status??"draft";return{label:`${e.policy_name} — v${i} (${n})${e.description?` — ${e.description}`:""}`,value:"production"===n?e.policy_name:e.policy_id?(t=e.policy_id,`policy_${t}`):e.policy_name}})}e.s(["U",0,({onChange:e,value:a,className:u,accessToken:l,disabled:h,onPoliciesLoaded:d})=>{let c=(0,n.f)("viewPolicies"),[f,p]=(0,i.useState)([]),[g,v]=(0,i.useState)(!1);return((0,i.useEffect)(()=>{(async()=>{if(l&&c){v(!0);try{let e=await (0,s.$)(l);e.policies&&(p(e.policies),d?.(e.policies))}catch(e){console.error("Error fetching policies:",e)}finally{v(!1)}}})()},[l,c,d]),c)?(0,t.jsx)("div",{className:"min-w-0",children:(0,t.jsx)(r.f,{disabled:h,placeholder:h?"Setting policies is a premium feature.":"Select policies (production or published versions)",onValueChange:t=>{e(t)},value:a,loading:g,className:u,options:o(f)})}):null},"A",0,o])},916940,e=>{var t=e.i(843476),i=e.i(271645),n=e.i(602869),s=e.i(845150);e.s(["f",0,({onChange:e,value:r,className:o,accessToken:a,placeholder:u="Select vector stores",disabled:l=!1})=>{let[h,d]=(0,i.useState)([]),[c,f]=(0,i.useState)(!1);return(0,i.useEffect)(()=>{(async()=>{if(a){f(!0);try{let e=await (0,n.jn)(a);e.data&&d(e.data)}catch(e){console.error("Error fetching vector stores:",e)}finally{f(!1)}}})()},[a]),(0,t.jsx)("div",{className:"min-w-0",children:(0,t.jsx)(s.f,{placeholder:u,onValueChange:e,value:r,loading:c,className:o,disabled:l,options:h.map(e=>({label:`${e.vector_store_name||e.vector_store_id} (${e.vector_store_id})`,value:e.vector_store_id,description:e.vector_store_description||void 0}))})})}])},741466,e=>{e.s(["f",0,300])}],59935,(e,t,i)=>{var n;let s;e.e,n=function e(){var t,i="u">typeof self?self:"u">typeof window?window:void 0!==i?i:{},n=!i.document&&!!i.postMessage,s=i.IS_PAPA_WORKER||!1,r={},o=0,a={};function u(e){this._handle=null,this._finished=!1,this._completed=!1,this._halted=!1,this._input=null,this._baseIndex=0,this._partialLine="",this._rowCount=0,this._start=0,this._nextChunk=null,this.isFirstChunk=!0,this._completeResults={data:[],errors:[],meta:{}},(function(e){var t=_(e);t.chunkSize=parseInt(t.chunkSize),e.step||e.chunk||(t.chunkSize=null),this._handle=new f(t),(this._handle.streamer=this)._config=t}).call(this,e),this.parseChunk=function(e,t){var n=parseInt(this._config.skipFirstNLines)||0;if(this.isFirstChunk&&0u[h]&&(u[h]=r),g[h]=r),p[h]=o}o.splice(1,0,p),a.splice(1,0,g),c=-1;let d=[];for(;++c