diff --git a/.circleci/config.yml b/.circleci/config.yml index f13e9bf66f1..b0a705966a2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,6 +5,16 @@ orbs: win: circleci/windows@5.0 # Add Windows orb commands: + skip_if_unrelated_changes: + parameters: + category: + type: enum + enum: ["backend", "client"] + default: "backend" + steps: + - run: + name: "Skip job when no << parameters.category >>-relevant files changed" + command: bash .circleci/scripts/path_filter.sh << parameters.category >> setup_google_dns: steps: - run: @@ -282,6 +292,7 @@ jobs: parallelism: 4 steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - restore_cache: keys: @@ -354,6 +365,7 @@ jobs: parallelism: 4 steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - restore_cache: keys: @@ -427,6 +439,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - restore_cache: keys: @@ -480,6 +493,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -545,6 +559,7 @@ jobs: DATABASE_URL: "postgresql://postgres:postgres@localhost:5432/litellm_test" steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -584,6 +599,7 @@ jobs: DATABASE_URL: "postgresql://postgres:postgres@localhost:5432/litellm_test" steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -624,6 +640,7 @@ jobs: DATABASE_URL: "postgresql://postgres:postgres@localhost:5432/litellm_test" steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -656,6 +673,7 @@ jobs: FAKE_OPENAI_API_BASE: http://127.0.0.1:8190 steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - restore_cache: @@ -705,6 +723,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - restore_cache: @@ -755,6 +774,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -787,6 +807,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - restore_cache: @@ -832,6 +853,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -877,6 +899,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -918,6 +941,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -963,6 +987,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -1004,9 +1029,12 @@ jobs: - *python312_image working_directory: ~/project resource_class: large + environment: + REQUEST_TIMEOUT: "180" steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - restore_cache: @@ -1032,7 +1060,8 @@ jobs: -v -x \ --junitxml=test-results/junit.xml \ --durations=5 \ - -n 8" + -n 8 \ + --reruns 1 --only-rerun Timeout" no_output_timeout: 15m # Store test results @@ -1045,6 +1074,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -1089,6 +1119,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -1132,6 +1163,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -1163,6 +1195,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -1205,6 +1238,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -1248,6 +1282,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -1291,6 +1326,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -1321,6 +1357,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -1366,6 +1403,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -1407,6 +1445,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - restore_cache: keys: @@ -1459,6 +1498,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -1482,6 +1522,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -1507,6 +1548,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -1531,6 +1573,7 @@ jobs: steps: - checkout + - skip_if_unrelated_changes - attach_workspace: at: ~/project - setup_google_dns @@ -1570,14 +1613,14 @@ jobs: - run: name: Run helm lint command: | - helm lint ./deploy/charts/litellm-helm + helm lint ./helm/litellm-helm # Run helm tests - run: name: Run helm tests command: | IMAGE_TAG=${CIRCLE_SHA1:-ci} - helm install litellm ./deploy/charts/litellm-helm -f ./deploy/charts/litellm-helm/ci/test-values.yaml \ + helm install litellm ./helm/litellm-helm -f ./helm/litellm-helm/ci/test-values.yaml \ --set image.repository=litellm-ci \ --set image.tag=${IMAGE_TAG} \ --set image.pullPolicy=Never @@ -1606,6 +1649,7 @@ jobs: working_directory: ~/project steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -1698,6 +1742,7 @@ jobs: working_directory: ~/project steps: - checkout + - skip_if_unrelated_changes - attach_workspace: at: ~/project - setup_google_dns @@ -1746,13 +1791,13 @@ jobs: -e LANGFUSE_PROJECT1_SECRET=$LANGFUSE_PROJECT1_SECRET \ -e LANGFUSE_PROJECT2_SECRET=$LANGFUSE_PROJECT2_SECRET \ -e RECORDER_OPENAI_BASE_URL=http://host.docker.internal:8090/v1 \ + -e LITELLM_LOG=ERROR \ --add-host host.docker.internal:host-gateway \ --name my-app \ -v $(pwd)/proxy_server_config.yaml:/app/config.yaml \ my-app:latest \ --config /app/config.yaml \ - --port 4000 \ - --detailed_debug \ + --port 4000 - run: name: Start outputting logs command: docker logs -f my-app @@ -1787,6 +1832,7 @@ jobs: working_directory: ~/project steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -1832,13 +1878,13 @@ jobs: -e LANGFUSE_PROJECT2_PUBLIC=$LANGFUSE_PROJECT2_PUBLIC \ -e LANGFUSE_PROJECT1_SECRET=$LANGFUSE_PROJECT1_SECRET \ -e LANGFUSE_PROJECT2_SECRET=$LANGFUSE_PROJECT2_SECRET \ + -e LITELLM_LOG=ERROR \ --add-host host.docker.internal:host-gateway \ --name my-app \ -v $(pwd)/litellm/proxy/example_config_yaml/oai_misc_config.yaml:/app/config.yaml \ litellm-docker-database:ci \ --config /app/config.yaml \ - --port 4000 \ - --detailed_debug \ + --port 4000 - run: name: Start outputting logs command: docker logs -f my-app @@ -1869,6 +1915,7 @@ jobs: working_directory: ~/project steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -1911,14 +1958,14 @@ jobs: -e COHERE_API_KEY=$COHERE_API_KEY \ -e RECORDER_COHERE_BASE_URL=http://host.docker.internal:8090/__recorder_upstream/api.cohere.com \ -e GCS_FLUSH_INTERVAL="1" \ + -e LITELLM_LOG=ERROR \ --add-host host.docker.internal:host-gateway \ --name my-app \ -v $(pwd)/litellm/proxy/example_config_yaml/otel_test_config.yaml:/app/config.yaml \ -v $(pwd)/litellm/proxy/example_config_yaml/custom_guardrail.py:/app/custom_guardrail.py \ litellm-docker-database:ci \ --config /app/config.yaml \ - --port 4000 \ - --detailed_debug \ + --port 4000 - run: name: Start outputting logs command: docker logs -f my-app @@ -1960,13 +2007,13 @@ jobs: -e OPENAI_API_KEY=$OPENAI_API_KEY \ -e FAKE_OPENAI_API_BASE=http://host.docker.internal:8190 \ -e LITELLM_LICENSE="bad-license" \ + -e LITELLM_LOG=ERROR \ --add-host host.docker.internal:host-gateway \ --name my-app-3 \ -v $(pwd)/litellm/proxy/example_config_yaml/enterprise_config.yaml:/app/config.yaml \ litellm-docker-database:ci \ --config /app/config.yaml \ - --port 4000 \ - --detailed_debug + --port 4000 - run: name: Start outputting logs for second container @@ -2000,6 +2047,7 @@ jobs: working_directory: ~/project steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -2041,13 +2089,13 @@ jobs: -e DD_SITE=$DD_SITE \ -e AWS_REGION_NAME=$AWS_REGION_NAME \ -e PROXY_BATCH_WRITE_AT=2 \ + -e LITELLM_LOG=ERROR \ --add-host host.docker.internal:host-gateway \ --name my-app \ -v $(pwd)/litellm/proxy/example_config_yaml/spend_tracking_config.yaml:/app/config.yaml \ litellm-docker-database:ci \ --config /app/config.yaml \ - --port 4000 \ - --detailed_debug \ + --port 4000 - run: name: Start outputting logs command: docker logs -f my-app @@ -2085,6 +2133,7 @@ jobs: working_directory: ~/project steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -2117,13 +2166,13 @@ jobs: -e USE_DDTRACE=True \ -e DD_API_KEY=$DD_API_KEY \ -e DD_SITE=$DD_SITE \ + -e LITELLM_LOG=ERROR \ --add-host host.docker.internal:host-gateway \ --name my-app \ -v $(pwd)/litellm/proxy/example_config_yaml/multi_instance_simple_config.yaml:/app/config.yaml \ litellm-docker-database:ci \ --config /app/config.yaml \ - --port 4000 \ - --detailed_debug \ + --port 4000 - run: name: Run Docker container 2 command: | @@ -2139,13 +2188,13 @@ jobs: -e USE_DDTRACE=True \ -e DD_API_KEY=$DD_API_KEY \ -e DD_SITE=$DD_SITE \ + -e LITELLM_LOG=ERROR \ --add-host host.docker.internal:host-gateway \ --name my-app-2 \ -v $(pwd)/litellm/proxy/example_config_yaml/multi_instance_simple_config.yaml:/app/config.yaml \ litellm-docker-database:ci \ --config /app/config.yaml \ - --port 4001 \ - --detailed_debug + --port 4001 - run: name: Start outputting logs command: docker logs -f my-app @@ -2180,6 +2229,7 @@ jobs: working_directory: ~/project steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -2201,19 +2251,20 @@ jobs: # the OTEL test - should get this as a trace command: | docker run -d \ + --restart on-failure \ -p 4000:4000 \ -e DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:5432/circle_test \ -e STORE_MODEL_IN_DB="True" \ -e LITELLM_MASTER_KEY="sk-1234" \ -e FAKE_OPENAI_API_BASE=http://host.docker.internal:8190 \ -e LITELLM_LICENSE=$LITELLM_LICENSE \ + -e LITELLM_LOG=ERROR \ --add-host host.docker.internal:host-gateway \ --name my-app \ -v $(pwd)/litellm/proxy/example_config_yaml/store_model_db_config.yaml:/app/config.yaml \ litellm-docker-database:ci \ --config /app/config.yaml \ - --port 4000 \ - --detailed_debug \ + --port 4000 - run: name: Start outputting logs command: docker logs -f my-app @@ -2252,6 +2303,7 @@ jobs: working_directory: ~/project steps: - checkout + - skip_if_unrelated_changes - setup_google_dns # Remove Docker CLI installation since it's already available in machine executor - install_uv @@ -2289,13 +2341,13 @@ jobs: -e DD_API_KEY=$DD_API_KEY \ -e DD_SITE=$DD_SITE \ -e GCS_FLUSH_INTERVAL="1" \ + -e LITELLM_LOG=ERROR \ --add-host host.docker.internal:host-gateway \ --name my-app \ -v $(pwd)/docker/build_from_pip/litellm_config.yaml:/app/config.yaml \ my-app:latest \ --config /app/config.yaml \ - --port 4000 \ - --detailed_debug \ + --port 4000 - run: name: Start outputting logs command: docker logs -f my-app @@ -2333,6 +2385,7 @@ jobs: working_directory: ~/project steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -2365,14 +2418,14 @@ jobs: -e DD_SITE=$DD_SITE \ -e LITELLM_LICENSE=$LITELLM_LICENSE \ -e LITELLM_USE_CHAT_COMPLETIONS_URL_FOR_ANTHROPIC_MESSAGES=true \ + -e LITELLM_LOG=ERROR \ --add-host host.docker.internal:host-gateway \ --name my-app \ -v $(pwd)/litellm/proxy/example_config_yaml/pass_through_config.yaml:/app/config.yaml \ -v $(pwd)/litellm/proxy/example_config_yaml/custom_auth_basic.py:/app/custom_auth_basic.py \ litellm-docker-database:ci \ --config /app/config.yaml \ - --port 4000 \ - --detailed_debug \ + --port 4000 - run: name: Start outputting logs command: docker logs -f my-app @@ -2471,6 +2524,7 @@ jobs: working_directory: ~/project steps: - checkout + - skip_if_unrelated_changes - setup_google_dns - install_uv - run: @@ -2499,13 +2553,13 @@ jobs: -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \ -e AWS_REGION_NAME="us-east-1" \ -e LITELLM_LOCAL_ANTHROPIC_BETA_HEADERS="True" \ + -e LITELLM_LOG=ERROR \ --add-host host.docker.internal:host-gateway \ --name my-app \ -v $(pwd)/tests/proxy_e2e_anthropic_messages_tests/test_config.yaml:/app/config.yaml \ litellm-docker-database:ci \ --config /app/config.yaml \ - --port 4000 \ - --detailed_debug + --port 4000 - run: name: Start outputting logs command: docker logs -f my-app @@ -2537,6 +2591,7 @@ jobs: - *python312_image steps: - checkout + - skip_if_unrelated_changes - attach_workspace: at: . # Check file locations @@ -2567,6 +2622,8 @@ jobs: working_directory: ~/project steps: - checkout + - skip_if_unrelated_changes: + category: client - setup_google_dns - restore_cache: keys: @@ -2609,6 +2666,8 @@ jobs: working_directory: ~/project steps: - checkout + - skip_if_unrelated_changes: + category: client - setup_google_dns - restore_cache: keys: @@ -2629,7 +2688,7 @@ jobs: cd ui/litellm-dashboard CI=true npm run test -- --run \ - --pool forks --poolOptions.forks.maxForks=8 + --pool forks --poolOptions.forks.maxForks=6 e2e_ui_testing: docker: @@ -2654,6 +2713,8 @@ jobs: PROXY_LOGOUT_URL: "https://www.example.com" steps: - checkout + - skip_if_unrelated_changes: + category: client - setup_google_dns - install_uv - restore_cache: @@ -2791,6 +2852,8 @@ jobs: SERVER_ROOT_PATH: "/litellm" steps: - checkout + - skip_if_unrelated_changes: + category: client - setup_google_dns - install_uv - restore_cache: @@ -2892,6 +2955,7 @@ jobs: working_directory: ~/project steps: - checkout + - skip_if_unrelated_changes - run: name: Build Docker image @@ -2917,6 +2981,7 @@ jobs: working_directory: ~/project steps: - checkout + - skip_if_unrelated_changes - attach_workspace: at: ~/project - setup_google_dns diff --git a/.circleci/scripts/classify_changes.sh b/.circleci/scripts/classify_changes.sh new file mode 100755 index 00000000000..2c15428be6a --- /dev/null +++ b/.circleci/scripts/classify_changes.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -uo pipefail + +category="${1:?usage: classify_changes.sh }" + +has_client=false +has_backend=false +while IFS= read -r file || [ -n "$file" ]; do + [ -n "$file" ] || continue + case "$file" in + ui/*) has_client=true ;; + docs/* | *.md | *.mdx) : ;; + *) has_backend=true ;; + esac +done + +case "$category" in + backend) + [ "$has_backend" = true ] && echo run || echo skip + ;; + client) + { [ "$has_client" = true ] || [ "$has_backend" = true ]; } && echo run || echo skip + ;; + *) + echo run + ;; +esac diff --git a/.circleci/scripts/path_filter.sh b/.circleci/scripts/path_filter.sh new file mode 100755 index 00000000000..dcf64a24399 --- /dev/null +++ b/.circleci/scripts/path_filter.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +set -uo pipefail + +category="${1:?usage: path_filter.sh }" +here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +run_full() { + echo "path-filter[$category]: running job ($1)" + exit 0 +} + +[ -n "${CIRCLE_PULL_REQUEST:-}" ] || run_full "not a pull request" + +candidate_bases="main litellm_internal_staging litellm_oss_staging" +merge_base="" +for base in $candidate_bases; do + git fetch --quiet origin "$base" 2>/dev/null || continue + candidate="$(git merge-base HEAD FETCH_HEAD 2>/dev/null)" || continue + [ -n "$candidate" ] || continue + if [ -z "$merge_base" ] || git merge-base --is-ancestor "$merge_base" "$candidate" 2>/dev/null; then + merge_base="$candidate" + fi +done + +[ -n "$merge_base" ] || run_full "could not resolve a merge base against $candidate_bases" + +changed="$(git diff --name-only "$merge_base" HEAD 2>/dev/null)" || run_full "git diff failed" +[ -n "$changed" ] || run_full "no files changed vs $merge_base" + +echo "path-filter[$category]: changed files vs ${merge_base}:" +printf '%s\n' "$changed" | sed 's/^/ /' || true + +decision="$(printf '%s\n' "$changed" | bash "$here/classify_changes.sh" "$category")" || run_full "classify_changes.sh failed" + +if [ "$decision" = run ]; then + run_full "$category-relevant changes detected" +fi + +echo "path-filter[$category]: only unrelated (docs/client) changes detected; halting job as successful" +circleci-agent step halt diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 7e705ec4f8f..2527239b904 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -13,7 +13,7 @@ 7edf3a9cb55548b143df1692f4ed7c4681d7fcf7 # style: reformat litellm/ with ruff format (#31317) -430b5b8f1b12dc261a49fda99ac5d1b22381a428 +17bfd415aeb5a57fb646b5cc67da1c730aa7c50b # style: unify ruff format width on 120 (#31518) -3dfbeabe626d203ac9de86024519d9a96c484ce4 +48b5a5a0cc5a694a11219416ee0b6eb6e620e74e diff --git a/.github/actions/detect-backend-changes/action.yml b/.github/actions/detect-backend-changes/action.yml new file mode 100644 index 00000000000..af01038f294 --- /dev/null +++ b/.github/actions/detect-backend-changes/action.yml @@ -0,0 +1,48 @@ +name: "Detect backend-relevant changes" +description: >- + Classify the pull request's changed files with .circleci/scripts/classify_changes.sh + and expose decision=run|skip. decision=skip means only ui/**, **.md or **.mdx files + changed, so callers can short-circuit expensive steps while the job still completes + successfully and satisfies its required status check. The decision defaults to run for + any non pull_request event or whenever the changed set cannot be resolved, so tests are + never skipped when the classification is uncertain. + +outputs: + decision: + description: "run when backend-relevant files changed, otherwise skip" + value: ${{ steps.classify.outputs.decision }} + +runs: + using: composite + steps: + - id: classify + shell: bash + env: + BASE_SHA: ${{ github.event.pull_request.base.sha }} + run: | + set -uo pipefail + if [ -z "${BASE_SHA:-}" ]; then + echo "detect-backend-changes: not a pull_request event; running job" + echo "decision=run" >> "${GITHUB_OUTPUT}" + exit 0 + fi + if ! git fetch --no-tags --depth=1 origin "${BASE_SHA}" >/dev/null 2>&1; then + echo "detect-backend-changes: could not fetch base ${BASE_SHA}; running job" + echo "decision=run" >> "${GITHUB_OUTPUT}" + exit 0 + fi + changed="$(git diff --name-only "${BASE_SHA}" HEAD 2>/dev/null)" || { + echo "detect-backend-changes: git diff failed; running job" + echo "decision=run" >> "${GITHUB_OUTPUT}" + exit 0 + } + if [ -z "${changed}" ]; then + echo "detect-backend-changes: no changed files vs ${BASE_SHA}; skipping job" + echo "decision=skip" >> "${GITHUB_OUTPUT}" + exit 0 + fi + echo "detect-backend-changes: changed files vs ${BASE_SHA}:" + printf '%s\n' "${changed}" | sed 's/^/ /' + decision="$(printf '%s\n' "${changed}" | bash .circleci/scripts/classify_changes.sh backend)" || decision="run" + echo "detect-backend-changes: decision=${decision}" + echo "decision=${decision}" >> "${GITHUB_OUTPUT}" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 12ad124fa20..bd9fc2285d1 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -4,7 +4,7 @@ ## Linear ticket - + ## Pre-Submission checklist @@ -13,7 +13,7 @@ - [ ] I have added meaningful tests - [ ] My PR passes all CI/CD checks (e.g., lint, format, unit tests) - [ ] My PR's scope is as isolated as possible; it only solves 1 specific problem -- [ ] I have requested a Greptile review by commenting `@greptileai` and received a **Confidence Score of at least 4/5** before requesting a maintainer review +- [ ] I have received a Greptile **Confidence Score of at least 4/5** before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment `@greptileai` to re-request a review after pushing changes) ## Delays in PR merge? @@ -24,6 +24,7 @@ If you're seeing a delay in your PR being merged, ping the LiteLLM Team on [Slac diff --git a/.github/workflows/_test-unit-base.yml b/.github/workflows/_test-unit-base.yml index 25c6d4a7019..9fd81b27f3b 100644 --- a/.github/workflows/_test-unit-base.yml +++ b/.github/workflows/_test-unit-base.yml @@ -45,12 +45,18 @@ jobs: name: Run tests runs-on: ubuntu-latest timeout-minutes: ${{ inputs.timeout-minutes }} + outputs: + decision: ${{ steps.changes.outputs.decision }} steps: - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 with: persist-credentials: false + - name: Detect backend-relevant changes + id: changes + uses: ./.github/actions/detect-backend-changes + - name: Set up Python uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: @@ -72,16 +78,19 @@ jobs: ${{ runner.os }}-uv- - name: Install dependencies + if: steps.changes.outputs.decision != 'skip' run: | .github/scripts/uv_sync_with_retries.sh --frozen --group ci --group proxy-dev --extra google --extra proxy --extra semantic-router - name: Generate Prisma client + if: steps.changes.outputs.decision != 'skip' env: PRISMA_BINARY_CACHE_DIR: ${{ runner.temp }}/prisma-cache run: | uv run --no-sync prisma generate --schema litellm/proxy/schema.prisma - name: Run tests + if: steps.changes.outputs.decision != 'skip' env: TEST_PATH: ${{ inputs.test-path }} MAX_FAILURES: ${{ inputs.max-failures }} @@ -114,7 +123,7 @@ jobs: fi - name: Save coverage report - if: always() + if: always() && steps.changes.outputs.decision != 'skip' uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 with: name: coverage-${{ inputs.artifact-name }}-${{ github.run_id }}-${{ github.run_attempt }} @@ -124,7 +133,7 @@ jobs: upload-coverage: name: Upload coverage to Codecov needs: run - if: always() + if: always() && needs.run.outputs.decision != 'skip' runs-on: ubuntu-latest permissions: contents: read diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index 17efbf90339..a1772102b89 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -4,9 +4,11 @@ on: push: branches: - main + - litellm_internal_staging pull_request: branches: - main + - litellm_internal_staging # Allow CodSpeed to trigger backtest performance analysis # in order to generate initial data workflow_dispatch: @@ -21,8 +23,8 @@ concurrency: jobs: benchmarks: - runs-on: ubuntu-latest - timeout-minutes: 15 + runs-on: ubuntu-24.04 + timeout-minutes: 60 steps: - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 @@ -48,6 +50,8 @@ jobs: uv run --frozen --no-default-groups --with pytest==8.3.5 --with pytest-codspeed==4.3.0 + --with "mcp>=1.26.0,<2.0" + --with "a2a-sdk>=1.1.0,<2.0" pytest -p pytest_codspeed.plugin tests/benchmarks/ diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 4834775e329..0ad84cd3ceb 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -122,10 +122,28 @@ jobs: makeLatest = (!latestVersion || isAtLeast(newVersion, latestVersion)) ? "true" : "false"; } + try { + await github.rest.git.createRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: `refs/tags/${tag}`, + sha: commitHash, + }); + } catch (error) { + if (error.status !== 422) throw error; + const existing = await github.rest.git.getRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: `tags/${tag}`, + }); + if (existing.data.object.sha !== commitHash) { + throw new Error(`Tag ${tag} already exists at ${existing.data.object.sha}, expected ${commitHash}`); + } + } + const response = await github.rest.repos.createRelease({ draft: true, generate_release_notes: true, - target_commitish: commitHash, name: tag, owner: context.repo.owner, prerelease: isPrerelease, @@ -138,11 +156,21 @@ jobs: owner: context.repo.owner, repo: context.repo.repo, release_id: response.data.id, + tag_name: tag, body: updatedBody, draft: false, - make_latest: makeLatest, }); + if (!isPrerelease) { + await github.rest.repos.updateRelease({ + owner: context.repo.owner, + repo: context.repo.repo, + release_id: response.data.id, + tag_name: tag, + make_latest: makeLatest, + }); + } + } catch (error) { core.setFailed(error.message); } diff --git a/.github/workflows/create_daily_oss_branch.yml b/.github/workflows/create_daily_oss_branch.yml new file mode 100644 index 00000000000..43de4a0e75f --- /dev/null +++ b/.github/workflows/create_daily_oss_branch.yml @@ -0,0 +1,61 @@ +name: Create Daily OSS Branch + +on: + schedule: + - cron: "0 16 * * 1-5" # 9am PT during daylight saving time, weekdays. + workflow_dispatch: + inputs: + date: + description: "Branch date in YYYY_MM_DD format. Defaults to today's UTC date." + required: false + type: string + +permissions: + contents: write + +jobs: + create-oss-branch: + if: github.repository == 'BerriAI/litellm' + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Create dated OSS branch + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REQUESTED_DATE: ${{ inputs.date }} + run: | + set -euo pipefail + + if [ -n "${REQUESTED_DATE}" ]; then + if ! echo "${REQUESTED_DATE}" | grep -Eq '^[0-9]{4}_[0-9]{2}_[0-9]{2}$'; then + echo "::error::date must use YYYY_MM_DD format, got '${REQUESTED_DATE}'" + exit 1 + fi + BRANCH_DATE="${REQUESTED_DATE}" + else + BRANCH_DATE="$(date -u +'%Y_%m_%d')" + fi + + BRANCH_NAME="litellm_oss_daily_${BRANCH_DATE}" + echo "Creating branch: ${BRANCH_NAME}" + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + git fetch origin main "${BRANCH_NAME}" || true + + if git show-ref --verify --quiet "refs/remotes/origin/${BRANCH_NAME}"; then + echo "Branch ${BRANCH_NAME} already exists. Skipping creation." + exit 0 + fi + + git checkout -b "${BRANCH_NAME}" origin/main + git push "https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" "${BRANCH_NAME}" + echo "Successfully created and pushed branch: ${BRANCH_NAME}" diff --git a/.github/workflows/guard-main-branch.yml b/.github/workflows/guard-main-branch.yml index 21aad18d298..aa4968f0c1e 100644 --- a/.github/workflows/guard-main-branch.yml +++ b/.github/workflows/guard-main-branch.yml @@ -31,12 +31,12 @@ jobs: echo "PR head repo: $HEAD_REPO" echo "PR head branch: $HEAD_REF" if [ "$HEAD_REPO" != "$BASE_REPO" ]; then - echo "::error::PRs to main must originate from the canonical repository ($BASE_REPO), not a fork ($HEAD_REPO). External contributors should open PRs against the 'litellm_oss_staging' branch instead." + echo "::error::PRs to main must originate from the canonical repository ($BASE_REPO), not a fork ($HEAD_REPO). External contributors should open PRs against the current daily OSS branch (named litellm_oss_daily_YYYY_MM_DD; a fresh one is cut each weekday, so target the most recent) instead." exit 1 fi if [ "$HEAD_REF" = "litellm_internal_staging" ] || [[ "$HEAD_REF" == litellm_hotfix_?* ]]; then echo "Allowed source branch." exit 0 fi - echo "::error::PRs to main must originate from 'litellm_internal_staging' or a 'litellm_hotfix_*' branch. Got: '$HEAD_REF'. If this is a contribution, retarget the PR against 'litellm_oss_staging' instead." + echo "::error::PRs to main must originate from 'litellm_internal_staging' or a 'litellm_hotfix_*' branch. Got: '$HEAD_REF'. If this is a contribution, retarget the PR against the current daily OSS branch (named litellm_oss_daily_YYYY_MM_DD; a fresh one is cut each weekday, so target the most recent) instead." exit 1 diff --git a/.github/workflows/helm_unit_test.yml b/.github/workflows/helm_unit_test.yml index 06836b1d1cd..5b9d20d97f3 100644 --- a/.github/workflows/helm_unit_test.yml +++ b/.github/workflows/helm_unit_test.yml @@ -38,4 +38,6 @@ jobs: echo "Helm unittest plugin integrity verified: $ACTUAL_SHA" - name: Run unit tests - run: helm unittest -f 'tests/*.yaml' deploy/charts/litellm-helm + run: | + helm unittest -f 'tests/*.yaml' helm/litellm-helm + helm unittest -f 'tests/*.yaml' helm/litellm diff --git a/.github/workflows/oss_daily_guardrails.yml b/.github/workflows/oss_daily_guardrails.yml new file mode 100644 index 00000000000..950c51c9b60 --- /dev/null +++ b/.github/workflows/oss_daily_guardrails.yml @@ -0,0 +1,50 @@ +name: OSS Daily Guardrails + +on: + push: + branches: + - "litellm_oss_daily_20*" + pull_request: + branches: + - "litellm_oss_daily_20*" + - litellm_internal_staging + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + oss-safe-checks: + name: Run OSS daily safe checks + if: startsWith(github.ref_name, 'litellm_oss_daily_20') || startsWith(github.head_ref, 'litellm_oss_daily_20') || startsWith(github.base_ref, 'litellm_oss_daily_20') + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + with: + persist-credentials: false + + - name: Set up Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: "3.12" + + - name: Set up uv + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 + with: + version: "0.10.9" + + - name: Run secret scan test + run: | + uv run --frozen --with 'pytest==9.0.2' pytest tests/litellm/test_no_hardcoded_secrets.py -v + + - name: Run Ruff + run: | + uv sync --frozen + cd litellm + uv run --no-sync ruff check . diff --git a/.github/workflows/test-linting.yml b/.github/workflows/test-linting.yml index 6deb28c95c7..c2fc3453261 100644 --- a/.github/workflows/test-linting.yml +++ b/.github/workflows/test-linting.yml @@ -63,7 +63,7 @@ jobs: env: BASE_SHA: ${{ github.event.pull_request.base.sha }} run: | - git diff --name-only "$BASE_SHA"...HEAD -- 'litellm/**/*.py' | grep -v '^litellm/enterprise/' > "$RUNNER_TEMP/ruff_format_files.txt" || true + git diff --name-only --diff-filter=ACMR "$BASE_SHA"...HEAD -- 'litellm/**/*.py' | grep -v '^litellm/enterprise/' > "$RUNNER_TEMP/ruff_format_files.txt" || true if [ ! -s "$RUNNER_TEMP/ruff_format_files.txt" ]; then echo "No changed litellm Python files to check with ruff format." exit 0 diff --git a/.github/workflows/test-litellm-ui-build.yml b/.github/workflows/test-litellm-ui-build.yml index ce8d8cb9c95..525e2c5b949 100644 --- a/.github/workflows/test-litellm-ui-build.yml +++ b/.github/workflows/test-litellm-ui-build.yml @@ -36,79 +36,3 @@ jobs: - name: Build run: npm run build - - frontend-lint: - runs-on: ubuntu-latest - timeout-minutes: 8 - defaults: - run: - working-directory: ui/litellm-dashboard - - steps: - - name: Checkout repository - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - with: - fetch-depth: 0 - persist-credentials: false - - - name: Collect changed files - id: changed - env: - BASE_SHA: ${{ github.event.pull_request.base.sha }} - run: | - : > "$RUNNER_TEMP/prettier_files.txt" - : > "$RUNNER_TEMP/eslint_files.txt" - while IFS= read -r f; do - [ -f "$f" ] || continue - case "$f" in - *.js | *.jsx | *.ts | *.tsx | *.mjs | *.cjs) - printf '%s\n' "$f" >> "$RUNNER_TEMP/prettier_files.txt" - printf '%s\n' "$f" >> "$RUNNER_TEMP/eslint_files.txt" ;; - *.json | *.css | *.scss | *.md | *.mdx | *.yml | *.yaml | *.html) - printf '%s\n' "$f" >> "$RUNNER_TEMP/prettier_files.txt" ;; - esac - done < <(git diff --name-only --diff-filter=ACMR --relative "$BASE_SHA"...HEAD -- .) - if [ -s "$RUNNER_TEMP/prettier_files.txt" ] || [ -s "$RUNNER_TEMP/eslint_files.txt" ]; then - echo "has_files=true" >> "$GITHUB_OUTPUT" - else - echo "has_files=false" >> "$GITHUB_OUTPUT" - echo "No lintable UI files changed in this PR; nothing to check." - fi - - - name: Setup Node.js - if: steps.changed.outputs.has_files == 'true' - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 - with: - node-version: "20" - cache: "npm" - cache-dependency-path: ui/litellm-dashboard/package-lock.json - - - name: Install dependencies - if: steps.changed.outputs.has_files == 'true' - run: npm ci - - - name: Lint changed files (prettier + eslint) - if: steps.changed.outputs.has_files == 'true' - run: | - prettier_files=() - eslint_files=() - while IFS= read -r f; do prettier_files+=("$f"); done < "$RUNNER_TEMP/prettier_files.txt" - while IFS= read -r f; do eslint_files+=("$f"); done < "$RUNNER_TEMP/eslint_files.txt" - status=0 - if [ ${#prettier_files[@]} -gt 0 ]; then - echo "::group::Prettier (${#prettier_files[@]} files)" - npx prettier --check "${prettier_files[@]}" || { status=1; echo "::error::Unformatted files. Fix with: npm run format"; } - echo "::endgroup::" - fi - if [ ${#eslint_files[@]} -gt 0 ]; then - echo "::group::ESLint (${#eslint_files[@]} files)" - npx eslint --no-warn-ignored --pass-on-unpruned-suppressions "${eslint_files[@]}" || status=1 - echo "::endgroup::" - fi - exit $status - - - name: Check lint budgets - if: ${{ !cancelled() && steps.changed.outputs.has_files == 'true' }} - run: | - npx eslint . -f json -o "$RUNNER_TEMP/lint-report.json" || true - node scripts/check-lint-budgets.mjs "$RUNNER_TEMP/lint-report.json" eslint-budgets.json --check eslint-metrics.json diff --git a/.github/workflows/test-litellm-ui-lint.yml b/.github/workflows/test-litellm-ui-lint.yml new file mode 100644 index 00000000000..226cbf6a879 --- /dev/null +++ b/.github/workflows/test-litellm-ui-lint.yml @@ -0,0 +1,92 @@ +name: UI Lint +permissions: + contents: read + +on: + pull_request: + branches: + - main + - litellm_internal_staging + - litellm_oss_staging + - "litellm_**" + +jobs: + frontend-lint: + runs-on: ubuntu-latest + timeout-minutes: 8 + defaults: + run: + working-directory: ui/litellm-dashboard + + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Collect changed files + id: changed + env: + BASE_SHA: ${{ github.event.pull_request.base.sha }} + run: | + : > "$RUNNER_TEMP/prettier_files.txt" + : > "$RUNNER_TEMP/eslint_files.txt" + while IFS= read -r f; do + [ -f "$f" ] || continue + case "$f" in + *.js | *.jsx | *.ts | *.tsx | *.mjs | *.cjs) + printf '%s\n' "$f" >> "$RUNNER_TEMP/prettier_files.txt" + printf '%s\n' "$f" >> "$RUNNER_TEMP/eslint_files.txt" ;; + *.json | *.css | *.scss | *.md | *.mdx | *.yml | *.yaml | *.html) + printf '%s\n' "$f" >> "$RUNNER_TEMP/prettier_files.txt" ;; + esac + done < <(git diff --name-only --diff-filter=ACMR --relative "$BASE_SHA"...HEAD -- .) + if [ -s "$RUNNER_TEMP/prettier_files.txt" ] || [ -s "$RUNNER_TEMP/eslint_files.txt" ]; then + echo "has_files=true" >> "$GITHUB_OUTPUT" + else + echo "has_files=false" >> "$GITHUB_OUTPUT" + echo "No lintable UI files changed in this PR; nothing to check." + fi + + - name: Setup Node.js + if: steps.changed.outputs.has_files == 'true' + uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 + with: + node-version: "20" + cache: "npm" + cache-dependency-path: ui/litellm-dashboard/package-lock.json + + - name: Install dependencies + if: steps.changed.outputs.has_files == 'true' + run: npm ci + + - name: Lint changed files (prettier + eslint) + if: steps.changed.outputs.has_files == 'true' + run: | + prettier_files=() + eslint_files=() + while IFS= read -r f; do prettier_files+=("$f"); done < "$RUNNER_TEMP/prettier_files.txt" + while IFS= read -r f; do eslint_files+=("$f"); done < "$RUNNER_TEMP/eslint_files.txt" + status=0 + if [ ${#prettier_files[@]} -gt 0 ]; then + echo "::group::Prettier (${#prettier_files[@]} files)" + npx prettier --check "${prettier_files[@]}" || { status=1; echo "::error::Unformatted files. Fix with: npm run format"; } + echo "::endgroup::" + fi + if [ ${#eslint_files[@]} -gt 0 ]; then + echo "::group::ESLint (${#eslint_files[@]} files)" + npx eslint --no-warn-ignored --pass-on-unpruned-suppressions "${eslint_files[@]}" || status=1 + echo "::endgroup::" + fi + exit $status + + - name: Check lint budgets + if: ${{ !cancelled() && steps.changed.outputs.has_files == 'true' }} + run: | + npx eslint . -f json -o "$RUNNER_TEMP/lint-report.json" || true + node scripts/check-lint-budgets.mjs "$RUNNER_TEMP/lint-report.json" eslint-budgets.json --check eslint-metrics.json + + - name: Check for dead code (knip) + if: ${{ !cancelled() && steps.changed.outputs.has_files == 'true' }} + run: npm run knip diff --git a/.github/workflows/test-terraform-provider.yml b/.github/workflows/test-terraform-provider.yml new file mode 100644 index 00000000000..03d8ff3461c --- /dev/null +++ b/.github/workflows/test-terraform-provider.yml @@ -0,0 +1,113 @@ +name: Terraform Provider + +on: + push: + paths: + - "terraform/provider/**" + - ".github/workflows/test-terraform-provider.yml" + pull_request: + branches: + - main + - litellm_internal_staging + - litellm_oss_staging + - "litellm_**" + paths: + - "terraform/provider/**" + - "litellm/proxy/**" + - ".github/workflows/test-terraform-provider.yml" + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + provider-checks: + name: gofmt, vet, build, test + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: + run: + working-directory: terraform/provider + steps: + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + with: + persist-credentials: false + + - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 + with: + go-version-file: terraform/provider/go.mod + cache: true + cache-dependency-path: terraform/provider/go.sum + + - name: gofmt + run: | + UNFORMATTED=$(gofmt -l .) + if [ -n "${UNFORMATTED}" ]; then + echo "::error::gofmt required for: ${UNFORMATTED}" + exit 1 + fi + + - name: go vet + run: go vet ./... + + - name: Build + run: go build ./... + + - name: Test + run: go test -timeout 120s ./... + + endpoint-drift: + name: Provider endpoints vs proxy OpenAPI schema + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + with: + persist-credentials: false + + - name: Set up Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: "3.12" + + - name: Set up uv + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 + with: + version: "0.10.9" + + - name: Cache uv dependencies + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: | + ~/.cache/uv + .venv + key: ${{ runner.os }}-uv-${{ hashFiles('uv.lock') }} + restore-keys: | + ${{ runner.os }}-uv- + + - name: Install dependencies + run: | + .github/scripts/uv_sync_with_retries.sh --frozen --group ci --group proxy-dev --extra google --extra proxy --extra semantic-router + + - name: Generate Prisma client + env: + PRISMA_BINARY_CACHE_DIR: ${{ runner.temp }}/prisma-cache + run: | + uv run --no-sync prisma generate --schema litellm/proxy/schema.prisma + + - name: Generate proxy OpenAPI schema + run: | + uv run --no-sync python terraform/provider/tools/dump_openapi.py "${RUNNER_TEMP}/openapi.json" + + - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 + with: + go-version-file: terraform/provider/go.mod + cache: true + cache-dependency-path: terraform/provider/go.sum + + - name: Audit provider endpoints against the schema + working-directory: terraform/provider + run: go run ./tools/endpointaudit -provider-dir ./litellm -spec "${RUNNER_TEMP}/openapi.json" diff --git a/.github/workflows/test-unit-documentation.yml b/.github/workflows/test-unit-documentation.yml index 4cef791a9b3..03f9f0a510b 100644 --- a/.github/workflows/test-unit-documentation.yml +++ b/.github/workflows/test-unit-documentation.yml @@ -32,6 +32,10 @@ jobs: path: docs/my-website persist-credentials: false + - name: Detect backend-relevant changes + id: changes + uses: ./.github/actions/detect-backend-changes + - name: Set up Python uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: @@ -53,10 +57,12 @@ jobs: ${{ runner.os }}-uv- - name: Install dependencies + if: steps.changes.outputs.decision != 'skip' run: | .github/scripts/uv_sync_with_retries.sh --frozen --group ci --group proxy-dev --extra google --extra proxy --extra semantic-router - name: Generate Prisma client + if: steps.changes.outputs.decision != 'skip' env: PRISMA_BINARY_CACHE_DIR: ${{ runner.temp }}/prisma-cache run: | @@ -64,6 +70,7 @@ jobs: # Run the same documentation tests that CircleCI ran (as direct Python scripts) - name: Run documentation validation tests + if: steps.changes.outputs.decision != 'skip' run: | uv run --no-sync python ./tests/documentation_tests/test_env_keys.py uv run --no-sync python ./tests/documentation_tests/test_router_settings.py diff --git a/.github/workflows/test-unit-proxy-legacy.yml b/.github/workflows/test-unit-proxy-legacy.yml index 8db218cd1fc..0068e80e584 100644 --- a/.github/workflows/test-unit-proxy-legacy.yml +++ b/.github/workflows/test-unit-proxy-legacy.yml @@ -49,6 +49,10 @@ jobs: with: persist-credentials: false + - name: Detect backend-relevant changes + id: changes + uses: ./.github/actions/detect-backend-changes + - name: Set up Python uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: @@ -70,16 +74,19 @@ jobs: ${{ runner.os }}-uv- - name: Install dependencies + if: steps.changes.outputs.decision != 'skip' run: | .github/scripts/uv_sync_with_retries.sh --frozen --group ci --group proxy-dev --extra google --extra proxy --extra semantic-router - name: Generate Prisma client + if: steps.changes.outputs.decision != 'skip' env: PRISMA_BINARY_CACHE_DIR: ${{ runner.temp }}/prisma-cache run: | uv run --no-sync prisma generate --schema litellm/proxy/schema.prisma - name: Run tests - ${{ matrix.test-group.name }} + if: steps.changes.outputs.decision != 'skip' env: TEST_PATH: ${{ matrix.test-group.path }} run: | diff --git a/.github/workflows/test_server_root_path.yml b/.github/workflows/test_server_root_path.yml index ac363071d55..f59cee29893 100644 --- a/.github/workflows/test_server_root_path.yml +++ b/.github/workflows/test_server_root_path.yml @@ -16,6 +16,7 @@ jobs: timeout-minutes: 30 strategy: + fail-fast: false matrix: root_path: ["/api/v1", "/llmproxy"] @@ -108,8 +109,26 @@ jobs: - name: Install UI deps and Chromium working-directory: ui/litellm-dashboard run: | - npm ci - npx playwright install --with-deps chromium + retry() { + local attempt=1 + local max_attempts=4 + until "$@"; do + if [ "$attempt" -ge "$max_attempts" ]; then + echo "Command failed after $attempt attempts: $*" + return 1 + fi + echo "Attempt $attempt failed: $*. Retrying in $((attempt * 15))s..." + sleep $((attempt * 15)) + attempt=$((attempt + 1)) + done + } + + npm config set fetch-retries 5 + npm config set fetch-retry-mintimeout 20000 + npm config set fetch-retry-maxtimeout 120000 + + retry npm ci + retry npx playwright install --with-deps chromium - name: Run SERVER_ROOT_PATH redirect e2e working-directory: ui/litellm-dashboard diff --git a/.gitignore b/.gitignore index 5b7c6e5585b..e3ccf50508f 100644 --- a/.gitignore +++ b/.gitignore @@ -50,9 +50,10 @@ litellm/proxy/tests/package-lock.json ui/litellm-dashboard/.next ui/litellm-dashboard/node_modules ui/litellm-dashboard/next-env.d.ts -deploy/charts/litellm/*.tgz -deploy/charts/litellm/charts/* -deploy/charts/*.tgz +ui/litellm-dashboard/package.json +ui/litellm-dashboard/package-lock.json +helm/litellm-helm/*.tgz +helm/*.tgz litellm/proxy/vertex_key.json **/.vim/ **/node_modules @@ -85,12 +86,17 @@ litellm/proxy/db/migrations/* litellm/proxy/migrations/*config.yaml litellm/proxy/migrations/* litellm/proxy/to_delete_loadtest_work/* +config.yaml tests/litellm/litellm_core_utils/llm_cost_calc/log.txt tests/test_custom_dir/* +test.py +litellm_config.yaml +!.github/observatory/litellm_config.yaml .cursor litellm/proxy/to_delete_loadtest_work/* update_model_cost_map.py +tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server_manager.py scripts/test_vertex_ai_search.py LAZY_LOADING_IMPROVEMENTS.md STABILIZATION_TODO.md @@ -124,6 +130,4 @@ crash.*.log # pytest coverage data .coverage -# _experimental/out UI build output -# (both componentized and non-componentized build the UI on project release) -litellm/proxy/_experimental/out/ \ No newline at end of file +ui/litellm-dashboard/out/ diff --git a/CLAUDE.md b/CLAUDE.md index eb32c2cd6da..78da2c65d96 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,8 +1,7 @@ -Do not write comments unless they are absolutely necessary to explain some very complex business logic. Please clean up if there are comments that are not absolutely necessary. Do not remove comments that are unrelated to the addition of the code of this PR - -Explanation: code comments are, in a way, a violation of DRY code. You must update logic in two locations to change the code and "hard to change" is literally the definition of tech debt. We should instead aim to write code that is intuitive to the reader, while being both easy to maintain and high performance +Do not write any comments (existing comments can stay) unless explicitly asked to in a user (not system) prompt Don't assume that the existing code is correct or the right way of doing things / good coding patterns. In fact, there are a lot of bad coding practices, overly complex code, code smells, etc. If something doesn't look right, speak up. Feel free to break existing patterns or question weird existing code to make new code high quality, as in: + - correct - secure - performant @@ -18,11 +17,15 @@ Same thing for bug fixes. The tests should make it so that this specific bug can `tests/test_litellm/` mirrors `litellm/` in a parallel path (see `tests/test_litellm/readme.md`). Name tests `test_.py`, but always match the existing test file in the directory you touch — many provider dirs use longer descriptive names (e.g. `test_anthropic_chat_transformation.py`) to avoid ambiguity across sibling folders. For bug fixes, extend the existing mapped test file rather than creating a new one. Only create a new test file for a new feature (provider, endpoint, or transformation module) that has no mapped test yet, following that directory's naming convention (or `test_.py` if you're the first test there). One focused regression test beats many shallow ones -When creating PRs, don't set base to `main`. `litellm_internal_staging` serves that purpose +End-to-end tests belong in `tests/e2e/` and must follow the harness conventions documented in that directory's `CLAUDE.md` -Always use @.github/pull_request_template.md as a guide for your PR body +When creating PRs, don't set base to `main`. `litellm_internal_staging` serves that purpose for internal contributors; external / OSS contributions target the current daily OSS branch instead, named `litellm_oss_daily_YYYY_MM_DD` (a fresh one is cut each weekday, so use the most recent) -Never use `pytest` commands or the like as "Screenshots / Proof of Fix". We prefer curl'ing a live proxy instance running on localhost:4000 (I like to run it with `python litellm/proxy/proxy_cli.py --config litellm/proxy/dev_config.yaml --detailed_debug --reload --use_v2_migration_resolver 2>&1 | tee litellm.log`) and showing both the command run and the output. Also, it should hit real LLM provider APIs, not mocks, and cost real $$$ because that is the most realistic test. The proof of fix should be exactly what the end user / customer would see / do. The run logs in PR #27703 is a prime example of how to do it (not a huge fan of using a python test script that future me and the team will have no visibility into; I prefer just curl commands or a short list of bash commands (e.g., using `for`)). If it's a UI thing, just tell me which URLs to go to (e.g., http://localhost:4000/ui/?page=logs), where to click, what fields to fill out, etc. along with the other commands to run in an ordered list, and I'll do it myself and post the screenshots after you make the PR +When writing a PR body, treat the comments and imperative instructions inside @.github/pull_request_template.md as rules to follow, not just layout. Agent harnesses may strip HTML comments from copies of that file injected into context, so read .github/pull_request_template.md from disk before writing a PR body to make sure you see every comment rule + +If you're resolving a linear ticket, in the "## Linear ticket" section of the PR, say "Resolves LIT-1234", replacing "LIT-1234" with the actual ticket id that you're resolving. If you don't have the ticket id, don't make one up or search for it. Just leave the section blank + +Never use `pytest` commands or the like as "Screenshots / Proof of Fix". We prefer curl'ing a live proxy instance running on localhost:4000 (I like to run it with `python litellm/proxy/proxy_cli.py --config litellm/proxy/dev_config.yaml --detailed_debug --reload --use_v2_migration_resolver 2>&1 | tee litellm.log`; the Admin UI dev server is `npm run dev` in `ui/litellm-dashboard`, served on port 3000) and showing both the command run and the output. Also, it should hit real LLM provider APIs, not mocks, and cost real $$$ because that is the most realistic test. The proof of fix should be exactly what the end user / customer would see / do. The run logs in PR #27703 is a prime example of how to do it (not a huge fan of using a python test script that future me and the team will have no visibility into; I prefer just curl commands or a short list of bash commands (e.g., using `for`)). If it's a UI thing, just tell me which URLs to go to (e.g., http://localhost:4000/ui/?page=logs), where to click, what fields to fill out, etc. along with the other commands to run in an ordered list, and I'll do it myself and post the screenshots after you make the PR If you ever make public-facing PR descriptions, comments, issues, commit messages, etc., always follow these guidelines to sound less AI-y: - don't use emojis @@ -34,17 +37,21 @@ If you ever make public-facing PR descriptions, comments, issues, commit message Don't hesitate to use values in .env to get needed API keys and other secrets, as long as you never add them to conversation history, commit them, or include them in GitHub issues / PRs -Run tests, format your code, and lint your code before each commit +Python max line length is 120, not 88 -When you fix violations gated by `ruff-strict-budget.json` or `basedpyright-code-budget.json`, run `make lint-budget-update` and commit the lowered baselines so the ceilings ratchet down instead of leaving stale headroom +Run tests before you commit. Also, run `make pre-commit` right before each commit, which generates types (as needed) and formats/lints your code. Any errors found must be fixed. It only runs when there are staged frontend and/or backend changes and calculates violations, generates types, etc. based on the worktree, so stage what you need or stash/delete unwanted files in litellm/ or ui/ (where backend and frontend lint run, respectively) before running it. If it fails because dashboard api types are stale, it already regenerated them for you. You just need to stage the schema.d.ts, re-run `make pre-commit` to confirm it passes, and commit + +When you fix violations gated by `ruff-strict-budget.json`, `type-discipline-budget.json`, or `basedpyright-code-budget.json`, run `make lint-budget-update` and commit the lowered limits so the ceilings ratchet down instead of leaving stale headroom. It measures the working tree, so it must contain exactly the fixes you're committing If you're trying to create a new function that relies on untyped stuff, instead of adding more Any's and pushing `reportAny` / `reportExplicitAny` closer to their basedpyright ceilings, just validate it in the caller with Pydantic (a model or `TypeAdapter` that returns the typed thing or raises will do) and then pass the now typed variable in If you get an LIT001 or LIT002 fail, refactor the code to follow functional programming best practices rather than introducing mutable data structures. For example, build values in one shot with comprehensions or generators wrapped in `tuple()` / `frozenset()` instead of seeding an empty `list`/`dict`/`set` and mutating it over time. Ideally `# mutable-ok` is never used; reach for it only as a genuine last resort when an immutable rewrite is truly impossible, and always pair it with a real reason -Ask to commit and push your work when you're done (or if you're confident that your code is good and works, just do it) +Every lint or type suppression must name the exact rule inside brackets and carry a reason comment, e.g. `# pyright: ignore[reportArgumentType] # stubs lack async overload` or `# noqa: TID251 # `. `# type: ignore` is banned (LIT009): pyrightconfig.json sets `enableTypeIgnoreComments` to false, so it silently does nothing -When you must use real LLM models to, for example, write e2e tests, write a QA runbook, etc., make sure to use the latest models (doesn't have to be smartest, can also be a modern small, fast one. No strong preference for smart vs fast here, just use something modern) as of the year and month of the current date. Do a web search as necessary to figure that out +Commit and push your work when you're done without asking + +When referencing or running models (coding, QA'ing, writing docs, writing tests, etc.), use the latest model in that model family unless otherwise specified; treat your training knowledge, memories, configs, and tests as stale, and determine the family's latest with model_prices_and_context_window.json or the web If you're an internal contributor, when creating a new PR, the typical flow is to branch off litellm_internal_staging and create a branch prefixed with litellm_. Do not create a branch prefixed with claude/ and generally do not have / in your branch names @@ -70,6 +77,7 @@ Follow these coding conventions for new/updated code (a three-line fix in a lega - No monster files or god objects - No file sprawl: deliberate file and folder structure - Standard over hand-rolled: use the official SDK or a library where one exists; where none does, follow industry standards instead of inventing local conventions +- API-fragmentation-aware: when logic must branch on which API surface produced or consumes data (e.g. chat completions vs Anthropic Messages vs Responses API shapes), proactively look for an existing shared helper (e.g. `litellm_core_utils/prompt_templates/factory.py`) before writing per-surface parsing in the new module; if none exists, add one there instead of duplicating the same format-detection logic in every new guardrail/integration Follow conventional commits for commit names and PR titles diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1080579d0fa..0202965ec4b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -322,7 +322,7 @@ npm run build ## Submitting Your PR 1. **Push your branch**: `git push origin your-feature-branch` -2. **Create a PR**: Go to GitHub and create a pull request +2. **Create a PR**: Go to GitHub and open a pull request against the current daily OSS branch, named `litellm_oss_daily_YYYY_MM_DD`. A fresh one is cut each weekday, so pick the most recent from the [branch list](https://github.com/BerriAI/litellm/branches/all?query=litellm_oss_daily). Do not target `main`. 3. **Fill out the PR template**: Provide clear description of changes 4. **Wait for review**: Maintainers will review and provide feedback 5. **Address feedback**: Make requested changes and push updates diff --git a/Dockerfile b/Dockerfile index b6fef1a21fc..bc0e6a5ca6f 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:c61ac6919b811ea53c4782d69f1fe05218ba3c25d53f01b6ab7892e621bd4370 +ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:42df77a9974d6ec8b17a5ee8bc23b532600a44d705acef2409e0933c1251b45f # Runtime image -ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:c61ac6919b811ea53c4782d69f1fe05218ba3c25d53f01b6ab7892e621bd4370 +ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:42df77a9974d6ec8b17a5ee8bc23b532600a44d705acef2409e0933c1251b45f 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:20.18-alpine3.20@sha256:3488b10bf958af7125a176419d2d8a9937d895bf124012aae811651988d2ffe6 diff --git a/Makefile b/Makefile index 7701f54e15c..f2753b09ff5 100644 --- a/Makefile +++ b/Makefile @@ -4,11 +4,12 @@ .PHONY: help test test-unit test-unit-llms test-unit-proxy-guardrails test-unit-proxy-core test-unit-proxy-misc \ test-unit-integrations test-unit-core-utils test-unit-other test-unit-root \ test-proxy-unit-a test-proxy-unit-b test-integration test-unit-helm \ - info lint lint-dev format \ - lint-basedpyright lint-basedpyright-budget-update \ + info lint lint-dev lint-checks format \ + lint-basedpyright lint-basedpyright-budget-update lint-type-discipline lint-type-discipline-budget-update \ lint-ruff-budget lint-ruff-budget-update lint-budget-update lint-gate \ install-dev install-proxy-dev install-test-deps install-hooks \ - install-helm-unittest check-circular-imports check-import-safety + install-helm-unittest check-circular-imports check-import-safety pre-commit \ + lint-install lint-fetch-base # Default target help: @@ -20,17 +21,18 @@ help: @echo " make install-test-deps - Install the full local test environment" @echo " make install-helm-unittest - Install helm unittest plugin" @echo " make install-hooks - Install git hooks (Conventional Commits + Branches)" + @echo " make pre-commit - Run CI-equivalent lint on staged files (run before committing)" @echo " make format - Apply ruff format code formatting" @echo " make format-check - Check ruff format code formatting (matches CI)" @echo " make lint - Run all linting (Ruff, basedpyright, format check, circular imports, import safety)" @echo " make lint-ruff - Run Ruff linting only" @echo " make lint-basedpyright - Run basedpyright strict, gated by per-rule error counts" - @echo " make lint-basedpyright-budget-update - Re-capture the basedpyright per-rule budget (ratchet)" + @echo " make lint-basedpyright-budget-update - Ratchet basedpyright limits down by what this branch fixed" @echo " make lint-format - Check ruff format formatting (matches CI)" - @echo " make lint-ruff-budget - Gate the codebase total of each strict ruff rule against its ceiling" + @echo " make lint-ruff-budget - Gate the codebase total of each strict ruff rule against its limit" @echo " make lint-gate - Strict ruff gate in CI-parity mode (fetches staging, simulates the merge)" - @echo " make lint-ruff-budget-update - Re-capture per-rule baselines in ruff-strict-budget.json (ratchet)" - @echo " make lint-budget-update - Re-capture all ratchet budgets (ruff + basedpyright)" + @echo " make lint-ruff-budget-update - Ratchet ruff-strict-budget.json limits down by what this branch fixed" + @echo " make lint-budget-update - Ratchet all budgets down (ruff + type-discipline + basedpyright)" @echo " make check-circular-imports - Check for circular imports" @echo " make check-import-safety - Check import safety" @echo " make test - Run all tests" @@ -51,13 +53,21 @@ help: UV := uv UV_RUN := $(UV) run --no-sync +LINT_DEP_INSTALL ?= install-dev +LINT_DEP_BASE ?= lint-fetch-base +LINT_JOBS := $(shell sysctl -n hw.ncpu 2>/dev/null || nproc 2>/dev/null || echo 4) +LINT_OUTPUT_SYNC := $(if $(filter output-sync,$(.FEATURES)),--output-sync=target,) + # Show info info: @echo "UV: $(UV)" # Installation targets +# --inexact: sync the locked deps without pruning anything already installed, so running +# a lint/format target doesn't tear the proxy extras (prisma, websockets, ...) out from +# under a dev's venv (CI installs its own env per job, so it is unaffected by this). install-dev: - $(UV) sync --frozen + $(UV) sync --inexact --frozen install-proxy-dev: $(UV) sync --frozen --group proxy-dev --extra proxy @@ -83,15 +93,40 @@ install-hooks: # Formatting # Wrap width is ruff.toml's single source of truth (line-length = 120), shared by the -# formatter, E501, and the import sorter so there's no 88-vs-120 split to reconcile. +# formatter and the import sorter so there's no 88-vs-120 split to reconcile. format: install-dev cd litellm && $(UV_RUN) ruff format --exclude '/enterprise/' . && cd .. format-check: install-dev cd litellm && $(UV_RUN) ruff format --check --exclude '/enterprise/' . && cd .. +# Single fetch of the PR base so the delta-based gates below share one network round +# trip instead of each re-fetching when chained from `lint`. +lint-fetch-base: + git fetch origin litellm_internal_staging + +# Mirror test-linting.yml's lint job environment: the proxy-dev group plus a generated +# Prisma client, so basedpyright resolves the same modules CI does (without the generated +# client the DB wrappers typed against it degrade to Unknown, drifting the budget from +# CI's). --inexact tops up the venv instead of pruning the proxy extras gen:api and the +# running proxy need. +lint-install: + $(UV) sync --inexact --frozen --group proxy-dev + $(UV_RUN) python scripts/prisma_generate_if_needed.py + +# Diff-scoped format check, identical to test-linting.yml's "Check ruff format" step: +# only the litellm Python files changed vs the base are checked, so a pre-existing +# format issue elsewhere doesn't block an unrelated commit. +lint-format-check-changed: $(LINT_DEP_INSTALL) $(LINT_DEP_BASE) + @files=$$(git diff --name-only origin/litellm_internal_staging...HEAD -- 'litellm/**/*.py' | grep -v '^litellm/enterprise/' || true); \ + if [ -z "$$files" ]; then \ + echo "No changed litellm Python files to format-check."; \ + else \ + echo "$$files" | xargs $(UV_RUN) ruff format --check --exclude '/enterprise/'; \ + fi + # Linting targets -lint-ruff: install-dev +lint-ruff: $(LINT_DEP_INSTALL) cd litellm && $(UV_RUN) ruff check . && cd .. # faster linter for developing ... @@ -126,11 +161,17 @@ lint-ruff-FULL-dev: install-dev if [ -n "$$files" ]; then echo "$$files" | xargs $(UV_RUN) ruff check; \ else echo "No changed .py files to check."; fi -lint-basedpyright: install-dev - git fetch origin litellm_internal_staging +lint-basedpyright: $(LINT_DEP_INSTALL) $(LINT_DEP_BASE) ($(UV_RUN) basedpyright --outputjson || true) | $(UV_RUN) python scripts/type_check_gate.py --base origin/litellm_internal_staging -lint-basedpyright-budget-update: install-dev +# Type-discipline budget (mutable collections / casts / type guards / kwargs / +# unexplained suppressions), the test-linting.yml step `make lint` used to omit. +lint-type-discipline: $(LINT_DEP_INSTALL) $(LINT_DEP_BASE) + $(UV_RUN) python scripts/type_discipline_gate.py --base origin/litellm_internal_staging + +# --update lowers each limit by what this branch fixed since its branch point, so +# it needs the base ref fetched to resolve the merge-base. +lint-basedpyright-budget-update: install-dev lint-fetch-base ($(UV_RUN) basedpyright --outputjson || true) | $(UV_RUN) python scripts/type_check_gate.py --update lint-format: format-check @@ -140,28 +181,47 @@ lint-ruff-budget: install-dev # Strict gate, invoked the same way CI does in test-linting.yml so a local pass # means the CI check will pass too. -lint-gate: install-dev - git fetch origin litellm_internal_staging +lint-gate: $(LINT_DEP_INSTALL) $(LINT_DEP_BASE) $(UV_RUN) python scripts/ruff_strict_gate.py --base origin/litellm_internal_staging -lint-ruff-budget-update: install-dev +lint-ruff-budget-update: install-dev lint-fetch-base $(UV_RUN) python scripts/ruff_strict_gate.py --update -# Ratchet all budgets in one shot (ruff strict + basedpyright) -lint-budget-update: lint-ruff-budget-update lint-basedpyright-budget-update +lint-type-discipline-budget-update: install-dev lint-fetch-base + $(UV_RUN) python scripts/type_discipline_gate.py --update -check-circular-imports: install-dev +# Ratchet all budgets in one shot (ruff strict + type-discipline + basedpyright) +lint-budget-update: lint-ruff-budget-update lint-type-discipline-budget-update lint-basedpyright-budget-update + +check-circular-imports: $(LINT_DEP_INSTALL) cd litellm && $(UV_RUN) python ../tests/documentation_tests/test_circular_imports.py && cd .. -check-import-safety: install-dev +check-import-safety: $(LINT_DEP_INSTALL) @$(UV_RUN) python -c "from litellm import *; print('[from litellm import *] OK! no issues!');" || (echo '🚨 import failed, this means you introduced unprotected imports! 🚨'; exit 1) -# Combined linting (matches test-linting.yml workflow) -lint: format-check lint-ruff lint-basedpyright check-circular-imports check-import-safety lint-ruff-budget +# Combined linting, isomorphic to test-linting.yml's lint job so a local pass means a +# green CI lint: it installs the same env (proxy-dev + generated Prisma client) and then +# runs the diff-scoped ruff format check, whole-tree ruff check, the strict-rule / +# type-discipline / basedpyright budgets as a delta vs the base, then the circular-import +# and import-safety checks. Steps that compare against the base resolve it the same way CI +# does (merge-base with origin/litellm_internal_staging). Setup (env sync, Prisma client, +# base fetch) runs once up front; the checks themselves are independent, so a sub-make +# fans them out with -j and the fast ones finish under basedpyright's shadow. +lint: lint-install lint-fetch-base + $(MAKE) -j $(LINT_JOBS) $(LINT_OUTPUT_SYNC) LINT_DEP_INSTALL= LINT_DEP_BASE= lint-checks + +lint-checks: lint-format-check-changed lint-ruff lint-gate lint-type-discipline lint-basedpyright check-circular-imports check-import-safety # Faster linting for local development (only checks changed code) lint-dev: lint-format-changed check-circular-imports check-import-safety +# Run the gating CI checks against your staged files right before committing. Mirrors +# test-linting.yml (Python), test-litellm-ui-build.yml's frontend-lint (dashboard), and +# check-ui-api-types.yml (API-type drift), skipping any whose files you didn't stage. +# Not auto-installed as a git hook so it never slows an unrelated human commit. +pre-commit: + ./scripts/pre_commit_lint.sh + # Testing targets test: install-test-deps $(UV_RUN) pytest tests/ @@ -205,7 +265,7 @@ test-integration: install-test-deps $(UV_RUN) pytest tests/ -k "not test_litellm" test-unit-helm: install-helm-unittest - helm unittest -f 'tests/*.yaml' deploy/charts/litellm-helm + helm unittest -f 'tests/*.yaml' helm/litellm-helm # LLM Translation testing targets test-llm-translation: install-test-deps diff --git a/backend/Dockerfile b/backend/Dockerfile index 667bdb073eb..62bd8b56483 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,5 +1,5 @@ -ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:c61ac6919b811ea53c4782d69f1fe05218ba3c25d53f01b6ab7892e621bd4370 -ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:c61ac6919b811ea53c4782d69f1fe05218ba3c25d53f01b6ab7892e621bd4370 +ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:42df77a9974d6ec8b17a5ee8bc23b532600a44d705acef2409e0933c1251b45f +ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:42df77a9974d6ec8b17a5ee8bc23b532600a44d705acef2409e0933c1251b45f ARG UV_IMAGE=ghcr.io/astral-sh/uv:0.11.7@sha256:240fb85ab0f263ef12f492d8476aa3a2e4e1e333f7d67fbdd923d00a506a516a FROM $UV_IMAGE AS uvbin diff --git a/backend/routes/allowlist.py b/backend/routes/allowlist.py index b67f7d42127..02574ca505d 100644 --- a/backend/routes/allowlist.py +++ b/backend/routes/allowlist.py @@ -46,6 +46,7 @@ BACKEND_PATH_PREFIXES: tuple[str, ...] = ( "/fallback", "/fallbacks", "/cache_settings", + "/coordination_redis/", "/cost_tracking", "/cost/", "/credentials", diff --git a/basedpyright-code-budget.json b/basedpyright-code-budget.json index f2b54e1f889..cb3427bed4d 100644 --- a/basedpyright-code-budget.json +++ b/basedpyright-code-budget.json @@ -1,194 +1,146 @@ { "reportAny": { - "baseline": 24989, - "slack": 2500 + "limit": 37484 }, "reportArgumentType": { - "baseline": 1814, - "slack": 180 + "limit": 2704 }, "reportAssignmentType": { - "baseline": 220, - "slack": 22 + "limit": 330 }, "reportAttributeAccessIssue": { - "baseline": 346, - "slack": 35 + "limit": 516 }, "reportCallIssue": { - "baseline": 87, - "slack": 10 + "limit": 124 }, "reportConstantRedefinition": { - "baseline": 39, - "slack": 4 + "limit": 59 }, "reportDeprecated": { - "baseline": 217, - "slack": 22 + "limit": 326 }, "reportDuplicateImport": { - "baseline": 28, - "slack": 3 + "limit": 42 }, "reportExplicitAny": { - "baseline": 6931, - "slack": 700 + "limit": 10397 }, "reportFunctionMemberAccess": { - "baseline": 7, - "slack": 3 + "limit": 11 }, "reportGeneralTypeIssues": { - "baseline": 151, - "slack": 15 + "limit": 227 }, "reportIncompatibleMethodOverride": { - "baseline": 52, - "slack": 5 + "limit": 78 }, "reportIncompatibleVariableOverride": { - "baseline": 8, - "slack": 3 + "limit": 12 }, "reportInconsistentOverload": { - "baseline": 12, - "slack": 3 + "limit": 18 }, "reportIndexIssue": { - "baseline": 26, - "slack": 3 + "limit": 37 }, "reportInvalidTypeForm": { - "baseline": 23, - "slack": 3 + "limit": 35 }, "reportInvalidTypeVarUse": { - "baseline": 2, - "slack": 3 + "limit": 5 }, "reportMatchNotExhaustive": { - "baseline": 1, - "slack": 0 + "limit": 0 }, "reportMissingParameterType": { - "baseline": 3933, - "slack": 390 + "limit": 5900 }, "reportMissingTypeArgument": { - "baseline": 10612, - "slack": 1000 + "limit": 15918 }, "reportMissingTypeStubs": { - "baseline": 27, - "slack": 10 + "limit": 41 }, "reportOperatorIssue": { - "baseline": 6, - "slack": 3 + "limit": 0 }, "reportOptionalCall": { - "baseline": 4, - "slack": 3 + "limit": 0 }, "reportOptionalIterable": { - "baseline": 3, - "slack": 3 + "limit": 0 }, "reportOptionalMemberAccess": { - "baseline": 724, - "slack": 72 + "limit": 1085 }, "reportOptionalOperand": { - "baseline": 3, - "slack": 3 + "limit": 0 }, "reportOptionalSubscript": { - "baseline": 11, - "slack": 3 + "limit": 0 }, "reportPossiblyUnboundVariable": { - "baseline": 52, - "slack": 10 + "limit": 77 }, "reportPrivateUsage": { - "baseline": 1625, - "slack": 160 + "limit": 2438 }, "reportRedeclaration": { - "baseline": 8, - "slack": 3 + "limit": 12 }, "reportReturnType": { - "baseline": 126, - "slack": 100 + "limit": 225 }, "reportTypedDictNotRequiredAccess": { - "baseline": 20, - "slack": 3 + "limit": 27 }, "reportUndefinedVariable": { - "baseline": 2, - "slack": 3 + "limit": 0 }, "reportUnknownArgumentType": { - "baseline": 30603, - "slack": 3000 + "limit": 45894 }, "reportUnknownLambdaType": { - "baseline": 75, - "slack": 10 + "limit": 113 }, "reportUnknownMemberType": { - "baseline": 27037, - "slack": 2500 + "limit": 40541 }, "reportUnknownParameterType": { - "baseline": 13612, - "slack": 1000 + "limit": 20418 }, "reportUnknownVariableType": { - "baseline": 21445, - "slack": 2000 + "limit": 32151 }, "reportUnnecessaryCast": { - "baseline": 118, - "slack": 10 + "limit": 177 }, "reportUnnecessaryComparison": { - "baseline": 683, - "slack": 100 + "limit": 1025 }, "reportUnnecessaryContains": { - "baseline": 4, - "slack": 3 + "limit": 7 }, "reportUnnecessaryIsInstance": { - "baseline": 808, - "slack": 80 + "limit": 1212 }, "reportUntypedBaseClass": { - "baseline": 110, - "slack": 11 + "limit": 165 }, "reportUntypedFunctionDecorator": { - "baseline": 22, - "slack": 3 + "limit": 33 }, "reportUnusedClass": { - "baseline": 22, - "slack": 3 + "limit": 33 }, "reportUnusedFunction": { - "baseline": 137, - "slack": 10 + "limit": 206 }, "reportUnusedImport": { - "baseline": 670, - "slack": 50 + "limit": 1005 }, "reportUnusedVariable": { - "baseline": 865, - "slack": 50 + "limit": 1297 } } diff --git a/codecov.yaml b/codecov.yaml index f5acdd39136..bc0b3604329 100644 --- a/codecov.yaml +++ b/codecov.yaml @@ -15,6 +15,16 @@ ignore: flag_management: default_rules: carryforward: true + # Dead flags no CI job uploads anymore: their carried-forward sessions were + # measured against old revisions, and the stale line maps mark comment lines + # of since-edited files as missed, sinking patch coverage on unrelated PRs. + individual_flags: + - name: proxy-mgmt-behavior + carryforward: false + - name: security + carryforward: false + - name: proxy-db-schema-migration + carryforward: false component_management: individual_components: diff --git a/deploy/azure_resource_manager/azure_marketplace.zip b/deploy/azure_resource_manager/azure_marketplace.zip deleted file mode 100644 index 34751258637..00000000000 Binary files a/deploy/azure_resource_manager/azure_marketplace.zip and /dev/null differ diff --git a/deploy/azure_resource_manager/azure_marketplace/createUiDefinition.json b/deploy/azure_resource_manager/azure_marketplace/createUiDefinition.json deleted file mode 100644 index 4eba73bdba4..00000000000 --- a/deploy/azure_resource_manager/azure_marketplace/createUiDefinition.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", - "handler": "Microsoft.Azure.CreateUIDef", - "version": "0.1.2-preview", - "parameters": { - "config": { - "isWizard": false, - "basics": { } - }, - "basics": [ ], - "steps": [ ], - "outputs": { }, - "resourceTypes": [ ] - } -} \ No newline at end of file diff --git a/deploy/azure_resource_manager/azure_marketplace/mainTemplate.json b/deploy/azure_resource_manager/azure_marketplace/mainTemplate.json deleted file mode 100644 index 114e855bf54..00000000000 --- a/deploy/azure_resource_manager/azure_marketplace/mainTemplate.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "imageName": { - "type": "string", - "defaultValue": "ghcr.io/berriai/litellm:main-latest" - }, - "containerName": { - "type": "string", - "defaultValue": "litellm-container" - }, - "dnsLabelName": { - "type": "string", - "defaultValue": "litellm" - }, - "portNumber": { - "type": "int", - "defaultValue": 4000 - } - }, - "resources": [ - { - "type": "Microsoft.ContainerInstance/containerGroups", - "apiVersion": "2021-03-01", - "name": "[parameters('containerName')]", - "location": "[resourceGroup().location]", - "properties": { - "containers": [ - { - "name": "[parameters('containerName')]", - "properties": { - "image": "[parameters('imageName')]", - "resources": { - "requests": { - "cpu": 1, - "memoryInGB": 2 - } - }, - "ports": [ - { - "port": "[parameters('portNumber')]" - } - ] - } - } - ], - "osType": "Linux", - "restartPolicy": "Always", - "ipAddress": { - "type": "Public", - "ports": [ - { - "protocol": "tcp", - "port": "[parameters('portNumber')]" - } - ], - "dnsNameLabel": "[parameters('dnsLabelName')]" - } - } - } - ] - } \ No newline at end of file diff --git a/deploy/azure_resource_manager/main.bicep b/deploy/azure_resource_manager/main.bicep deleted file mode 100644 index b104cefe1e1..00000000000 --- a/deploy/azure_resource_manager/main.bicep +++ /dev/null @@ -1,42 +0,0 @@ -param imageName string = 'ghcr.io/berriai/litellm:main-latest' -param containerName string = 'litellm-container' -param dnsLabelName string = 'litellm' -param portNumber int = 4000 - -resource containerGroupName 'Microsoft.ContainerInstance/containerGroups@2021-03-01' = { - name: containerName - location: resourceGroup().location - properties: { - containers: [ - { - name: containerName - properties: { - image: imageName - resources: { - requests: { - cpu: 1 - memoryInGB: 2 - } - } - ports: [ - { - port: portNumber - } - ] - } - } - ] - osType: 'Linux' - restartPolicy: 'Always' - ipAddress: { - type: 'Public' - ports: [ - { - protocol: 'tcp' - port: portNumber - } - ] - dnsNameLabel: dnsLabelName - } - } -} diff --git a/deploy/charts/litellm-helm/templates/configmap-litellm.yaml b/deploy/charts/litellm-helm/templates/configmap-litellm.yaml deleted file mode 100644 index acbe4e3a4b5..00000000000 --- a/deploy/charts/litellm-helm/templates/configmap-litellm.yaml +++ /dev/null @@ -1,9 +0,0 @@ -{{- if .Values.proxyConfigMap.create }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "litellm.fullname" . }}-config -data: - config.yaml: | -{{ .Values.proxy_config | toYaml | indent 6 }} -{{- end }} diff --git a/docker/Dockerfile.database b/docker/Dockerfile.database index b3af953511d..4564ee403fe 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:c61ac6919b811ea53c4782d69f1fe05218ba3c25d53f01b6ab7892e621bd4370 +ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:42df77a9974d6ec8b17a5ee8bc23b532600a44d705acef2409e0933c1251b45f # Runtime image -ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:c61ac6919b811ea53c4782d69f1fe05218ba3c25d53f01b6ab7892e621bd4370 +ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:42df77a9974d6ec8b17a5ee8bc23b532600a44d705acef2409e0933c1251b45f 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:20.18-alpine3.20@sha256:3488b10bf958af7125a176419d2d8a9937d895bf124012aae811651988d2ffe6 diff --git a/docker/Dockerfile.non_root b/docker/Dockerfile.non_root index c24cb9008f0..1883e87be60 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:c61ac6919b811ea53c4782d69f1fe05218ba3c25d53f01b6ab7892e621bd4370 -ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:c61ac6919b811ea53c4782d69f1fe05218ba3c25d53f01b6ab7892e621bd4370 +ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:42df77a9974d6ec8b17a5ee8bc23b532600a44d705acef2409e0933c1251b45f +ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:42df77a9974d6ec8b17a5ee8bc23b532600a44d705acef2409e0933c1251b45f ARG PROXY_EXTRAS_SOURCE=published 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. diff --git a/docker/build_admin_ui.sh b/docker/build_admin_ui.sh index efb2bac3535..68acdd78e3e 100755 --- a/docker/build_admin_ui.sh +++ b/docker/build_admin_ui.sh @@ -57,8 +57,6 @@ source ~/.nvm/nvm.sh nvm install v18.17.0 nvm use v18.17.0 -# copy _enterprise.json from this directory to /ui/litellm-dashboard, and rename it to ui_colors.json -cp enterprise/enterprise_ui/enterprise_colors.json ui/litellm-dashboard/ui_colors.json # cd in to /ui/litellm-dashboard cd ui/litellm-dashboard diff --git a/enterprise/README.md b/enterprise/README.md index f5eb5078e81..c708dad5a06 100644 --- a/enterprise/README.md +++ b/enterprise/README.md @@ -6,4 +6,4 @@ Code in this folder is licensed under a commercial license. Please review the [L 👉 **Using in an Enterprise / Need specific features ?** Meet with us [here](https://enterprise.litellm.ai/demo?month=2024-02) -See all Enterprise Features here 👉 [Docs](https://docs.litellm.ai/docs/proxy/enterprise) +See all Enterprise Features here 👉 [Docs](https://docs.litellm.ai/docs/enterprise) diff --git a/enterprise/litellm_enterprise/enterprise_callbacks/send_emails/base_email.py b/enterprise/litellm_enterprise/enterprise_callbacks/send_emails/base_email.py index 89c3b854686..e7898cac565 100644 --- a/enterprise/litellm_enterprise/enterprise_callbacks/send_emails/base_email.py +++ b/enterprise/litellm_enterprise/enterprise_callbacks/send_emails/base_email.py @@ -239,6 +239,7 @@ class BaseEmailLogger(CustomLogger): max_budget_info=max_budget_info, base_url=email_params.base_url, email_support_contact=email_params.support_contact, + email_footer=email_params.signature, ) await self.send_email( from_email=self.DEFAULT_LITELLM_EMAIL, @@ -311,6 +312,7 @@ class BaseEmailLogger(CustomLogger): max_budget_info=max_budget_info, base_url=email_params.base_url, email_support_contact=email_params.support_contact, + email_footer=email_params.signature, ) # Send email to all recipients @@ -379,6 +381,7 @@ class BaseEmailLogger(CustomLogger): alert_threshold=alert_threshold_str, base_url=email_params.base_url, email_support_contact=email_params.support_contact, + email_footer=email_params.signature, ) await self.send_email( from_email=self.DEFAULT_LITELLM_EMAIL, @@ -403,6 +406,7 @@ class BaseEmailLogger(CustomLogger): alert_threshold=alert_threshold_str, base_url=email_params.base_url, email_support_contact=email_params.support_contact, + email_footer=email_params.signature, ) await self.send_email( from_email=self.DEFAULT_LITELLM_EMAIL, @@ -473,9 +477,12 @@ class BaseEmailLogger(CustomLogger): _id = user_info.token or user_info.user_id or "default_id" _cache_key = f"email_budget_alerts:soft_budget_crossed:{_id}" - # Check if we've already sent this alert - result = await _cache.async_get_cache(key=_cache_key) - if result is None: + send_count = await _cache.async_increment_cache( + key=_cache_key, + value=1, + ttl=EMAIL_BUDGET_ALERT_TTL, + ) + if send_count is None or send_count <= 1: # Create WebhookEvent for soft budget alert event_message = f"Soft Budget Crossed - Total Soft Budget: ${user_info.soft_budget}" webhook_event = WebhookEvent( @@ -504,18 +511,12 @@ class BaseEmailLogger(CustomLogger): await self.send_team_soft_budget_alert_email(webhook_event) else: await self.send_soft_budget_alert_email(webhook_event) - - # Cache the alert to prevent duplicate sends - await _cache.async_set_cache( - key=_cache_key, - value="SENT", - ttl=EMAIL_BUDGET_ALERT_TTL, - ) except Exception as e: verbose_proxy_logger.error( f"Error sending soft budget alert email: {e}", exc_info=True, ) + await self._release_budget_alert_claim(_cache, _cache_key) return # For max_budget_alert, check if we've already sent an alert @@ -541,9 +542,12 @@ class BaseEmailLogger(CustomLogger): _id = user_info.token or user_info.user_id or "default_id" _cache_key = f"email_budget_alerts:max_budget_alert:{_id}" - # Check if we've already sent this alert - result = await _cache.async_get_cache(key=_cache_key) - if result is None: + send_count = await _cache.async_increment_cache( + key=_cache_key, + value=1, + ttl=EMAIL_BUDGET_ALERT_TTL, + ) + if send_count is None or send_count <= 1: # Calculate percentage percentage = int( EMAIL_BUDGET_ALERT_MAX_SPEND_ALERT_PERCENTAGE * 100 @@ -572,18 +576,12 @@ class BaseEmailLogger(CustomLogger): try: await self.send_max_budget_alert_email(webhook_event) - - # Cache the alert to prevent duplicate sends - await _cache.async_set_cache( - key=_cache_key, - value="SENT", - ttl=EMAIL_BUDGET_ALERT_TTL, - ) except Exception as e: verbose_proxy_logger.error( f"Error sending max budget alert email: {e}", exc_info=True, ) + await self._release_budget_alert_claim(_cache, _cache_key) return async def _handle_multi_threshold_max_budget_alert( @@ -613,10 +611,6 @@ class BaseEmailLogger(CustomLogger): f"email_budget_alerts:max_budget_alert:{threshold_pct}:{_id}" ) - result = await _cache.async_get_cache(key=_cache_key) - if result is not None: - continue - # Parse emails + auto-include owner emails = _parse_email_list(raw_emails) if user_info.user_email: @@ -630,6 +624,14 @@ class BaseEmailLogger(CustomLogger): continue recipient_emails = list(set(emails)) + send_count = await _cache.async_increment_cache( + key=_cache_key, + value=1, + ttl=EMAIL_BUDGET_ALERT_TTL, + ) + if send_count is not None and send_count > 1: + continue + event_message = f"Max Budget Alert - {threshold_pct}% of Maximum Budget Reached" webhook_event = WebhookEvent( event="max_budget_alert", @@ -656,16 +658,21 @@ class BaseEmailLogger(CustomLogger): threshold_pct=threshold_pct, recipient_emails=recipient_emails, ) - await _cache.async_set_cache( - key=_cache_key, - value="SENT", - ttl=EMAIL_BUDGET_ALERT_TTL, - ) except Exception as e: verbose_proxy_logger.error( f"Error sending multi-threshold max budget alert email for {threshold_pct}%: {e}", exc_info=True, ) + await self._release_budget_alert_claim(_cache, _cache_key) + + async def _release_budget_alert_claim(self, cache: DualCache, cache_key: str) -> None: + try: + await cache.async_delete_cache(key=cache_key) + except Exception: + verbose_proxy_logger.debug( + "Failed to release budget alert claim for %s; it expires with the TTL", + cache_key, + ) async def _get_email_params( self, @@ -912,9 +919,9 @@ class BaseEmailLogger(CustomLogger): """ Construct invitation link for the user - # http://localhost:4000/ui?invitation_id=7a096b3a-37c6-440f-9dd1-ba22e8043f6b + # http://localhost:4000/ui/onboarding?invitation_id=7a096b3a-37c6-440f-9dd1-ba22e8043f6b """ - return f"{base_url}/ui?invitation_id={invitation_id}" + return f"{base_url}/ui/onboarding?invitation_id={invitation_id}" async def send_email( self, diff --git a/enterprise/litellm_enterprise/proxy/common_utils/check_batch_cost.py b/enterprise/litellm_enterprise/proxy/common_utils/check_batch_cost.py index ee7745d0add..b9ac98f515c 100644 --- a/enterprise/litellm_enterprise/proxy/common_utils/check_batch_cost.py +++ b/enterprise/litellm_enterprise/proxy/common_utils/check_batch_cost.py @@ -13,8 +13,11 @@ from litellm.constants import ( ) if TYPE_CHECKING: + from litellm.integrations.prometheus import PrometheusLogger + from litellm.proxy._types import LiteLLM_ManagedObjectTable from litellm.proxy.utils import PrismaClient, ProxyLogging from litellm.router import Router + from litellm.types.utils import LiteLLMBatch CHECK_BATCH_COST_USER_AGENT = "LiteLLM Proxy/CheckBatchCost" @@ -26,6 +29,7 @@ class CheckBatchCost: proxy_logging_obj: "ProxyLogging", prisma_client: "PrismaClient", llm_router: "Router", + track_unmanaged_vertex_batch_cost: bool = False, ): from litellm.proxy.utils import PrismaClient, ProxyLogging from litellm.router import Router @@ -33,6 +37,7 @@ class CheckBatchCost: self.proxy_logging_obj: ProxyLogging = proxy_logging_obj self.prisma_client: PrismaClient = prisma_client self.llm_router: Router = llm_router + self._track_unmanaged_vertex_batch_cost = track_unmanaged_vertex_batch_cost # Cached after the first poll cycle. Once we know the column is absent we skip # the guaranteed-failing primary query on every subsequent cycle. self._has_batch_processed_column: bool = True @@ -97,13 +102,196 @@ class CheckBatchCost: order={"created_at": "asc"}, ) - async def check_batch_cost(self): + @staticmethod + def _record_error( + prom_logger: Optional["PrometheusLogger"], error_type: str + ) -> None: + if prom_logger is not None: + prom_logger.record_check_batch_cost_error(error_type) + + def _resolve_job_routing( + self, + job: "LiteLLM_ManagedObjectTable", + prom_logger: Optional["PrometheusLogger"], + ) -> Optional[Tuple[str, str]]: """ - Check if the batch JOB has been tracked. - - get all status="validating" and file_purpose="batch" jobs - - check if batch is now complete - - if not, return False - - if so, return True + Resolve (model_id, batch_id) for a managed-object row, where model_id is a router + deployment id and batch_id is the raw provider batch id. + + Managed batches encode both in a base64 unified id. Unmanaged Vertex batches, created with + a raw gs:// input_file_id, store the raw provider job id as unified_object_id; when + track_unmanaged_vertex_batch_cost is enabled the model is derived from the gs:// path and + mapped to a configured vertex_ai deployment. Returns None (recording a metric) when the row + can't be routed. + """ + from litellm.proxy.openai_files_endpoints.common_utils import ( + _is_base64_encoded_unified_file_id, + get_batch_id_from_unified_batch_id, + get_model_id_from_unified_batch_id, + ) + + unified_object_id = job.unified_object_id + decoded = _is_base64_encoded_unified_file_id(unified_object_id) + if decoded: + model_id = get_model_id_from_unified_batch_id(decoded) + if model_id is None: + verbose_proxy_logger.info( + f"Skipping job {unified_object_id} because it is not a valid model id" + ) + self._record_error(prom_logger, "invalid_model_id") + return None + return model_id, get_batch_id_from_unified_batch_id(decoded) + + if self._track_unmanaged_vertex_batch_cost: + return self._resolve_unmanaged_vertex_routing(job, prom_logger) + + verbose_proxy_logger.info( + f"Skipping job {unified_object_id} because it is not a valid unified object id" + ) + self._record_error(prom_logger, "invalid_unified_id") + return None + + def _resolve_unmanaged_vertex_routing( + self, + job: "LiteLLM_ManagedObjectTable", + prom_logger: Optional["PrometheusLogger"], + ) -> Optional[Tuple[str, str]]: + from litellm.llms.vertex_ai.batches.transformation import ( + VertexAIBatchTransformation, + ) + + input_file_id = self._get_input_file_id(job) + if not VertexAIBatchTransformation.is_unmanaged_gcs_batch_input_file_id( + input_file_id + ): + verbose_proxy_logger.info( + f"Skipping job {job.unified_object_id}: not an unmanaged vertex batch " + "(no gs:// input_file_id with a publishers/ model path)" + ) + self._record_error(prom_logger, "invalid_unified_id") + return None + assert input_file_id is not None # narrowed by is_unmanaged_gcs_batch_input_file_id + + bare_model_name = VertexAIBatchTransformation.get_bare_model_name_from_gcs_file( + input_file_id + ) + deployment_id = self._get_vertex_ai_deployment_id_for_bare_model( + bare_model_name + ) + if deployment_id is None: + verbose_proxy_logger.info( + f"Skipping unmanaged vertex batch {job.unified_object_id}: no vertex_ai " + f"deployment configured for model {bare_model_name}" + ) + self._record_error(prom_logger, "unmanaged_no_matching_deployment") + return None + + return deployment_id, job.unified_object_id + + def _get_vertex_ai_deployment_id_for_bare_model( + self, bare_model_name: str + ) -> Optional[str]: + model_group = self.llm_router.resolve_model_name_from_model_id(bare_model_name) + deployment_id = ( + self._get_vertex_ai_deployment_id(model_group) if model_group else None + ) + if deployment_id is not None: + return deployment_id + + return self._get_vertex_ai_deployment_id_from_matching_deployments( + bare_model_name + ) + + def _get_vertex_ai_deployment_id_from_matching_deployments( + self, bare_model_name: str + ) -> Optional[str]: + from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider + + for deployment in self.llm_router.get_model_list(model_name=None) or []: + litellm_params = deployment.get("litellm_params") or {} + actual_model = litellm_params.get("model") + if not isinstance(actual_model, str): + continue + if not self._is_bare_model_match(actual_model, bare_model_name): + continue + try: + _, llm_provider, _, _ = get_llm_provider( + model=actual_model, + custom_llm_provider=litellm_params.get("custom_llm_provider"), + ) + except Exception: + continue + if llm_provider != "vertex_ai": + continue + model_info = deployment.get("model_info") or {} + deployment_id = model_info.get("id") + if isinstance(deployment_id, str): + return deployment_id + return None + + @staticmethod + def _is_bare_model_match(actual_model: str, bare_model_name: str) -> bool: + return ( + actual_model == bare_model_name + or actual_model.endswith(f"/{bare_model_name}") + or actual_model.endswith(f":{bare_model_name}") + ) + + def _get_vertex_ai_deployment_id(self, model_group: str) -> Optional[str]: + """ + Returns the first deployment id for `model_group` whose provider is vertex_ai, + skipping deployments from other providers that happen to share the model group name. + """ + from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider + + for deployment_id in self.llm_router.get_model_ids(model_name=model_group): + deployment_info = self.llm_router.get_deployment(model_id=deployment_id) + if deployment_info is None: + continue + try: + _, llm_provider, _, _ = get_llm_provider( + model=deployment_info.litellm_params.model, + custom_llm_provider=deployment_info.litellm_params.custom_llm_provider, + ) + except Exception: + continue + if llm_provider == "vertex_ai": + return deployment_id + return None + + @staticmethod + def _get_input_file_id(job: "LiteLLM_ManagedObjectTable") -> Optional[str]: + import json + + from litellm.types.utils import LiteLLMBatch + + file_object = job.file_object + if isinstance(file_object, str): + try: + file_object = json.loads(file_object) + except (json.JSONDecodeError, ValueError): + return None + if not isinstance(file_object, dict): + return None + try: + return LiteLLMBatch.model_validate(file_object).input_file_id + except Exception: + return None + + async def _track_completed_batch_cost( + self, + job: "LiteLLM_ManagedObjectTable", + response: "LiteLLMBatch", + model_id: str, + batch_id: str, + prom_logger: Optional["PrometheusLogger"], + ) -> Optional[Tuple[Optional[str], Optional[str]]]: + """ + Fetch a completed batch's results, compute cost/usage, and emit the + aretrieve_batch spend log. Returns (model_name, llm_provider) on + success, None when the job can't be routed to a deployment. Raises on + results-fetch or cost-computation failures so the caller can leave the + job unprocessed and retry it on a later poll. """ from litellm.batches.batch_utils import ( _get_file_content_as_dictionary, @@ -114,10 +302,186 @@ class CheckBatchCost: from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLogging from litellm.proxy.openai_files_endpoints.common_utils import ( _is_base64_encoded_unified_file_id, - get_batch_id_from_unified_batch_id, - get_model_id_from_unified_batch_id, ) + verbose_proxy_logger.info( + f"Batch ID: {batch_id} is complete, tracking cost and usage" + ) + + # aretrieve_batch is called with the raw provider batch ID, so response.id + # is the raw provider value (e.g. "batch_20260223-0518.234"). We need the + # unified base64 ID in the S3 log so downstream consumers can correlate it + # back to the batch they submitted via the proxy. + # + # CheckBatchCost builds its own LiteLLMLogging object (logging_obj below) and + # calls async_success_handler(result=response) directly. That handler calls + # _build_standard_logging_payload(response, ...) which reads response.id at + # that point — so setting response.id here is sufficient. + # + # The HTTP endpoint does this substitution via the managed files hook + # (async_post_call_success_hook). CheckBatchCost bypasses that hook entirely, + # so we do it explicitly here. + response.id = job.unified_object_id + + # This background job runs as default_user_id, so going through the HTTP endpoint + # would trigger check_managed_file_id_access and get 403. Instead, extract the raw + # provider file ID and call afile_content directly with deployment credentials. + raw_output_file_id = response.output_file_id + decoded = _is_base64_encoded_unified_file_id(raw_output_file_id) + if decoded: + try: + raw_output_file_id = decoded.split("llm_output_file_id,")[1].split(";")[0] + except (IndexError, AttributeError): + pass + + credentials = self.llm_router.get_deployment_credentials_with_provider(model_id) or {} + _file_content = await afile_content( + file_id=raw_output_file_id, + **credentials, + ) + + # Access content - handle both direct attribute and method call + if hasattr(_file_content, 'content'): + content_bytes = _file_content.content # type: ignore[union-attr] + elif hasattr(_file_content, 'read'): + content_bytes = await _file_content.read() # type: ignore[misc] + else: + content_bytes = _file_content # type: ignore[assignment] + + file_content_as_dict = _get_file_content_as_dictionary( + content_bytes # type: ignore[arg-type] + ) + + # Record output file size + if prom_logger and content_bytes: + try: + prom_logger.record_managed_file_size( + size_bytes=len(content_bytes), # type: ignore + purpose="batch", + file_type="output", + model=model_id, + ) + except Exception: + pass + + deployment_info = self.llm_router.get_deployment(model_id=model_id) + if deployment_info is None: + verbose_proxy_logger.info( + f"Skipping job {job.unified_object_id} because it is not a valid deployment info" + ) + self._record_error(prom_logger, "deployment_not_found") + return None + custom_llm_provider = deployment_info.litellm_params.custom_llm_provider + litellm_model_name = deployment_info.litellm_params.model + + model_name, llm_provider, _, _ = get_llm_provider( + model=litellm_model_name, + custom_llm_provider=custom_llm_provider, + ) + + # CheckBatchCost bypasses async_post_call_success_hook, so convert raw + # output/error file IDs to managed base64 IDs before the DB write here. + managed_files_hook = self.proxy_logging_obj.get_proxy_hook("managed_files") + if managed_files_hook is not None: + from litellm.proxy._types import UserAPIKeyAuth + _minimal_auth = UserAPIKeyAuth( + user_id=job.created_by or "default-user-id", + team_id=getattr(job, "team_id", None), + ) + for _file_attr in ["output_file_id", "error_file_id"]: + _raw_file_id = getattr(response, _file_attr, None) + if _raw_file_id and not _is_base64_encoded_unified_file_id(_raw_file_id): + try: + _unified_file_id = managed_files_hook.get_unified_output_file_id( + output_file_id=_raw_file_id, + model_id=model_id, + model_name=str(model_name) if model_name else deployment_info.model_name or None, + ) + await managed_files_hook.store_unified_file_id( + file_id=_unified_file_id, + file_object=None, + litellm_parent_otel_span=None, + model_mappings={model_id: _raw_file_id}, + user_api_key_dict=_minimal_auth, + ) + setattr(response, _file_attr, _unified_file_id) + verbose_proxy_logger.info( + f"CheckBatchCost: converted {_file_attr} " + f"{_raw_file_id!r} -> managed ID for batch {batch_id}" + ) + except Exception as _e: + verbose_proxy_logger.warning( + f"CheckBatchCost: failed to create managed file ID for " + f"{_file_attr}={_raw_file_id!r}: {_e}" + ) + + # Pass deployment model_info so custom batch pricing + # (input_cost_per_token_batches etc.) is used for cost calc + deployment_model_info = deployment_info.model_info.model_dump() if deployment_info.model_info else {} + batch_cost, batch_usage, batch_models = ( + await calculate_batch_cost_and_usage( + file_content_dictionary=file_content_as_dict, + custom_llm_provider=llm_provider, # type: ignore + model_name=model_name, + model_info=deployment_model_info, # type: ignore[arg-type] + ) + ) + logging_obj = LiteLLMLogging( + model=batch_models[0], + messages=[{"role": "user", "content": ""}], + stream=False, + call_type="aretrieve_batch", + start_time=datetime.now(), + litellm_call_id=str(uuid.uuid4()), + function_id=str(uuid.uuid4()), + ) + + creator_user_id = job.created_by + user_info = await self._get_user_info(batch_id, job.created_by) + + logging_obj.update_environment_variables( + litellm_params={ + # set the user-agent header so that S3 callback consumers can easily identify CheckBatchCost callbacks + "proxy_server_request": { + "headers": { + "user-agent": CHECK_BATCH_COST_USER_AGENT, + } + }, + "metadata": { + "user_api_key_user_id": creator_user_id, + **user_info, + }, + }, + optional_params={}, + ) + + await logging_obj.async_success_handler( + result=response, + batch_cost=batch_cost, + batch_usage=batch_usage, + batch_models=batch_models, + ) + + # Record batch duration (completed_at - created_at) + if prom_logger and response.completed_at and response.created_at: + duration_seconds = float(response.completed_at - response.created_at) + if duration_seconds >= 0: + prom_logger.record_managed_batch_duration( + duration_seconds=duration_seconds, + model=model_name, + api_provider=str(llm_provider) if llm_provider else None, + ) + + return model_name, str(llm_provider) if llm_provider else None + + async def check_batch_cost(self): + """ + Check if the batch JOB has been tracked. + - get all status="validating" and file_purpose="batch" jobs + - check if batch is now complete + - if not, return False + - if so, return True + """ try: from litellm.integrations.prometheus import PrometheusLogger prom_logger = PrometheusLogger.get_instance() @@ -172,31 +536,10 @@ class CheckBatchCost: else: jobs = await self._fallback_find_jobs() for job in jobs: - # get the model from the job - unified_object_id = job.unified_object_id - decoded_unified_object_id = _is_base64_encoded_unified_file_id( - unified_object_id - ) - if not decoded_unified_object_id: - verbose_proxy_logger.info( - f"Skipping job {unified_object_id} because it is not a valid unified object id" - ) - if prom_logger: - prom_logger.record_check_batch_cost_error("invalid_unified_id") - continue - else: - unified_object_id = decoded_unified_object_id - - model_id = get_model_id_from_unified_batch_id(unified_object_id) - batch_id = get_batch_id_from_unified_batch_id(unified_object_id) - - if model_id is None: - verbose_proxy_logger.info( - f"Skipping job {unified_object_id} because it is not a valid model id" - ) - if prom_logger: - prom_logger.record_check_batch_cost_error("invalid_model_id") + routing = self._resolve_job_routing(job, prom_logger) + if routing is None: continue + model_id, batch_id = routing verbose_proxy_logger.info( f"Querying model ID: {model_id} for cost and usage of batch ID: {batch_id}" @@ -213,7 +556,7 @@ class CheckBatchCost: ) except Exception as e: verbose_proxy_logger.info( - f"Skipping job {unified_object_id} because of error querying model ID: {model_id} for cost and usage of batch ID: {batch_id}: {e}" + f"Skipping job {job.unified_object_id} because of error querying model ID: {model_id} for cost and usage of batch ID: {batch_id}: {e}" ) if prom_logger: prom_logger.record_check_batch_cost_error("provider_retrieval_error") @@ -224,177 +567,26 @@ class CheckBatchCost: response.status == "completed" and response.output_file_id is not None ): - verbose_proxy_logger.info( - f"Batch ID: {batch_id} is complete, tracking cost and usage" - ) - - # aretrieve_batch is called with the raw provider batch ID, so response.id - # is the raw provider value (e.g. "batch_20260223-0518.234"). We need the - # unified base64 ID in the S3 log so downstream consumers can correlate it - # back to the batch they submitted via the proxy. - # - # CheckBatchCost builds its own LiteLLMLogging object (logging_obj below) and - # calls async_success_handler(result=response) directly. That handler calls - # _build_standard_logging_payload(response, ...) which reads response.id at - # that point — so setting response.id here is sufficient. - # - # The HTTP endpoint does this substitution via the managed files hook - # (async_post_call_success_hook). CheckBatchCost bypasses that hook entirely, - # so we do it explicitly here. - response.id = job.unified_object_id - - # This background job runs as default_user_id, so going through the HTTP endpoint - # would trigger check_managed_file_id_access and get 403. Instead, extract the raw - # provider file ID and call afile_content directly with deployment credentials. - raw_output_file_id = response.output_file_id - decoded = _is_base64_encoded_unified_file_id(raw_output_file_id) - if decoded: - try: - raw_output_file_id = decoded.split("llm_output_file_id,")[1].split(";")[0] - except (IndexError, AttributeError): - pass - - credentials = self.llm_router.get_deployment_credentials_with_provider(model_id) or {} - _file_content = await afile_content( - file_id=raw_output_file_id, - **credentials, - ) - - # Access content - handle both direct attribute and method call - if hasattr(_file_content, 'content'): - content_bytes = _file_content.content # type: ignore[union-attr] - elif hasattr(_file_content, 'read'): - content_bytes = await _file_content.read() # type: ignore[misc] - else: - content_bytes = _file_content # type: ignore[assignment] - - file_content_as_dict = _get_file_content_as_dictionary( - content_bytes # type: ignore[arg-type] - ) - - # Record output file size - if prom_logger and content_bytes: - try: - prom_logger.record_managed_file_size( - size_bytes=len(content_bytes), # type: ignore - purpose="batch", - file_type="output", - model=model_id, - ) - except Exception: - pass - - deployment_info = self.llm_router.get_deployment(model_id=model_id) - if deployment_info is None: - verbose_proxy_logger.info( - f"Skipping job {unified_object_id} because it is not a valid deployment info" + try: + tracked = await self._track_completed_batch_cost( + job=job, + response=response, + model_id=model_id, + batch_id=batch_id, + prom_logger=prom_logger, ) - if prom_logger: - prom_logger.record_check_batch_cost_error("deployment_not_found") + except Exception as tracking_err: + verbose_proxy_logger.error( + f"CheckBatchCost: failed to track cost for batch {batch_id} " + f"(job {job.id}); leaving it unprocessed so the next poll retries: {tracking_err}" + ) + self._record_error(prom_logger, "cost_tracking_error") + continue + if tracked is None: continue - custom_llm_provider = deployment_info.litellm_params.custom_llm_provider - litellm_model_name = deployment_info.litellm_params.model - - model_name, llm_provider, _, _ = get_llm_provider( - model=litellm_model_name, - custom_llm_provider=custom_llm_provider, - ) - - # CheckBatchCost bypasses async_post_call_success_hook, so convert raw - # output/error file IDs to managed base64 IDs before the DB write here. - managed_files_hook = self.proxy_logging_obj.get_proxy_hook("managed_files") - if managed_files_hook is not None: - from litellm.proxy._types import UserAPIKeyAuth - _minimal_auth = UserAPIKeyAuth( - user_id=job.created_by or "default-user-id", - team_id=getattr(job, "team_id", None), - ) - for _file_attr in ["output_file_id", "error_file_id"]: - _raw_file_id = getattr(response, _file_attr, None) - if _raw_file_id and not _is_base64_encoded_unified_file_id(_raw_file_id): - try: - _unified_file_id = managed_files_hook.get_unified_output_file_id( - output_file_id=_raw_file_id, - model_id=model_id, - model_name=str(model_name) if model_name else deployment_info.model_name or None, - ) - await managed_files_hook.store_unified_file_id( - file_id=_unified_file_id, - file_object=None, - litellm_parent_otel_span=None, - model_mappings={model_id: _raw_file_id}, - user_api_key_dict=_minimal_auth, - ) - setattr(response, _file_attr, _unified_file_id) - verbose_proxy_logger.info( - f"CheckBatchCost: converted {_file_attr} " - f"{_raw_file_id!r} -> managed ID for batch {batch_id}" - ) - except Exception as _e: - verbose_proxy_logger.warning( - f"CheckBatchCost: failed to create managed file ID for " - f"{_file_attr}={_raw_file_id!r}: {_e}" - ) - - # Pass deployment model_info so custom batch pricing - # (input_cost_per_token_batches etc.) is used for cost calc - deployment_model_info = deployment_info.model_info.model_dump() if deployment_info.model_info else {} - batch_cost, batch_usage, batch_models = ( - await calculate_batch_cost_and_usage( - file_content_dictionary=file_content_as_dict, - custom_llm_provider=llm_provider, # type: ignore - model_name=model_name, - model_info=deployment_model_info, # type: ignore[arg-type] - ) - ) - logging_obj = LiteLLMLogging( - model=batch_models[0], - messages=[{"role": "user", "content": ""}], - stream=False, - call_type="aretrieve_batch", - start_time=datetime.now(), - litellm_call_id=str(uuid.uuid4()), - function_id=str(uuid.uuid4()), - ) - - creator_user_id = job.created_by - user_info = await self._get_user_info(batch_id, job.created_by) - - logging_obj.update_environment_variables( - litellm_params={ - # set the user-agent header so that S3 callback consumers can easily identify CheckBatchCost callbacks - "proxy_server_request": { - "headers": { - "user-agent": CHECK_BATCH_COST_USER_AGENT, - } - }, - "metadata": { - "user_api_key_user_id": creator_user_id, - **user_info, - }, - }, - optional_params={}, - ) - - await logging_obj.async_success_handler( - result=response, - batch_cost=batch_cost, - batch_usage=batch_usage, - batch_models=batch_models, - ) - - # Record batch duration (completed_at - created_at) - if prom_logger and response.completed_at and response.created_at: - duration_seconds = float(response.completed_at - response.created_at) - if duration_seconds >= 0: - prom_logger.record_managed_batch_duration( - duration_seconds=duration_seconds, - model=model_name, - api_provider=str(llm_provider) if llm_provider else None, - ) # Track this job for the final metrics summary - processed_models.append((model_name, str(llm_provider) if llm_provider else None)) + processed_models.append(tracked) # mark the job as complete try: @@ -413,6 +605,26 @@ class CheckBatchCost: f"CheckBatchCost: failed to mark job {job.id} complete in DB: {db_err}" ) + elif response.status in ("failed", "expired", "cancelled"): + try: + update_data = { + "status": response.status, + "file_object": response.model_dump_json(), + } + if self._has_batch_processed_column: + update_data["batch_processed"] = True + await self.prisma_client.db.litellm_managedobjecttable.update( + where={"id": job.id}, + data=update_data, + ) + verbose_proxy_logger.info( + f"CheckBatchCost: marked job {job.id} as {response.status} in DB" + ) + except Exception as db_err: + verbose_proxy_logger.error( + f"CheckBatchCost: failed to mark job {job.id} as {response.status} in DB: {db_err}" + ) + # Record polling run metrics (always, even if nothing was processed) if prom_logger: prom_logger.record_check_batch_cost_run( diff --git a/enterprise/litellm_enterprise/proxy/hooks/managed_files.py b/enterprise/litellm_enterprise/proxy/hooks/managed_files.py index af4870bb1a5..3f42867d90e 100644 --- a/enterprise/litellm_enterprise/proxy/hooks/managed_files.py +++ b/enterprise/litellm_enterprise/proxy/hooks/managed_files.py @@ -125,23 +125,33 @@ class _PROXY_LiteLLMManagedFiles(CustomLogger, BaseFileEndpoints): "team_id": user_api_key_dict.team_id, "updated_by": user_api_key_dict.user_id, } + update_data = { + "model_mappings": json.dumps(model_mappings), + "flat_model_file_ids": list(model_mappings.values()), + "updated_by": user_api_key_dict.user_id, + } if file_object is not None: - db_data["file_object"] = file_object.model_dump_json() + file_object_json = file_object.model_dump_json() + db_data["file_object"] = file_object_json + update_data["file_object"] = file_object_json # Extract storage metadata from hidden params if present hidden_params = getattr(file_object, "_hidden_params", {}) or {} if "storage_backend" in hidden_params: db_data["storage_backend"] = hidden_params["storage_backend"] + update_data["storage_backend"] = hidden_params["storage_backend"] if "storage_url" in hidden_params: db_data["storage_url"] = hidden_params["storage_url"] + update_data["storage_url"] = hidden_params["storage_url"] verbose_logger.debug( f"Storage metadata: storage_backend={db_data.get('storage_backend')}, " f"storage_url={db_data.get('storage_url')}" ) - result = await self.prisma_client.db.litellm_managedfiletable.create( - data=db_data + result = await self.prisma_client.db.litellm_managedfiletable.upsert( + where={"unified_file_id": file_id}, + data={"create": db_data, "update": update_data}, ) verbose_logger.debug( f"LiteLLM Managed File object with id={file_id} stored in db: {result}" diff --git a/enterprise/pyproject.toml b/enterprise/pyproject.toml index 66f6aeb7abc..85ccbef752f 100644 --- a/enterprise/pyproject.toml +++ b/enterprise/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "litellm-enterprise" -version = "0.1.44" +version = "0.1.49" description = "Package for LiteLLM Enterprise features" readme = "README.md" requires-python = ">=3.9" @@ -26,7 +26,7 @@ required-version = ">=0.10.9" module-root = "" [tool.commitizen] -version = "0.1.44" +version = "0.1.49" version_files = [ "pyproject.toml:^version", "../pyproject.toml:litellm-enterprise==", diff --git a/gateway/Dockerfile b/gateway/Dockerfile index 716b2fa09d1..da2f2c9c1e0 100644 --- a/gateway/Dockerfile +++ b/gateway/Dockerfile @@ -1,5 +1,5 @@ -ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:c61ac6919b811ea53c4782d69f1fe05218ba3c25d53f01b6ab7892e621bd4370 -ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:c61ac6919b811ea53c4782d69f1fe05218ba3c25d53f01b6ab7892e621bd4370 +ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:42df77a9974d6ec8b17a5ee8bc23b532600a44d705acef2409e0933c1251b45f +ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:42df77a9974d6ec8b17a5ee8bc23b532600a44d705acef2409e0933c1251b45f ARG UV_IMAGE=ghcr.io/astral-sh/uv:0.11.7@sha256:240fb85ab0f263ef12f492d8476aa3a2e4e1e333f7d67fbdd923d00a506a516a FROM $UV_IMAGE AS uvbin diff --git a/gateway/main.py b/gateway/main.py index 09d30f5da3f..61b885b27e4 100644 --- a/gateway/main.py +++ b/gateway/main.py @@ -25,17 +25,25 @@ DatabaseURLSettings.from_env().apply_to_env() from litellm.proxy.proxy_server import app -from gateway.routes.allowlist import GATEWAY_EXACT_PATHS, GATEWAY_PATH_PREFIXES +from gateway.routes.allowlist import ( + GATEWAY_EXACT_PATHS, + GATEWAY_MOUNT_PATHS, + GATEWAY_PATH_PREFIXES, +) def _is_gateway_route(route) -> bool: - """Keep the route on the gateway if its path is in the LLM data-plane surface.""" + """Keep the route on the gateway if its path is in the LLM data-plane surface. + + Prometheus registers /metrics as a Mount (``app.mount("/metrics", make_asgi_app())``), + so Mounts are matched against GATEWAY_MOUNT_PATHS instead of being dropped with + the UI static mounts. + """ path = getattr(route, "path", None) if path is None: return False if isinstance(route, Mount): - # Gateway never serves the static UI or its asset bundles. - return False + return path in GATEWAY_MOUNT_PATHS if path in GATEWAY_EXACT_PATHS: return True return any(path.startswith(prefix) for prefix in GATEWAY_PATH_PREFIXES) diff --git a/gateway/routes/allowlist.py b/gateway/routes/allowlist.py index 144bb4c473f..792a56a2cd8 100644 --- a/gateway/routes/allowlist.py +++ b/gateway/routes/allowlist.py @@ -106,7 +106,7 @@ GATEWAY_PATH_PREFIXES: tuple[str, ...] = ( # Health & ops "/health", "/metrics", - "/watsonx" + "/watsonx", ) GATEWAY_EXACT_PATHS: frozenset[str] = frozenset( @@ -120,3 +120,9 @@ GATEWAY_EXACT_PATHS: frozenset[str] = frozenset( "/test", } ) + +GATEWAY_MOUNT_PATHS: frozenset[str] = frozenset( + { + "/metrics", + } +) diff --git a/deploy/charts/litellm-helm/.helmignore b/helm/litellm-helm/.helmignore similarity index 100% rename from deploy/charts/litellm-helm/.helmignore rename to helm/litellm-helm/.helmignore diff --git a/deploy/charts/litellm-helm/Chart.lock b/helm/litellm-helm/Chart.lock similarity index 100% rename from deploy/charts/litellm-helm/Chart.lock rename to helm/litellm-helm/Chart.lock diff --git a/deploy/charts/litellm-helm/Chart.yaml b/helm/litellm-helm/Chart.yaml similarity index 100% rename from deploy/charts/litellm-helm/Chart.yaml rename to helm/litellm-helm/Chart.yaml diff --git a/deploy/charts/litellm-helm/README.md b/helm/litellm-helm/README.md similarity index 100% rename from deploy/charts/litellm-helm/README.md rename to helm/litellm-helm/README.md diff --git a/deploy/charts/litellm-helm/charts/postgresql-14.3.1.tgz b/helm/litellm-helm/charts/postgresql-14.3.1.tgz similarity index 100% rename from deploy/charts/litellm-helm/charts/postgresql-14.3.1.tgz rename to helm/litellm-helm/charts/postgresql-14.3.1.tgz diff --git a/deploy/charts/litellm-helm/charts/redis-18.19.1.tgz b/helm/litellm-helm/charts/redis-18.19.1.tgz similarity index 100% rename from deploy/charts/litellm-helm/charts/redis-18.19.1.tgz rename to helm/litellm-helm/charts/redis-18.19.1.tgz diff --git a/deploy/charts/litellm-helm/ci/test-values.yaml b/helm/litellm-helm/ci/test-values.yaml similarity index 100% rename from deploy/charts/litellm-helm/ci/test-values.yaml rename to helm/litellm-helm/ci/test-values.yaml diff --git a/deploy/charts/litellm-helm/templates/NOTES.txt b/helm/litellm-helm/templates/NOTES.txt similarity index 100% rename from deploy/charts/litellm-helm/templates/NOTES.txt rename to helm/litellm-helm/templates/NOTES.txt diff --git a/deploy/charts/litellm-helm/templates/_helpers.tpl b/helm/litellm-helm/templates/_helpers.tpl similarity index 91% rename from deploy/charts/litellm-helm/templates/_helpers.tpl rename to helm/litellm-helm/templates/_helpers.tpl index 25b02dd5f37..469d52c03a7 100644 --- a/deploy/charts/litellm-helm/templates/_helpers.tpl +++ b/helm/litellm-helm/templates/_helpers.tpl @@ -76,10 +76,13 @@ so fall back to "default" (or an explicit override) to avoid a cyclic dependency {{- end }} {{/* -Get redis service name +Get redis service name. +The bundled Redis subchart only serves sentinel in "replication" architecture +(it rejects standalone + sentinel outright), and in that mode the sentinel +Service is named "-redis", not "-redis-master". */}} {{- define "litellm.redis.serviceName" -}} -{{- if and (eq .Values.redis.architecture "standalone") .Values.redis.sentinel.enabled -}} +{{- if .Values.redis.sentinel.enabled -}} {{- printf "%s-%s" .Release.Name (default "redis" .Values.redis.nameOverride | trunc 63 | trimSuffix "-") -}} {{- else -}} {{- printf "%s-%s-master" .Release.Name (default "redis" .Values.redis.nameOverride | trunc 63 | trimSuffix "-") -}} diff --git a/helm/litellm-helm/templates/configmap-litellm.yaml b/helm/litellm-helm/templates/configmap-litellm.yaml new file mode 100644 index 00000000000..03e4f620206 --- /dev/null +++ b/helm/litellm-helm/templates/configmap-litellm.yaml @@ -0,0 +1,22 @@ +{{- if .Values.proxyConfigMap.create }} +{{- $config := deepCopy .Values.proxy_config }} +{{- if and .Values.redis.enabled (dig "coordination" "enabled" true .Values.redis) }} +{{- $generalSettings := (get $config "general_settings") | default dict }} +{{- if not (hasKey $generalSettings "coordination_redis") }} +{{- $coordinationRedis := dict "host" "os.environ/REDIS_HOST" "port" "os.environ/REDIS_PORT" "password" "os.environ/REDIS_PASSWORD" }} +{{- if .Values.redis.sentinel.enabled }} +{{- $sentinelNode := list (include "litellm.redis.serviceName" .) (include "litellm.redis.port" . | int) }} +{{- $coordinationRedis = dict "sentinel_nodes" (list $sentinelNode) "service_name" (default "mymaster" .Values.redis.sentinel.masterSet) "password" "os.environ/REDIS_PASSWORD" }} +{{- end }} +{{- $_ := set $generalSettings "coordination_redis" $coordinationRedis }} +{{- $_ := set $config "general_settings" $generalSettings }} +{{- end }} +{{- end }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "litellm.fullname" . }}-config +data: + config.yaml: | +{{ $config | toYaml | indent 6 }} +{{- end }} diff --git a/deploy/charts/litellm-helm/templates/deployment.yaml b/helm/litellm-helm/templates/deployment.yaml similarity index 100% rename from deploy/charts/litellm-helm/templates/deployment.yaml rename to helm/litellm-helm/templates/deployment.yaml diff --git a/deploy/charts/litellm-helm/templates/extra-resources.yaml b/helm/litellm-helm/templates/extra-resources.yaml similarity index 100% rename from deploy/charts/litellm-helm/templates/extra-resources.yaml rename to helm/litellm-helm/templates/extra-resources.yaml diff --git a/deploy/charts/litellm-helm/templates/hpa.yaml b/helm/litellm-helm/templates/hpa.yaml similarity index 100% rename from deploy/charts/litellm-helm/templates/hpa.yaml rename to helm/litellm-helm/templates/hpa.yaml diff --git a/deploy/charts/litellm-helm/templates/ingress.yaml b/helm/litellm-helm/templates/ingress.yaml similarity index 100% rename from deploy/charts/litellm-helm/templates/ingress.yaml rename to helm/litellm-helm/templates/ingress.yaml diff --git a/deploy/charts/litellm-helm/templates/keda.yaml b/helm/litellm-helm/templates/keda.yaml similarity index 100% rename from deploy/charts/litellm-helm/templates/keda.yaml rename to helm/litellm-helm/templates/keda.yaml diff --git a/deploy/charts/litellm-helm/templates/migrations-job.yaml b/helm/litellm-helm/templates/migrations-job.yaml similarity index 100% rename from deploy/charts/litellm-helm/templates/migrations-job.yaml rename to helm/litellm-helm/templates/migrations-job.yaml diff --git a/deploy/charts/litellm-helm/templates/poddisruptionbudget.yaml b/helm/litellm-helm/templates/poddisruptionbudget.yaml similarity index 100% rename from deploy/charts/litellm-helm/templates/poddisruptionbudget.yaml rename to helm/litellm-helm/templates/poddisruptionbudget.yaml diff --git a/deploy/charts/litellm-helm/templates/secret-dbcredentials.yaml b/helm/litellm-helm/templates/secret-dbcredentials.yaml similarity index 100% rename from deploy/charts/litellm-helm/templates/secret-dbcredentials.yaml rename to helm/litellm-helm/templates/secret-dbcredentials.yaml diff --git a/deploy/charts/litellm-helm/templates/secret-masterkey.yaml b/helm/litellm-helm/templates/secret-masterkey.yaml similarity index 100% rename from deploy/charts/litellm-helm/templates/secret-masterkey.yaml rename to helm/litellm-helm/templates/secret-masterkey.yaml diff --git a/deploy/charts/litellm-helm/templates/service.yaml b/helm/litellm-helm/templates/service.yaml similarity index 100% rename from deploy/charts/litellm-helm/templates/service.yaml rename to helm/litellm-helm/templates/service.yaml diff --git a/deploy/charts/litellm-helm/templates/serviceaccount.yaml b/helm/litellm-helm/templates/serviceaccount.yaml similarity index 100% rename from deploy/charts/litellm-helm/templates/serviceaccount.yaml rename to helm/litellm-helm/templates/serviceaccount.yaml diff --git a/deploy/charts/litellm-helm/templates/servicemonitor.yaml b/helm/litellm-helm/templates/servicemonitor.yaml similarity index 100% rename from deploy/charts/litellm-helm/templates/servicemonitor.yaml rename to helm/litellm-helm/templates/servicemonitor.yaml diff --git a/deploy/charts/litellm-helm/templates/tests/test-connection.yaml b/helm/litellm-helm/templates/tests/test-connection.yaml similarity index 100% rename from deploy/charts/litellm-helm/templates/tests/test-connection.yaml rename to helm/litellm-helm/templates/tests/test-connection.yaml diff --git a/deploy/charts/litellm-helm/templates/tests/test-env-vars.yaml b/helm/litellm-helm/templates/tests/test-env-vars.yaml similarity index 100% rename from deploy/charts/litellm-helm/templates/tests/test-env-vars.yaml rename to helm/litellm-helm/templates/tests/test-env-vars.yaml diff --git a/deploy/charts/litellm-helm/templates/tests/test-servicemonitor.yaml b/helm/litellm-helm/templates/tests/test-servicemonitor.yaml similarity index 100% rename from deploy/charts/litellm-helm/templates/tests/test-servicemonitor.yaml rename to helm/litellm-helm/templates/tests/test-servicemonitor.yaml diff --git a/helm/litellm-helm/tests/coordination_redis_tests.yaml b/helm/litellm-helm/tests/coordination_redis_tests.yaml new file mode 100644 index 00000000000..0b58b1e6bc8 --- /dev/null +++ b/helm/litellm-helm/tests/coordination_redis_tests.yaml @@ -0,0 +1,143 @@ +suite: test coordination redis +templates: + - configmap-litellm.yaml + - deployment.yaml +tests: + - it: should not render coordination_redis when redis is disabled + template: configmap-litellm.yaml + set: + redis.enabled: false + asserts: + - notMatchRegex: + path: data["config.yaml"] + pattern: coordination_redis + + - it: should not emit redis env vars when redis is disabled + template: deployment.yaml + set: + redis.enabled: false + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_HOST + value: RELEASE-NAME-redis-master + any: true + + - it: should render coordination_redis pointing at the bundled redis when enabled + template: configmap-litellm.yaml + set: + redis.enabled: true + asserts: + - matchRegex: + path: data["config.yaml"] + pattern: "coordination_redis:\n host: os.environ/REDIS_HOST\n password: os.environ/REDIS_PASSWORD\n port: os.environ/REDIS_PORT\n" + - matchRegex: + path: data["config.yaml"] + pattern: "master_key: os.environ/PROXY_MASTER_KEY" + + - it: should emit redis env vars backing the coordination_redis os.environ refs + template: deployment.yaml + set: + redis.enabled: true + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_HOST + value: RELEASE-NAME-redis-master + - contains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_PORT + value: "6379" + - contains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: RELEASE-NAME-redis + key: redis-password + + - it: should not render coordination_redis when coordination is opted out + template: configmap-litellm.yaml + set: + redis.enabled: true + redis.coordination.enabled: false + asserts: + - notMatchRegex: + path: data["config.yaml"] + pattern: coordination_redis + + - it: should keep emitting redis env vars when coordination is opted out + template: deployment.yaml + set: + redis.enabled: true + redis.coordination.enabled: false + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_HOST + value: RELEASE-NAME-redis-master + + - it: should not clobber a user supplied coordination_redis block + template: configmap-litellm.yaml + set: + redis.enabled: true + proxy_config.general_settings.coordination_redis: + url: os.environ/COORDINATION_REDIS_URL + asserts: + - matchRegex: + path: data["config.yaml"] + pattern: "coordination_redis:\n url: os.environ/COORDINATION_REDIS_URL\n" + - notMatchRegex: + path: data["config.yaml"] + pattern: "host: os.environ/REDIS_HOST" + + - it: should render sentinel_nodes and service_name in sentinel mode + template: configmap-litellm.yaml + set: + redis.enabled: true + redis.architecture: replication + redis.sentinel.enabled: true + asserts: + # The sentinel Service the redis subchart renders is "-redis", and a + # plain client cannot speak the sentinel protocol, so host/port must not appear + - matchRegex: + path: data["config.yaml"] + pattern: "coordination_redis:\n password: os.environ/REDIS_PASSWORD\n sentinel_nodes:\n - - RELEASE-NAME-redis\n - 26379\n service_name: mymaster\n" + - notMatchRegex: + path: data["config.yaml"] + pattern: "host: os.environ/REDIS_HOST" + + - it: should carry a custom sentinel masterSet into service_name + template: configmap-litellm.yaml + set: + redis.enabled: true + redis.architecture: replication + redis.sentinel.enabled: true + redis.sentinel.masterSet: litellm-master + asserts: + - matchRegex: + path: data["config.yaml"] + pattern: "service_name: litellm-master" + + - it: should point REDIS_HOST at the sentinel service in sentinel mode + template: deployment.yaml + set: + redis.enabled: true + redis.architecture: replication + redis.sentinel.enabled: true + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_HOST + value: RELEASE-NAME-redis + - contains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_PORT + value: "26379" diff --git a/deploy/charts/litellm-helm/tests/deployment_command_args_labels_tests.yaml b/helm/litellm-helm/tests/deployment_command_args_labels_tests.yaml similarity index 100% rename from deploy/charts/litellm-helm/tests/deployment_command_args_labels_tests.yaml rename to helm/litellm-helm/tests/deployment_command_args_labels_tests.yaml diff --git a/deploy/charts/litellm-helm/tests/deployment_tests.yaml b/helm/litellm-helm/tests/deployment_tests.yaml similarity index 100% rename from deploy/charts/litellm-helm/tests/deployment_tests.yaml rename to helm/litellm-helm/tests/deployment_tests.yaml diff --git a/deploy/charts/litellm-helm/tests/hpa_tests.yaml b/helm/litellm-helm/tests/hpa_tests.yaml similarity index 100% rename from deploy/charts/litellm-helm/tests/hpa_tests.yaml rename to helm/litellm-helm/tests/hpa_tests.yaml diff --git a/deploy/charts/litellm-helm/tests/ingress_tests.yaml b/helm/litellm-helm/tests/ingress_tests.yaml similarity index 100% rename from deploy/charts/litellm-helm/tests/ingress_tests.yaml rename to helm/litellm-helm/tests/ingress_tests.yaml diff --git a/deploy/charts/litellm-helm/tests/masterkey-secret_tests.yaml b/helm/litellm-helm/tests/masterkey-secret_tests.yaml similarity index 100% rename from deploy/charts/litellm-helm/tests/masterkey-secret_tests.yaml rename to helm/litellm-helm/tests/masterkey-secret_tests.yaml diff --git a/deploy/charts/litellm-helm/tests/migrations-job_tests.yaml b/helm/litellm-helm/tests/migrations-job_tests.yaml similarity index 100% rename from deploy/charts/litellm-helm/tests/migrations-job_tests.yaml rename to helm/litellm-helm/tests/migrations-job_tests.yaml diff --git a/deploy/charts/litellm-helm/tests/pdb_tests.yaml b/helm/litellm-helm/tests/pdb_tests.yaml similarity index 100% rename from deploy/charts/litellm-helm/tests/pdb_tests.yaml rename to helm/litellm-helm/tests/pdb_tests.yaml diff --git a/deploy/charts/litellm-helm/tests/service_tests.yaml b/helm/litellm-helm/tests/service_tests.yaml similarity index 100% rename from deploy/charts/litellm-helm/tests/service_tests.yaml rename to helm/litellm-helm/tests/service_tests.yaml diff --git a/deploy/charts/litellm-helm/values.yaml b/helm/litellm-helm/values.yaml similarity index 91% rename from deploy/charts/litellm-helm/values.yaml rename to helm/litellm-helm/values.yaml index 6e30a6af444..d3821a547e5 100644 --- a/deploy/charts/litellm-helm/values.yaml +++ b/helm/litellm-helm/values.yaml @@ -331,12 +331,28 @@ postgresql: # secretKeys: # userPasswordKey: password -# requires cache: true in config file -# either enable this or pass a secret for REDIS_HOST, REDIS_PORT, REDIS_PASSWORD or REDIS_URL -# with cache: true to use existing redis instance +# Redis is the proxy's coordination store: cross-pod tpm/rpm rate limits, spend +# tracking, and the pod lock manager. Enabling this deploys the bundled Redis +# subchart, wires REDIS_HOST / REDIS_PORT / REDIS_PASSWORD into the proxy, and +# renders a `general_settings.coordination_redis` block into the proxy config. +# +# To point at an existing Redis instead, leave `enabled: false` and pass a +# secret for REDIS_HOST, REDIS_PORT, REDIS_PASSWORD or REDIS_URL; the proxy +# falls back to those env vars for coordination. Set `cache: true` in the proxy +# config only if you also want LLM response caching, which is independent of +# coordination +# +# When `redis.sentinel.enabled` is set, the coordination block is rendered with +# `sentinel_nodes` and `service_name` (from `redis.sentinel.masterSet`) instead +# of host/port, because a plain Redis client cannot talk to the sentinel port redis: enabled: false architecture: standalone + coordination: + # Set to false to keep the bundled Redis for response caching only and leave + # `general_settings.coordination_redis` out of the rendered config. A + # `coordination_redis` block you define yourself in `proxy_config` always wins + enabled: true # Prisma migration job settings migrationJob: diff --git a/helm/litellm/templates/_helpers.tpl b/helm/litellm/templates/_helpers.tpl index 4319907883e..7c281aa158b 100644 --- a/helm/litellm/templates/_helpers.tpl +++ b/helm/litellm/templates/_helpers.tpl @@ -213,6 +213,10 @@ harmless no-op for the Job and authoritative for the app pods. */}} - name: DISABLE_SCHEMA_UPDATE value: "true" +{{/* These feed the proxy's coordination Redis (cross-pod rate limits, spend + tracking, pod lock manager) via its REDIS_* env fallback. An explicit + `general_settings.coordination_redis` block in proxy_config takes + precedence over anything emitted here. */}} {{- if $root.Values.redis.host }} - name: REDIS_HOST value: {{ $root.Values.redis.host | quote }} @@ -226,10 +230,11 @@ harmless no-op for the Job and authoritative for the app pods. key: {{ $root.Values.redis.passwordSecret.passwordKey | default "password" }} {{- end }} {{- if $root.Values.redis.cluster }} -{{/* The proxy's Cache() reads REDIS_CLUSTER_NODES as JSON and constructs a - RedisClusterCache when it's set (litellm/caching/caching.py:169-192). - We seed with the single configured endpoint — the cluster client - discovers the remaining nodes from CLUSTER SLOTS at startup. */}} +{{/* The proxy falls back to REDIS_CLUSTER_NODES (JSON) to build a cluster-mode + coordination client when `general_settings.coordination_redis` is absent + and no plain-Redis response cache is configured. We seed with the single + configured endpoint; the cluster client discovers the remaining nodes from + CLUSTER SLOTS at startup. */}} - name: REDIS_CLUSTER_NODES value: {{ printf "[{\"host\":%q,\"port\":%v}]" $root.Values.redis.host (int $root.Values.redis.port) | quote }} {{- end }} diff --git a/helm/litellm/templates/backend/deployment.yaml b/helm/litellm/templates/backend/deployment.yaml index b355db43540..8b4552bf302 100644 --- a/helm/litellm/templates/backend/deployment.yaml +++ b/helm/litellm/templates/backend/deployment.yaml @@ -45,11 +45,16 @@ spec: value: /app/config/config.yaml {{- end }} {{- include "litellm.envFrom" .Values.backend | nindent 10 }} - {{- if .Values.gateway.config.create }} + {{- if or .Values.gateway.config.create .Values.backend.volumeMounts }} volumeMounts: + {{- if .Values.gateway.config.create }} - name: gateway-config mountPath: /app/config/config.yaml subPath: config.yaml + {{- end }} + {{- with .Values.backend.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} {{- end }} {{- with .Values.backend.livenessProbe }} livenessProbe: @@ -61,11 +66,16 @@ spec: {{- end }} resources: {{- toYaml .Values.backend.resources | nindent 12 }} - {{- if .Values.gateway.config.create }} + {{- if or .Values.gateway.config.create .Values.backend.volumes }} volumes: + {{- if .Values.gateway.config.create }} - name: gateway-config configMap: name: {{ include "litellm.gateway.fullname" . }}-config + {{- end }} + {{- with .Values.backend.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} {{- end }} {{- with .Values.backend.nodeSelector }} nodeSelector: diff --git a/helm/litellm/templates/gateway/deployment.yaml b/helm/litellm/templates/gateway/deployment.yaml index 05ea4052159..bd491b69e0f 100644 --- a/helm/litellm/templates/gateway/deployment.yaml +++ b/helm/litellm/templates/gateway/deployment.yaml @@ -47,11 +47,16 @@ spec: value: {{ .Values.gateway.numWorkers | quote }} {{- end }} {{- include "litellm.envFrom" .Values.gateway | nindent 10 }} - {{- if .Values.gateway.config.create }} + {{- if or .Values.gateway.config.create .Values.gateway.volumeMounts }} volumeMounts: + {{- if .Values.gateway.config.create }} - name: gateway-config mountPath: /app/config/config.yaml subPath: config.yaml + {{- end }} + {{- with .Values.gateway.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} {{- end }} {{- with .Values.gateway.livenessProbe }} livenessProbe: @@ -63,11 +68,16 @@ spec: {{- end }} resources: {{- toYaml .Values.gateway.resources | nindent 12 }} - {{- if .Values.gateway.config.create }} + {{- if or .Values.gateway.config.create .Values.gateway.volumes }} volumes: + {{- if .Values.gateway.config.create }} - name: gateway-config configMap: name: {{ include "litellm.gateway.fullname" . }}-config + {{- end }} + {{- with .Values.gateway.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} {{- end }} {{- with .Values.gateway.nodeSelector }} nodeSelector: diff --git a/helm/litellm/templates/ui/deployment.yaml b/helm/litellm/templates/ui/deployment.yaml index b40b44cca53..79e9a3e43bb 100644 --- a/helm/litellm/templates/ui/deployment.yaml +++ b/helm/litellm/templates/ui/deployment.yaml @@ -46,6 +46,10 @@ spec: {{- toYaml . | nindent 12 }} {{- end }} {{- include "litellm.envFrom" .Values.ui | nindent 10 }} + {{- with .Values.ui.volumeMounts }} + volumeMounts: + {{- toYaml . | nindent 12 }} + {{- end }} {{- with .Values.ui.livenessProbe }} livenessProbe: {{- toYaml . | nindent 12 }} @@ -56,6 +60,10 @@ spec: {{- end }} resources: {{- toYaml .Values.ui.resources | nindent 12 }} + {{- with .Values.ui.volumes }} + volumes: + {{- toYaml . | nindent 8 }} + {{- end }} {{- with .Values.ui.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/helm/litellm/tests/deployment_volumes_tests.yaml b/helm/litellm/tests/deployment_volumes_tests.yaml new file mode 100644 index 00000000000..3a64300b86c --- /dev/null +++ b/helm/litellm/tests/deployment_volumes_tests.yaml @@ -0,0 +1,172 @@ +suite: test deployment volumes and volumeMounts +templates: + - gateway/deployment.yaml + - gateway/configmap.yaml + - backend/deployment.yaml + - ui/deployment.yaml +values: + - ./values/required.yaml +tests: + - it: gateway renders only the config volume by default + template: gateway/deployment.yaml + asserts: + - equal: + path: spec.template.spec.volumes + value: + - name: gateway-config + configMap: + name: RELEASE-NAME-litellm-gateway-config + - equal: + path: spec.template.spec.containers[0].volumeMounts + value: + - name: gateway-config + mountPath: /app/config/config.yaml + subPath: config.yaml + + - it: gateway merges user volumes and volumeMounts with the config volume + template: gateway/deployment.yaml + set: + gateway.volumes: + - name: custom-callbacks + configMap: + name: custom-callbacks + gateway.volumeMounts: + - name: custom-callbacks + mountPath: /app/custom_callbacks.py + subPath: custom_callbacks.py + asserts: + - equal: + path: spec.template.spec.volumes[0].name + value: gateway-config + - equal: + path: spec.template.spec.volumes[1] + value: + name: custom-callbacks + configMap: + name: custom-callbacks + - equal: + path: spec.template.spec.containers[0].volumeMounts[0].name + value: gateway-config + - equal: + path: spec.template.spec.containers[0].volumeMounts[1] + value: + name: custom-callbacks + mountPath: /app/custom_callbacks.py + subPath: custom_callbacks.py + + - it: gateway renders user volumes even when config creation is disabled + template: gateway/deployment.yaml + set: + gateway.config.create: false + gateway.volumes: + - name: certs + secret: + secretName: tls-certs + gateway.volumeMounts: + - name: certs + mountPath: /etc/certs + readOnly: true + asserts: + - equal: + path: spec.template.spec.volumes + value: + - name: certs + secret: + secretName: tls-certs + - equal: + path: spec.template.spec.containers[0].volumeMounts + value: + - name: certs + mountPath: /etc/certs + readOnly: true + + - it: gateway omits volumes when config creation is disabled and no user volumes are set + template: gateway/deployment.yaml + set: + gateway.config.create: false + asserts: + - isNull: + path: spec.template.spec.volumes + - isNull: + path: spec.template.spec.containers[0].volumeMounts + + - it: backend merges user volumes and volumeMounts with the shared config volume + template: backend/deployment.yaml + set: + backend.volumes: + - name: sso-handler + configMap: + name: sso-handler + backend.volumeMounts: + - name: sso-handler + mountPath: /app/custom_sso.py + subPath: custom_sso.py + asserts: + - equal: + path: spec.template.spec.volumes[0].name + value: gateway-config + - equal: + path: spec.template.spec.volumes[1] + value: + name: sso-handler + configMap: + name: sso-handler + - equal: + path: spec.template.spec.containers[0].volumeMounts[1] + value: + name: sso-handler + mountPath: /app/custom_sso.py + subPath: custom_sso.py + + - it: backend renders user volumes even when config creation is disabled + template: backend/deployment.yaml + set: + gateway.config.create: false + backend.volumes: + - name: data + emptyDir: {} + backend.volumeMounts: + - name: data + mountPath: /data + asserts: + - equal: + path: spec.template.spec.volumes + value: + - name: data + emptyDir: {} + - equal: + path: spec.template.spec.containers[0].volumeMounts + value: + - name: data + mountPath: /data + + - it: ui renders no volumes by default + template: ui/deployment.yaml + asserts: + - isNull: + path: spec.template.spec.volumes + - isNull: + path: spec.template.spec.containers[0].volumeMounts + + - it: ui renders user volumes and volumeMounts + template: ui/deployment.yaml + set: + ui.volumes: + - name: nginx-config + configMap: + name: custom-nginx + ui.volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/conf.d + asserts: + - equal: + path: spec.template.spec.volumes + value: + - name: nginx-config + configMap: + name: custom-nginx + - equal: + path: spec.template.spec.containers[0].volumeMounts + value: + - name: nginx-config + mountPath: /etc/nginx/conf.d diff --git a/helm/litellm/tests/redis_env_tests.yaml b/helm/litellm/tests/redis_env_tests.yaml new file mode 100644 index 00000000000..684d7071b35 --- /dev/null +++ b/helm/litellm/tests/redis_env_tests.yaml @@ -0,0 +1,109 @@ +suite: test redis coordination env vars +templates: + - gateway/deployment.yaml + - gateway/configmap.yaml + - backend/deployment.yaml +values: + - ./values/required.yaml +tests: + - it: gateway omits redis env vars when no host is configured + template: gateway/deployment.yaml + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_HOST + value: redis.example.com + any: true + - notContains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_CLUSTER_NODES + any: true + + - it: gateway emits host, port and password when redis is configured + template: gateway/deployment.yaml + set: + redis.host: redis.example.com + redis.port: 6380 + redis.passwordSecret.name: redis-secret + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_HOST + value: redis.example.com + - contains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_PORT + value: "6380" + - contains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: redis-secret + key: password + + - it: backend emits the same redis env vars so both pods coordinate on one redis + template: backend/deployment.yaml + set: + redis.host: redis.example.com + redis.passwordSecret.name: redis-secret + redis.passwordSecret.passwordKey: redis-password + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_HOST + value: redis.example.com + - contains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: redis-secret + key: redis-password + + - it: gateway omits REDIS_PASSWORD for an auth-less redis + template: gateway/deployment.yaml + set: + redis.host: redis.example.com + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_PASSWORD + any: true + - contains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_HOST + value: redis.example.com + + - it: gateway seeds REDIS_CLUSTER_NODES from host and port in cluster mode + template: gateway/deployment.yaml + set: + redis.host: redis.example.com + redis.port: 6380 + redis.cluster: true + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_CLUSTER_NODES + value: '[{"host":"redis.example.com","port":6380}]' + + - it: gateway omits REDIS_CLUSTER_NODES when cluster mode is off + template: gateway/deployment.yaml + set: + redis.host: redis.example.com + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: REDIS_CLUSTER_NODES + any: true diff --git a/helm/litellm/tests/values/required.yaml b/helm/litellm/tests/values/required.yaml new file mode 100644 index 00000000000..21d3f7a5a6a --- /dev/null +++ b/helm/litellm/tests/values/required.yaml @@ -0,0 +1,4 @@ +database: + writer: + host: postgres.example.com + dbname: litellm diff --git a/helm/litellm/values.yaml b/helm/litellm/values.yaml index 934661643bd..a8f2d39663e 100644 --- a/helm/litellm/values.yaml +++ b/helm/litellm/values.yaml @@ -100,7 +100,18 @@ database: usernameKey: username passwordKey: password -# Optional Redis (caching, rate limiting). Leave host empty to disable. +# Optional Redis. Leave host empty to disable. +# +# This is the proxy's coordination store: cross-pod tpm/rpm rate limits, spend +# tracking, and the pod lock manager. The chart emits REDIS_HOST / REDIS_PORT / +# REDIS_PASSWORD, which the proxy picks up through its coordination Redis env +# fallback. Response caching is separate and off unless you enable it in +# `proxy_config.litellm_settings.cache`. +# +# For full control, define `general_settings.coordination_redis` in +# `proxy_config` (host/port/password/username/url/ssl/startup_nodes/ +# sentinel_nodes/sentinel_password/service_name, each accepting os.environ/VAR +# refs). An explicit block overrides these env vars. # # Set `cluster: true` for Redis Cluster mode (e.g. AWS ElastiCache Cluster, # self-hosted Redis Cluster). The chart emits REDIS_CLUSTER_NODES from @@ -124,6 +135,11 @@ gateway: extraEnv: [] # Add extra environment variables to the gateway envConfigMaps: [] # Add extra environment variables to the gateway from config maps envSecrets: [] # Add extra environment variables to the gateway from secrets + # Additional volumes on the gateway Deployment (e.g. a ConfigMap holding + # custom callback / SSO handler code, mounted next to the proxy config). + volumes: [] + # Additional volumeMounts on the gateway container. + volumeMounts: [] config: create: true proxy_config: {} @@ -167,6 +183,10 @@ backend: extraEnv: [] envConfigMaps: [] envSecrets: [] + # Additional volumes on the backend Deployment. + volumes: [] + # Additional volumeMounts on the backend container. + volumeMounts: [] image: repository: ghcr.io/berriai/litellm-backend tag: "" @@ -206,6 +226,10 @@ ui: extraEnv: [] envConfigMaps: [] envSecrets: [] + # Additional volumes on the ui Deployment. + volumes: [] + # Additional volumeMounts on the ui container. + volumeMounts: [] image: repository: ghcr.io/berriai/litellm-ui tag: "" diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260626120000_add_mcp_tool_search_enabled/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260626120000_add_mcp_tool_search_enabled/migration.sql new file mode 100644 index 00000000000..542677426ba --- /dev/null +++ b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260626120000_add_mcp_tool_search_enabled/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "LiteLLM_ObjectPermissionTable" ADD COLUMN "mcp_tool_search_enabled" BOOLEAN; diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260629000000_add_max_concurrent_requests_to_mcp_server_table/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260629000000_add_max_concurrent_requests_to_mcp_server_table/migration.sql new file mode 100644 index 00000000000..eeeecce741d --- /dev/null +++ b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260629000000_add_max_concurrent_requests_to_mcp_server_table/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "LiteLLM_MCPServerTable" ADD COLUMN "max_concurrent_requests" INTEGER; diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260630120000_add_token_exchange_to_mcp_servers/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260630120000_add_token_exchange_to_mcp_servers/migration.sql new file mode 100644 index 00000000000..dec5fccc319 --- /dev/null +++ b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260630120000_add_token_exchange_to_mcp_servers/migration.sql @@ -0,0 +1,8 @@ +-- Timestamp sorts before some already-applied migrations; this is safe: the +-- runner is `prisma migrate deploy`, which applies every pending migration +-- regardless of name order (utils.py has an informational check for exactly +-- this), and IF NOT EXISTS keeps a re-apply idempotent. +-- AlterTable +ALTER TABLE "LiteLLM_MCPServerTable" ADD COLUMN IF NOT EXISTS "token_exchange_endpoint" TEXT; +ALTER TABLE "LiteLLM_MCPServerTable" ADD COLUMN IF NOT EXISTS "audience" TEXT; +ALTER TABLE "LiteLLM_MCPServerTable" ADD COLUMN IF NOT EXISTS "subject_token_type" TEXT; diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260630190000_add_budget_fallbacks_to_litellm_verification_token/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260630190000_add_budget_fallbacks_to_litellm_verification_token/migration.sql new file mode 100644 index 00000000000..1a5c16288de --- /dev/null +++ b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260630190000_add_budget_fallbacks_to_litellm_verification_token/migration.sql @@ -0,0 +1,5 @@ +-- AlterTable +ALTER TABLE "LiteLLM_VerificationToken" ADD COLUMN IF NOT EXISTS "budget_fallbacks" JSONB NOT NULL DEFAULT '{}'; + +-- AlterTable +ALTER TABLE "LiteLLM_DeletedVerificationToken" ADD COLUMN IF NOT EXISTS "budget_fallbacks" JSONB NOT NULL DEFAULT '{}'; diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260703120000_add_token_exchange_profile_to_mcp_servers/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260703120000_add_token_exchange_profile_to_mcp_servers/migration.sql new file mode 100644 index 00000000000..6dda56c4fb3 --- /dev/null +++ b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260703120000_add_token_exchange_profile_to_mcp_servers/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "LiteLLM_MCPServerTable" ADD COLUMN IF NOT EXISTS "token_exchange_profile" TEXT; diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260710000000_add_dcr_bridge_to_mcp_server_table/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260710000000_add_dcr_bridge_to_mcp_server_table/migration.sql new file mode 100644 index 00000000000..2cfabb9c02e --- /dev/null +++ b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260710000000_add_dcr_bridge_to_mcp_server_table/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "LiteLLM_MCPServerTable" ADD COLUMN "dcr_bridge" BOOLEAN; diff --git a/litellm-proxy-extras/litellm_proxy_extras/schema.prisma b/litellm-proxy-extras/litellm_proxy_extras/schema.prisma index e21c0016491..fb4d8d0b5a3 100644 --- a/litellm-proxy-extras/litellm_proxy_extras/schema.prisma +++ b/litellm-proxy-extras/litellm_proxy_extras/schema.prisma @@ -279,6 +279,7 @@ model LiteLLM_ObjectPermissionTable { blocked_tools String[] @default([]) // Tool names blocked for any key/team/user with this permission mcp_toolsets String[] @default([]) // Toolset IDs granted to this key/team/user search_tools String[] @default([]) // search_tool_name values this key/team/user may call + mcp_tool_search_enabled Boolean? teams LiteLLM_TeamTable[] projects LiteLLM_ProjectTable[] verification_tokens LiteLLM_VerificationToken[] @@ -328,15 +329,23 @@ model LiteLLM_MCPServerTable { token_url String? registration_url String? oauth2_flow String? + token_exchange_endpoint String? + // Named for the RFC 8693 "audience" token-exchange request parameter (that flow only). + // RFC 8707 resource indicators are a separate concept, named "resource" in the v2 egress types. + audience String? + subject_token_type String? + token_exchange_profile String? allow_all_keys Boolean @default(false) available_on_public_internet Boolean @default(true) delegate_auth_to_upstream Boolean @default(false) oauth_passthrough Boolean @default(false) + dcr_bridge Boolean? is_byok Boolean @default(false) byok_description String[] @default([]) byok_api_key_help_url String? source_url String? timeout Float? + max_concurrent_requests Int? // BYOM submission lifecycle approval_status String? @default("active") submitted_by String? @@ -417,6 +426,7 @@ model LiteLLM_VerificationToken { access_group_ids String[] @default([]) model_spend Json @default("{}") model_max_budget Json @default("{}") + budget_fallbacks Json @default("{}") budget_id String? organization_id String? object_permission_id String? @@ -510,6 +520,7 @@ model LiteLLM_DeletedVerificationToken { access_group_ids String[] @default([]) model_spend Json @default("{}") model_max_budget Json @default("{}") + budget_fallbacks Json @default("{}") router_settings Json? @default("{}") budget_id String? organization_id String? diff --git a/litellm-proxy-extras/pyproject.toml b/litellm-proxy-extras/pyproject.toml index e2a86205fc5..4d237622da2 100644 --- a/litellm-proxy-extras/pyproject.toml +++ b/litellm-proxy-extras/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "litellm-proxy-extras" -version = "0.4.74" +version = "0.4.75" description = "Additional files for the LiteLLM Proxy. Reduces the size of the main litellm package." readme = "README.md" requires-python = ">=3.9" @@ -26,7 +26,7 @@ required-version = ">=0.10.9" module-root = "" [tool.commitizen] -version = "0.4.74" +version = "0.4.75" version_files = [ "pyproject.toml:^version", "../pyproject.toml:litellm-proxy-extras==", diff --git a/litellm/__init__.py b/litellm/__init__.py index 15e95ded906..6e2a03b7c7c 100644 --- a/litellm/__init__.py +++ b/litellm/__init__.py @@ -263,6 +263,8 @@ azure_key: Optional[str] = None anthropic_key: Optional[str] = None replicate_key: Optional[str] = None bytez_key: Optional[str] = None +gdc_key: Optional[str] = None +gdc_api_base: Optional[str] = None cohere_key: Optional[str] = None infinity_key: Optional[str] = None clarifai_key: Optional[str] = None @@ -377,6 +379,7 @@ 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 +budget_exceeded_throttle_percentage: Optional[float] = None forward_traceparent_to_llm_provider: bool = False @@ -586,6 +589,7 @@ gemini_models: Set = set() xai_models: Set = set() zai_models: Set = set() deepseek_models: Set = set() +tencent_models: Set = set() runwayml_models: Set = set() azure_ai_models: Set = set() jina_ai_models: Set = set() @@ -799,6 +803,8 @@ def add_known_models(model_cost_map: Optional[Dict] = None): fal_ai_models.add(key) elif value.get("litellm_provider") == "deepseek": deepseek_models.add(key) + elif value.get("litellm_provider") == "tencent": + tencent_models.add(key) elif value.get("litellm_provider") == "runwayml": runwayml_models.add(key) elif value.get("litellm_provider") == "meta_llama": @@ -1091,6 +1097,7 @@ models_by_provider: dict = { "zai": zai_models, "fal_ai": fal_ai_models, "deepseek": deepseek_models, + "tencent": tencent_models, "runwayml": runwayml_models, "mistral": mistral_chat_models, "azure_ai": azure_ai_models, @@ -1787,6 +1794,7 @@ if TYPE_CHECKING: from .llms.nvidia_nim.embed import ( NvidiaNimEmbeddingConfig as NvidiaNimEmbeddingConfig, ) + from .llms.gdc.chat.transformation import GDCGeminiConfig as GDCGeminiConfig # Type stubs for lazy-loaded config instances openaiOSeriesConfig: OpenAIOSeriesConfig @@ -1801,6 +1809,9 @@ if TYPE_CHECKING: from .llms.deepseek.chat.transformation import ( DeepSeekChatConfig as _DeepSeekChatConfig, ) + from .llms.tencent.chat.transformation import ( + TencentChatConfig as _TencentChatConfig, + ) from .llms.sap.chat.transformation import ( GenAIHubOrchestrationConfig as _GenAIHubOrchestrationConfig, ) @@ -1843,6 +1854,7 @@ if TYPE_CHECKING: # Type stubs for lazy-loaded config classes (to help mypy understand types) VLLMConfig: Type[_VLLMConfig] DeepSeekChatConfig: Type[_DeepSeekChatConfig] + TencentChatConfig: Type[_TencentChatConfig] GenAIHubOrchestrationConfig: Type[_GenAIHubOrchestrationConfig] GenAIHubEmbeddingConfig: Type[_GenAIHubEmbeddingConfig] AzureOpenAIO1Config: Type[_AzureOpenAIO1Config] diff --git a/litellm/_lazy_imports_registry.py b/litellm/_lazy_imports_registry.py index 4f131354d2e..488331e3895 100644 --- a/litellm/_lazy_imports_registry.py +++ b/litellm/_lazy_imports_registry.py @@ -284,6 +284,7 @@ LLM_CONFIG_NAMES = ( "LiteLLMProxyChatConfig", "VLLMConfig", "DeepSeekChatConfig", + "TencentChatConfig", "LMStudioChatConfig", "LmStudioEmbeddingConfig", "NscaleConfig", @@ -323,6 +324,7 @@ LLM_CONFIG_NAMES = ( "SnowflakeEmbeddingConfig", "AmazonNovaChatConfig", "SonioxAudioTranscriptionConfig", + "GDCGeminiConfig", ) # Types that support lazy loading via _lazy_import_types @@ -1095,6 +1097,7 @@ _LLM_CONFIGS_IMPORT_MAP = { ), "VLLMConfig": (".llms.vllm.completion.transformation", "VLLMConfig"), "DeepSeekChatConfig": (".llms.deepseek.chat.transformation", "DeepSeekChatConfig"), + "TencentChatConfig": (".llms.tencent.chat.transformation", "TencentChatConfig"), "LMStudioChatConfig": (".llms.lm_studio.chat.transformation", "LMStudioChatConfig"), "LmStudioEmbeddingConfig": ( ".llms.lm_studio.embed.transformation", @@ -1157,6 +1160,10 @@ _LLM_CONFIGS_IMPORT_MAP = { ".llms.dashscope.chat.transformation", "DashScopeChatConfig", ), + "GDCGeminiConfig": ( + ".llms.gdc.chat.transformation", + "GDCGeminiConfig", + ), "ModelScopeChatConfig": ( ".llms.modelscope.chat.transformation", "ModelScopeChatConfig", diff --git a/litellm/_redis.py b/litellm/_redis.py index 2bcce0e1083..0b91cdabffc 100644 --- a/litellm/_redis.py +++ b/litellm/_redis.py @@ -23,7 +23,11 @@ from litellm._redis_credential_provider import ( GCPIAMCredentialProvider, _generate_gcp_iam_access_token, ) -from litellm.constants import REDIS_CONNECTION_POOL_TIMEOUT, REDIS_SOCKET_TIMEOUT +from litellm.constants import ( + REDIS_CLUSTER_HEALTH_CHECK_INTERVAL, + REDIS_CONNECTION_POOL_TIMEOUT, + REDIS_SOCKET_TIMEOUT, +) from litellm.litellm_core_utils.sensitive_data_masker import SensitiveDataMasker from ._logging import verbose_logger @@ -102,6 +106,8 @@ def _get_redis_cluster_kwargs(client=None): "max_connections", "socket_timeout", "socket_connect_timeout", + "health_check_interval", + "socket_keepalive", } return available_args @@ -319,8 +325,19 @@ def _get_redis_client_logic(**env_overrides): value = get_secret(v) # type: ignore env_overrides[k] = value + environment_kwargs = _redis_kwargs_from_environment() + + # An explicitly configured connection target outranks REDIS_URL from the + # environment. Without this, the url branch below strips the caller's + # host/port/password and silently connects to whatever REDIS_URL names. + caller_named_a_target = any( + env_overrides.get(key) is not None for key in ("host", "startup_nodes", "sentinel_nodes") + ) + if caller_named_a_target and env_overrides.get("url") is None: + environment_kwargs.pop("url", None) + redis_kwargs = { - **_redis_kwargs_from_environment(), + **environment_kwargs, **env_overrides, } @@ -579,6 +596,13 @@ def get_redis_async_client( new_startup_nodes.append(ClusterNode(**item)) cluster_kwargs.pop("startup_nodes", None) + # Default to a periodic health check + TCP keepalive so a connection silently dropped + # by a cluster restart (e.g. ElastiCache Serverless maintenance) is revalidated and + # reconnected before reuse instead of stalling in re-initialization; an explicit value + # from config still wins. + cluster_kwargs.setdefault("health_check_interval", REDIS_CLUSTER_HEALTH_CHECK_INTERVAL) + cluster_kwargs.setdefault("socket_keepalive", True) + # Create async RedisCluster with IAM token as password if available cluster_client = async_redis.RedisCluster( startup_nodes=new_startup_nodes, @@ -665,9 +689,8 @@ def get_redis_connection_pool( redis_kwargs["credential_provider"] = GCPIAMCredentialProvider(redis_connect_func._gcp_service_account) connection_class = async_redis.Connection - if "ssl" in redis_kwargs: + if redis_kwargs.pop("ssl", False): connection_class = async_redis.SSLConnection - redis_kwargs.pop("ssl", None) redis_kwargs["connection_class"] = connection_class return async_redis.BlockingConnectionPool(timeout=REDIS_CONNECTION_POOL_TIMEOUT, **redis_kwargs) diff --git a/litellm/a2a_protocol/main.py b/litellm/a2a_protocol/main.py index 37bf7c34f02..4c23ecfed54 100644 --- a/litellm/a2a_protocol/main.py +++ b/litellm/a2a_protocol/main.py @@ -129,6 +129,33 @@ def _set_agent_id_on_logging_obj( litellm_logging_obj.model_call_details["agent_id"] = agent_id +_A2A_COST_PARAM_KEYS = ("cost_per_query", "input_cost_per_token", "output_cost_per_token") + + +def _set_litellm_params_on_logging_obj( + kwargs: dict[str, Any], + litellm_params: dict[str, Any], +) -> None: + """ + Merge the agent's pricing params into model_call_details["litellm_params"] + so A2ACostCalculator can read them. + + The non-streaming path reuses the proxy-built logging object, whose + litellm_params already carries metadata / proxy_server_request / user-key + context, so merge the pricing keys in rather than replacing the dict. + """ + logging_obj = kwargs.get("litellm_logging_obj") + if logging_obj is None: + return + + cost_params = {key: litellm_params[key] for key in _A2A_COST_PARAM_KEYS if litellm_params.get(key) is not None} + if not cost_params: + return + + existing = logging_obj.model_call_details.get("litellm_params") or {} + logging_obj.model_call_details["litellm_params"] = {**existing, **cost_params} + + def _get_a2a_model_info(a2a_client: Any, kwargs: Dict[str, Any]) -> str: """ Extract agent info and set model/custom_llm_provider for cost tracking. @@ -477,6 +504,9 @@ async def asend_message( completion_tokens=completion_tokens, ) + # Merge agent pricing params into the logging obj so cost is calculated + _set_litellm_params_on_logging_obj(kwargs=kwargs, litellm_params=litellm_params) + # Set agent_id on logging obj for SpendLogs tracking _set_agent_id_on_logging_obj(kwargs=kwargs, agent_id=agent_id) diff --git a/litellm/a2a_protocol/streaming_iterator.py b/litellm/a2a_protocol/streaming_iterator.py index 529154919f3..1ef174a5eee 100644 --- a/litellm/a2a_protocol/streaming_iterator.py +++ b/litellm/a2a_protocol/streaming_iterator.py @@ -11,7 +11,6 @@ from litellm._logging import verbose_logger from litellm.a2a_protocol.cost_calculator import A2ACostCalculator from litellm.a2a_protocol.utils import A2ARequestUtils from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj -from litellm.litellm_core_utils.thread_pool_executor import executor if TYPE_CHECKING: from a2a.types import SendStreamingMessageRequest, SendStreamingMessageResponse @@ -128,22 +127,15 @@ class A2AStreamingIterator: # Call success handlers - they will build standard_logging_object asyncio.create_task( - self.logging_obj.async_success_handler( - result=result, + self.logging_obj.dispatch_success_handlers( + result, start_time=self.start_time, end_time=end_time, cache_hit=None, + prefer_async_handlers=True, ) ) - executor.submit( - self.logging_obj.success_handler, - result=result, - cache_hit=None, - start_time=self.start_time, - end_time=end_time, - ) - verbose_logger.info( f"A2A streaming completed: prompt_tokens={prompt_tokens}, " f"completion_tokens={completion_tokens}, total_tokens={total_tokens}, " diff --git a/litellm/a2a_protocol/utils.py b/litellm/a2a_protocol/utils.py index 0dbd1eefc63..ce5a168c3ac 100644 --- a/litellm/a2a_protocol/utils.py +++ b/litellm/a2a_protocol/utils.py @@ -121,8 +121,13 @@ class A2ARequestUtils: Returns: Tuple of (prompt_tokens, completion_tokens, total_tokens) """ - # Count input tokens + # Count input tokens. Dump the message to a dict first so extraction hits + # the dict branch — request-side parts are a2a-sdk Part RootModels whose + # kind/text live on part.root, which the object branch cannot read. This + # mirrors how the response side already works (it operates on model_dump). input_message = A2ARequestUtils.get_input_message_from_request(request) + if input_message is not None and hasattr(input_message, "model_dump"): + input_message = input_message.model_dump(mode="json") input_text = A2ARequestUtils.extract_text_from_message(input_message) prompt_tokens = A2ARequestUtils.count_tokens(input_text) diff --git a/litellm/anthropic_beta_headers_config.json b/litellm/anthropic_beta_headers_config.json index 11fdb26e42d..3f6817f6e35 100644 --- a/litellm/anthropic_beta_headers_config.json +++ b/litellm/anthropic_beta_headers_config.json @@ -102,7 +102,7 @@ "computer-use-2025-01-24": "computer-use-2025-01-24", "computer-use-2025-11-24": "computer-use-2025-11-24", "context-1m-2025-08-07": "context-1m-2025-08-07", - "context-management-2025-06-27": null, + "context-management-2025-06-27": "context-management-2025-06-27", "effort-2025-11-24": "effort-2025-11-24", "fast-mode-2026-02-01": null, "files-api-2025-04-14": null, diff --git a/litellm/batches/batch_utils.py b/litellm/batches/batch_utils.py index 985198ce7ce..11b07d39981 100644 --- a/litellm/batches/batch_utils.py +++ b/litellm/batches/batch_utils.py @@ -3,6 +3,7 @@ from typing import Any, Iterator, List, Literal, Optional, Tuple import litellm from litellm._logging import verbose_logger +from litellm.litellm_core_utils.llm_cost_calc.utils import _parse_prompt_tokens_details from litellm.types.llms.openai import Batch from litellm.types.utils import CallTypes, ModelInfo, Usage from litellm.utils import token_counter @@ -34,7 +35,7 @@ async def calculate_batch_cost_and_usage( custom_llm_provider=custom_llm_provider, model_name=model_name, ) - batch_models = _get_batch_models_from_file_content(file_content_dictionary, model_name) + batch_models = _get_batch_models_from_file_content(file_content_dictionary, model_name, custom_llm_provider) return batch_cost, batch_usage, batch_models @@ -70,7 +71,7 @@ async def _handle_completed_batch( model_name=model_name, ) - batch_models = _get_batch_models_from_file_content(file_content_dictionary, model_name) + batch_models = _get_batch_models_from_file_content(file_content_dictionary, model_name, custom_llm_provider) return batch_cost, batch_usage, batch_models @@ -78,6 +79,7 @@ async def _handle_completed_batch( def _get_batch_models_from_file_content( file_content_dictionary: List[dict], model_name: Optional[str] = None, + custom_llm_provider: str = "openai", ) -> List[str]: """ Get the models from the file content @@ -86,8 +88,8 @@ def _get_batch_models_from_file_content( return [model_name] batch_models = [] for _item in file_content_dictionary: - if _batch_response_was_successful(_item): - _response_body = _get_response_from_batch_job_output_file(_item) + if _batch_response_was_successful(_item, custom_llm_provider): + _response_body = _get_response_from_batch_job_output_file(_item, custom_llm_provider) _model = _response_body.get("model") if _model: batch_models.append(_model) @@ -373,10 +375,10 @@ def _get_batch_job_cost_from_file_content( # parse the file content as json verbose_logger.debug("file_content_dictionary=%s", json.dumps(file_content_dictionary, indent=4)) for _item in file_content_dictionary: - if _batch_response_was_successful(_item): - _response_body = _get_response_from_batch_job_output_file(_item) - if model_info is not None: - usage = _get_batch_job_usage_from_response_body(_response_body) + if _batch_response_was_successful(_item, custom_llm_provider): + _response_body = _get_response_from_batch_job_output_file(_item, custom_llm_provider) + if model_info is not None or custom_llm_provider == "anthropic": + usage = _get_batch_job_usage_from_response_body(_response_body, custom_llm_provider) model = _response_body.get("model", "") prompt_cost, completion_cost = batch_cost_calculator( usage=usage, @@ -418,17 +420,31 @@ def _get_batch_job_total_usage_from_file_content( total_tokens: int = 0 prompt_tokens: int = 0 completion_tokens: int = 0 + cache_read_tokens: int = 0 + cache_creation_tokens: int = 0 for _item in file_content_dictionary: - if _batch_response_was_successful(_item): - _response_body = _get_response_from_batch_job_output_file(_item) - usage: Usage = _get_batch_job_usage_from_response_body(_response_body) + if _batch_response_was_successful(_item, custom_llm_provider): + _response_body = _get_response_from_batch_job_output_file(_item, custom_llm_provider) + usage: Usage = _get_batch_job_usage_from_response_body(_response_body, custom_llm_provider) total_tokens += usage.total_tokens prompt_tokens += usage.prompt_tokens completion_tokens += usage.completion_tokens + prompt_details = _parse_prompt_tokens_details(usage) + cache_read_tokens += prompt_details["cache_hit_tokens"] + cache_creation_tokens += prompt_details["cache_creation_tokens"] + cache_token_params = { + key: tokens + for key, tokens in ( + ("cache_read_input_tokens", cache_read_tokens), + ("cache_creation_input_tokens", cache_creation_tokens), + ) + if tokens > 0 + } return Usage( total_tokens=total_tokens, prompt_tokens=prompt_tokens, completion_tokens=completion_tokens, + **cache_token_params, ) @@ -465,27 +481,51 @@ def _count_prompt_or_input_tokens(model: str, value: Any) -> int: return 0 -def _get_batch_job_usage_from_response_body(response_body: dict) -> Usage: +def _get_batch_job_usage_from_response_body(response_body: dict, custom_llm_provider: str = "openai") -> Usage: """ Get the tokens of a batch job from the response body """ + if custom_llm_provider == "anthropic": + from litellm.llms.anthropic.chat.transformation import AnthropicConfig + + return AnthropicConfig().calculate_usage( + usage_object=response_body.get("usage", None) or {}, + reasoning_content=None, + ) _usage_dict = response_body.get("usage", None) or {} usage: Usage = Usage(**_usage_dict) return usage -def _get_response_from_batch_job_output_file(batch_job_output_file: dict) -> Any: +def _get_anthropic_result_from_batch_results_line(batch_results_line: dict) -> dict: + """ + Get the ``result`` object from a line of an Anthropic message batch results JSONL file. + + Anthropic batch results lines look like: + ``{"custom_id": ..., "result": {"type": "succeeded", "message": {..., "usage": {...}}}}`` + """ + return batch_results_line.get("result", None) or {} + + +def _get_response_from_batch_job_output_file(batch_job_output_file: dict, custom_llm_provider: str = "openai") -> Any: """ Get the response from the batch job output file """ + if custom_llm_provider == "anthropic": + return _get_anthropic_result_from_batch_results_line(batch_job_output_file).get("message", None) or {} _response: dict = batch_job_output_file.get("response", None) or {} _response_body = _response.get("body", None) or {} return _response_body -def _batch_response_was_successful(batch_job_output_file: dict) -> bool: +def _batch_response_was_successful(batch_job_output_file: dict, custom_llm_provider: str = "openai") -> bool: """ - Check if the batch job response status == 200 + Check if the batch job response was successful + + OpenAI-shaped output rows report ``response.status_code == 200``; Anthropic + message batch results lines report ``result.type == "succeeded"``. """ + if custom_llm_provider == "anthropic": + return _get_anthropic_result_from_batch_results_line(batch_job_output_file).get("type") == "succeeded" _response: dict = batch_job_output_file.get("response", None) or {} return _response.get("status_code", None) == 200 diff --git a/litellm/caching/disk_cache.py b/litellm/caching/disk_cache.py index b51acbe9cfd..d9f65ce949e 100644 --- a/litellm/caching/disk_cache.py +++ b/litellm/caching/disk_cache.py @@ -59,8 +59,9 @@ class DiskCache(BaseCache): def increment_cache(self, key, value: int, **kwargs) -> int: # get the value - init_value = self.get_cache(key=key) or 0 - value = init_value + value # type: ignore + cached_value = self.get_cache(key=key) + init_value = cached_value if isinstance(cached_value, int) else 0 + value = init_value + value self.set_cache(key, value, **kwargs) return value @@ -76,8 +77,9 @@ class DiskCache(BaseCache): async def async_increment(self, key, value: int, **kwargs) -> int: # get the value - init_value = await self.async_get_cache(key=key) or 0 - value = init_value + value # type: ignore + cached_value = await self.async_get_cache(key=key) + init_value = cached_value if isinstance(cached_value, int) else 0 + value = init_value + value await self.async_set_cache(key, value, **kwargs) return value diff --git a/litellm/caching/valkey_semantic_cache.py b/litellm/caching/valkey_semantic_cache.py index 746e91207d8..76b7f7d5b87 100644 --- a/litellm/caching/valkey_semantic_cache.py +++ b/litellm/caching/valkey_semantic_cache.py @@ -279,7 +279,7 @@ class ValkeySemanticCache(RedisSemanticCache): print_verbose("No prompt provided for semantic caching") return - embedding = await self._get_async_embedding(prompt, **kwargs) + embedding = await self._get_async_embedding(prompt, metadata=kwargs.get("metadata")) await self._ensure_index_async(len(embedding)) doc_key = self._doc_key(key) @@ -298,7 +298,7 @@ class ValkeySemanticCache(RedisSemanticCache): kwargs.setdefault("metadata", {})["semantic-similarity"] = 0.0 return None - embedding = await self._get_async_embedding(prompt, **kwargs) + embedding = await self._get_async_embedding(prompt, metadata=kwargs.get("metadata")) await self._ensure_index_async(len(embedding)) search_result = await self.async_client.ft(self.index_name).search( diff --git a/litellm/constants.py b/litellm/constants.py index aeb74a65839..715d57e594d 100644 --- a/litellm/constants.py +++ b/litellm/constants.py @@ -332,6 +332,10 @@ REDIS_CONNECTION_POOL_TIMEOUT = int(os.getenv("REDIS_CONNECTION_POOL_TIMEOUT", 5 REDIS_CIRCUIT_BREAKER_FAILURE_THRESHOLD = int(os.getenv("REDIS_CIRCUIT_BREAKER_FAILURE_THRESHOLD", 5)) REDIS_CIRCUIT_BREAKER_RECOVERY_TIMEOUT = int(os.getenv("REDIS_CIRCUIT_BREAKER_RECOVERY_TIMEOUT", 60)) REDIS_CIRCUIT_BREAKER_ENABLED = os.getenv("REDIS_CIRCUIT_BREAKER_ENABLED", "true").lower() == "true" +# Seconds of idle before a Redis cluster connection is validated with a PING and +# reconnected if dead, so a connection silently dropped by a cluster restart +# (e.g. ElastiCache Serverless maintenance) is not reused while broken +REDIS_CLUSTER_HEALTH_CHECK_INTERVAL = 25 # Default Redis major version to assume when version cannot be determined # Using 7 as it's the modern version that supports LPOP with count parameter DEFAULT_REDIS_MAJOR_VERSION = int(os.getenv("DEFAULT_REDIS_MAJOR_VERSION", 7)) @@ -456,6 +460,7 @@ LITELLM_CHAT_PROVIDERS = [ "openai", "openai_like", "bytez", + "gdc", "xai", "custom_openai", "text-completion-openai", @@ -503,6 +508,7 @@ LITELLM_CHAT_PROVIDERS = [ "text-completion-codestral", "text-completion-inception", "deepseek", + "tencent", "sambanova", "maritalk", "cloudflare", @@ -709,6 +715,7 @@ openai_compatible_endpoints: List = [ "https://api.clarifai.com/v2/ext/openai/v1", "https://api.libertai.io/v1", "https://pinstripes.io/v1", + "https://api.meta.ai/v1", ] @@ -724,6 +731,7 @@ openai_compatible_providers: List = [ "volcengine", "codestral", "deepseek", + "tencent", "deepinfra", "perplexity", "xinference", @@ -774,6 +782,7 @@ openai_compatible_providers: List = [ "ragflow", "pinstripes", # Pinstripes - JSON-configured provider "darkbloom", + "meta", # Meta Model API (Muse Spark) - JSON-configured provider ] openai_text_completion_compatible_providers: List = [ # providers that support `/v1/completions` "together_ai", @@ -1123,6 +1132,7 @@ BEDROCK_CONVERSE_MODELS = [ "anthropic.claude-haiku-4-5-20251001-v1:0", "anthropic.claude-sonnet-4-5-20250929-v1:0", "anthropic.claude-fable-5", + "anthropic.claude-sonnet-5", "anthropic.claude-opus-4-8", "anthropic.claude-opus-4-7", "anthropic.claude-opus-4-6-v1:0", @@ -1496,6 +1506,7 @@ LITELLM_SETTINGS_SAFE_DB_OVERRIDES = [ "public_model_groups_links", "cost_discount_config", "cost_margin_config", + "budget_exceeded_throttle_percentage", ] SPECIAL_LITELLM_AUTH_TOKEN = ["ui-token"] DEFAULT_MANAGEMENT_OBJECT_IN_MEMORY_CACHE_TTL = int(os.getenv("DEFAULT_MANAGEMENT_OBJECT_IN_MEMORY_CACHE_TTL", 60)) diff --git a/litellm/cost_calculator.py b/litellm/cost_calculator.py index e8535a570c8..74dc0e19da3 100644 --- a/litellm/cost_calculator.py +++ b/litellm/cost_calculator.py @@ -52,6 +52,9 @@ from litellm.llms.databricks.cost_calculator import ( from litellm.llms.deepseek.cost_calculator import ( cost_per_token as deepseek_cost_per_token, ) +from litellm.llms.tencent.cost_calculator import ( + cost_per_token as tencent_cost_per_token, +) from litellm.llms.fireworks_ai.cost_calculator import ( cost_per_token as fireworks_ai_cost_per_token, ) @@ -219,7 +222,7 @@ def _cost_per_token_custom_pricing_helper( output_cost = completion_tokens * output_cost_per_token return input_cost, output_cost elif custom_cost_per_second is not None: - output_cost = custom_cost_per_second * response_time_ms / 1000 # type: ignore + output_cost = custom_cost_per_second * (response_time_ms or 0.0) / 1000 return 0, output_cost return None @@ -625,6 +628,8 @@ def cost_per_token( return gemini_cost_per_token(model=model, usage=usage_block, service_tier=service_tier) elif custom_llm_provider == "deepseek": return deepseek_cost_per_token(model=model, usage=usage_block) + elif custom_llm_provider == "tencent": + return tencent_cost_per_token(model=model, usage=usage_block) elif custom_llm_provider == "perplexity": return perplexity_cost_per_token(model=model, usage=usage_block) elif custom_llm_provider == "xai": @@ -657,29 +662,27 @@ def cost_per_token( data_residency=data_residency, ) - if model_info.get("input_cost_per_second", None) is not None and response_time_ms is not None: + input_cost_per_second = model_info.get("input_cost_per_second") + if input_cost_per_second is not None and response_time_ms is not None: verbose_logger.debug( "For model=%s - input_cost_per_second: %s; response time: %s", model, - model_info.get("input_cost_per_second", None), + input_cost_per_second, response_time_ms, ) ## COST PER SECOND ## - prompt_tokens_cost_usd_dollar = ( - model_info["input_cost_per_second"] * response_time_ms / 1000 # type: ignore - ) + prompt_tokens_cost_usd_dollar = input_cost_per_second * response_time_ms / 1000 - if model_info.get("output_cost_per_second", None) is not None and response_time_ms is not None: + output_cost_per_second = model_info.get("output_cost_per_second") + if output_cost_per_second is not None and response_time_ms is not None: verbose_logger.debug( "For model=%s - output_cost_per_second: %s; response time: %s", model, - model_info.get("output_cost_per_second", None), + output_cost_per_second, response_time_ms, ) ## COST PER SECOND ## - completion_tokens_cost_usd_dollar = ( - model_info["output_cost_per_second"] * response_time_ms / 1000 # type: ignore - ) + completion_tokens_cost_usd_dollar = output_cost_per_second * response_time_ms / 1000 verbose_logger.debug( "Returned custom cost for model=%s - prompt_tokens_cost_usd_dollar: %s, completion_tokens_cost_usd_dollar: %s", @@ -1495,6 +1498,7 @@ def completion_cost( custom_llm_provider=custom_llm_provider, litellm_model_name=model, data_residency=data_residency, + litellm_logging_obj=litellm_logging_obj, ) elif call_type == _MCP_CALL_TYPE: from litellm.proxy._experimental.mcp_server.cost_calculator import ( @@ -2151,17 +2155,23 @@ def batch_cost_calculator( if input_cost_per_token_batches: total_prompt_cost = usage.prompt_tokens * input_cost_per_token_batches elif input_cost_per_token: + details = _parse_prompt_tokens_details(usage) + cache_read_tokens = details["cache_hit_tokens"] + cache_creation_tokens = details["cache_creation_tokens"] + # Subtract cached tokens from prompt_tokens before calculating cost # Fixes issue where cached tokens are being charged again + base_input_tokens = get_billable_input_tokens(usage) - cache_creation_tokens total_prompt_cost = ( - get_billable_input_tokens(usage) * (input_cost_per_token) / 2 + base_input_tokens * (input_cost_per_token) / 2 ) # batch cost is usually half of the regular token cost # Add cache read cost if applicable - details = _parse_prompt_tokens_details(usage) - cache_read_tokens = details["cache_hit_tokens"] cache_read_cost_key = _get_service_tier_cost_key("cache_read_input_token_cost", None) total_prompt_cost += calculate_cost_component(model_info, cache_read_cost_key, cache_read_tokens) / 2 + + cache_creation_cost = model_info.get("cache_creation_input_token_cost") or input_cost_per_token + total_prompt_cost += cache_creation_tokens * cache_creation_cost / 2 if output_cost_per_token_batches: total_completion_cost = usage.completion_tokens * output_cost_per_token_batches elif output_cost_per_token: @@ -2297,6 +2307,7 @@ def handle_realtime_stream_cost_calculation( custom_llm_provider: str, litellm_model_name: str, data_residency: Optional[str] = None, + litellm_logging_obj: Optional[LitellmLoggingObject] = None, ) -> float: """ Handles the cost calculation for realtime stream responses. @@ -2332,14 +2343,25 @@ def handle_realtime_stream_cost_calculation( input_cost_per_token += _input_cost_per_token output_cost_per_token += _output_cost_per_token break # exit if we find a valid model - total_cost = input_cost_per_token + output_cost_per_token - - if any(r.get("type") == _TRANSCRIPTION_COMPLETED_EVENT_TYPE for r in results): - total_cost += handle_realtime_transcription_cost_calculation( + transcription_cost = ( + handle_realtime_transcription_cost_calculation( results=results, custom_llm_provider=custom_llm_provider, litellm_model_name=litellm_model_name, ) + if any(r.get("type") == _TRANSCRIPTION_COMPLETED_EVENT_TYPE for r in results) + else 0.0 + ) + total_cost = input_cost_per_token + output_cost_per_token + transcription_cost + + _store_cost_breakdown_in_logging_obj( + litellm_logging_obj=litellm_logging_obj, + prompt_tokens_cost_usd_dollar=input_cost_per_token, + completion_tokens_cost_usd_dollar=output_cost_per_token, + cost_for_built_in_tools_cost_usd_dollar=0.0, + total_cost_usd_dollar=total_cost, + additional_costs={"transcription_cost": transcription_cost} if transcription_cost > 0 else None, + ) return total_cost diff --git a/litellm/exceptions.py b/litellm/exceptions.py index d97ba347b07..aca3fb551cc 100644 --- a/litellm/exceptions.py +++ b/litellm/exceptions.py @@ -1165,29 +1165,21 @@ class ModifyResponseException(Exception): request_data: Dict[str, Any], guardrail_name: Optional[str] = None, detection_info: Optional[Dict[str, Any]] = None, + original_response: Optional[Any] = None, ): self.message = message self.model = model self.request_data = request_data self.guardrail_name = guardrail_name self.detection_info = detection_info or {} + # The LLM response that was blocked (post-call). Carries the real token + # usage the upstream call consumed, so the synthetic block response can + # report it instead of discarding it. None for pre-call blocks (the LLM + # was never invoked). + self.original_response = original_response super().__init__(message) -class GuardrailInterventionNormalStringError( - Exception -): # custom exception to raise when a guardrail intervenes, but we want to return a normal string to the user - def __init__(self, message: str): - self.message = message - super().__init__(self.message) - - def __str__(self): - return self.message - - def __repr__(self): - return self.__str__() - - class SensitiveDataRouteException(Exception): """ Exception raised when a guardrail detects sensitive data and wants to reroute the request. diff --git a/litellm/experimental_mcp_client/client.py b/litellm/experimental_mcp_client/client.py index 831e588e5ba..da711463a44 100644 --- a/litellm/experimental_mcp_client/client.py +++ b/litellm/experimental_mcp_client/client.py @@ -382,15 +382,25 @@ class MCPClient: if root_cause is not None and isinstance(in_flight_error, asyncio.CancelledError): raise root_cause from in_flight_error - async def run_with_session(self, operation: Callable[[ClientSession], Awaitable[TSessionResult]]) -> TSessionResult: - """Open a session, run the provided coroutine, and clean up.""" + async def run_with_session( + self, + operation: Callable[[ClientSession], Awaitable[TSessionResult]], + *, + quiet_on_error: bool = False, + ) -> TSessionResult: + """Open a session, run the provided coroutine, and clean up. + + quiet_on_error demotes the failure line to debug for callers that own the exception + (call_tool / list_tools under raise_on_error), so an expected pass-through re-auth does + not emit a warning per call; every other caller keeps the operator-visible warning.""" http_client: Optional[httpx.AsyncClient] = None try: self._last_initialize_instructions = None transport_ctx, http_client = self._create_transport_context() return await self._execute_session_operation(transport_ctx, operation) except Exception: - verbose_logger.warning("MCP client run_with_session failed for %s", self.server_url or "stdio") + _log = verbose_logger.debug if quiet_on_error else verbose_logger.warning + _log("MCP client run_with_session failed for %s", self.server_url or "stdio") raise finally: if http_client is not None: @@ -491,7 +501,7 @@ class MCPClient: return await session.list_tools() try: - result = await self.run_with_session(_list_tools_operation) + result = await self.run_with_session(_list_tools_operation, quiet_on_error=raise_on_error) tool_count = len(result.tools) tool_names = [tool.name for tool in result.tools] verbose_logger.info(f"MCP client listed {tool_count} tools from {self.server_url or 'stdio'}: {tool_names}") @@ -501,7 +511,13 @@ class MCPClient: raise except Exception as e: error_type = type(e).__name__ - verbose_logger.exception( + # Mirror call_tool: when the caller opted into raise_on_error it owns the exception and + # logs it at the fitting level (an expected pass-through re-auth 401 is info, not an + # error), so log at debug here to avoid an error-level line + traceback that would trip + # error-rate alerts on that expected signal. The swallow path still logs the full + # exception because nothing downstream will surface the failure. + _log = verbose_logger.debug if raise_on_error else verbose_logger.exception + _log( f"MCP client list_tools failed - " f"Error Type: {error_type}, " f"Error: {str(e)}, " @@ -510,7 +526,8 @@ class MCPClient: ) # Check if it's a stream/connection error if "BrokenResourceError" in error_type or "Broken" in error_type: - verbose_logger.error( + _log_broken = verbose_logger.debug if raise_on_error else verbose_logger.error + _log_broken( "MCP client detected broken connection/stream during list_tools - " "the MCP server may have crashed, disconnected, or timed out" ) @@ -520,13 +537,28 @@ class MCPClient: # Return empty list instead of raising to allow graceful degradation return [] + @staticmethod + def error_tool_result(exc: Exception) -> MCPCallToolResult: + """The error result ``call_tool`` returns when it swallows a failure (no re-execution).""" + return MCPCallToolResult( + content=[TextContent(type="text", text=f"{type(exc).__name__}: {str(exc)}")], + isError=True, + ) + async def call_tool( self, call_tool_request_params: MCPCallToolRequestParams, host_progress_callback: Optional[Callable] = None, + raise_on_error: bool = False, ) -> MCPCallToolResult: """ Call an MCP Tool. + + Args: + raise_on_error: When True, re-raise the underlying exception instead of returning an + ``isError=True`` result. The token-exchange (OBO) tool-call path uses this to detect + an upstream 401 so it can re-mint the exchanged token and retry once; every other + caller keeps the default and gets graceful ``isError`` degradation. """ verbose_logger.info(f"MCP client calling tool '{call_tool_request_params.name}'") @@ -552,7 +584,7 @@ class MCPClient: ) try: - tool_result = await self.run_with_session(_call_tool_operation) + tool_result = await self.run_with_session(_call_tool_operation, quiet_on_error=raise_on_error) verbose_logger.info(f"MCP client tool call '{call_tool_request_params.name}' completed successfully") return tool_result except asyncio.CancelledError: @@ -565,7 +597,13 @@ class MCPClient: verbose_logger.debug(f"MCP client tool call traceback:\n{error_trace}") # Log detailed error information error_type = type(e).__name__ - verbose_logger.error( + # When the caller opted into raise_on_error it owns the exception and logs it at the + # level that fits (an expected pass-through re-auth 401 is info, not an operator-actionable + # error), so log at debug here to avoid an error-level line that would trip error-rate + # alerts on that expected signal. The swallow path (raise_on_error=False) still logs at + # error because nothing downstream will surface the failure. + _log = verbose_logger.debug if raise_on_error else verbose_logger.error + _log( f"MCP client call_tool failed - " f"Error Type: {error_type}, " f"Error: {str(e)}, " @@ -575,15 +613,14 @@ class MCPClient: ) # Check if it's a stream/connection error if "BrokenResourceError" in error_type or "Broken" in error_type: - verbose_logger.error( + _log( "MCP client detected broken connection/stream - " "the MCP server may have crashed, disconnected, or timed out." ) + if raise_on_error: + raise # Return a default error result instead of raising - return MCPCallToolResult( - content=[TextContent(type="text", text=f"{error_type}: {str(e)}")], # Empty content for error case - isError=True, - ) + return self.error_tool_result(e) async def list_prompts(self) -> List[Prompt]: """List available prompts from the server.""" diff --git a/litellm/fine_tuning/main.py b/litellm/fine_tuning/main.py index 8a8a916fa9c..ce5074cdaf5 100644 --- a/litellm/fine_tuning/main.py +++ b/litellm/fine_tuning/main.py @@ -256,8 +256,6 @@ def create_fine_tuning_job( extra_body = optional_params.get("extra_body", {}) if extra_body is not None: extra_body.pop("azure_ad_token", None) - else: - get_secret_str("AZURE_AD_TOKEN") # type: ignore # Prepare Azure-specific parameters for extra_body extra_body = _prepare_azure_extra_body(extra_body, kwargs, azure_specific_hyperparams) @@ -442,7 +440,7 @@ def cancel_fine_tuning_job( ) # Azure OpenAI elif custom_llm_provider == "azure": - api_base = optional_params.api_base or litellm.api_base or get_secret("AZURE_API_BASE") # type: ignore + api_base = optional_params.api_base or litellm.api_base or get_secret_str("AZURE_API_BASE") api_version = optional_params.api_version or litellm.api_version or get_secret_str("AZURE_API_VERSION") # type: ignore @@ -457,8 +455,6 @@ def cancel_fine_tuning_job( extra_body = optional_params.get("extra_body", {}) if extra_body is not None: extra_body.pop("azure_ad_token", None) - else: - get_secret_str("AZURE_AD_TOKEN") # type: ignore response = azure_fine_tuning_apis_instance.cancel_fine_tuning_job( api_base=api_base, @@ -616,8 +612,6 @@ def list_fine_tuning_jobs( extra_body = optional_params.get("extra_body", {}) if extra_body is not None: extra_body.pop("azure_ad_token", None) - else: - get_secret("AZURE_AD_TOKEN") # type: ignore response = azure_fine_tuning_apis_instance.list_fine_tuning_jobs( api_base=api_base, @@ -759,8 +753,6 @@ def retrieve_fine_tuning_job( extra_body = optional_params.get("extra_body", {}) if extra_body is not None: extra_body.pop("azure_ad_token", None) - else: - get_secret_str("AZURE_AD_TOKEN") # type: ignore response = azure_fine_tuning_apis_instance.retrieve_fine_tuning_job( api_base=api_base, diff --git a/litellm/integrations/anthropic_cache_control_hook.py b/litellm/integrations/anthropic_cache_control_hook.py index 1314fd82255..608fdebc1d9 100644 --- a/litellm/integrations/anthropic_cache_control_hook.py +++ b/litellm/integrations/anthropic_cache_control_hook.py @@ -1,9 +1,12 @@ """ -This hook is used to inject cache control directives into the messages of a chat completion. +This hook is used to inject cache control directives into messages. Users can define - `cache_control_injection_points` in the completion params and litellm will inject the cache control directives into the messages at the specified injection points. +Supported for both `v1/chat/completions` (via the prompt-management hook) and +`v1/messages` (via `apply_to_anthropic_messages_request`). + """ import copy @@ -225,6 +228,98 @@ class AnthropicCacheControlHook(CustomPromptManagement): message_content[-1]["cache_control"] = control # type: ignore return message + @staticmethod + def apply_to_anthropic_messages_request( + messages: List[Dict], + system: str | list | None, + injection_points: List[CacheControlInjectionPoint], + ) -> Tuple[List[Dict], str | list | None, List[CacheControlInjectionPoint]]: + """Apply cache control injection for the Anthropic-native v1/messages endpoint. + + Returns (messages, system, remaining_non_message_points). + """ + if not injection_points: + return messages, system, [] + + processed_messages: List[Dict] = copy.deepcopy(messages) + processed_system = copy.deepcopy(system) if system is not None else None + + message_points: List[CacheControlMessageInjectionPoint] = [] + system_points: List[CacheControlMessageInjectionPoint] = [] + remaining_points: List[CacheControlInjectionPoint] = [] + + for point in injection_points: + if point.get("location") == "message": + msg_point = cast(CacheControlMessageInjectionPoint, point) + if msg_point.get("role") == "system": + system_points.append(msg_point) + else: + message_points.append(msg_point) + else: + remaining_points.append(point) + + reserved_blocks = 1 if any(p.get("location") == "tool_config" for p in remaining_points) else 0 + max_blocks = MAX_CACHE_CONTROL_BLOCKS - reserved_blocks + + used_blocks = sum( + AnthropicCacheControlHook._count_cache_control_blocks(cast(AllMessageValues, msg)) + for msg in processed_messages + ) + if isinstance(processed_system, list): + used_blocks += sum( + 1 for b in processed_system if isinstance(b, dict) and b.get("cache_control") is not None + ) + + if system_points and processed_system is not None and used_blocks < max_blocks: + system_already_has_cc = isinstance(processed_system, list) and any( + isinstance(b, dict) and b.get("cache_control") is not None for b in processed_system + ) + if not system_already_has_cc: + control = system_points[0].get("control") or ChatCompletionCachedContent(type="ephemeral") + if isinstance(processed_system, str): + processed_system = [{"type": "text", "text": processed_system, "cache_control": control}] + used_blocks += 1 + elif len(processed_system) > 0 and isinstance(processed_system[-1], dict): + processed_system[-1] = {**processed_system[-1], "cache_control": control} + used_blocks += 1 + + for i, msg in enumerate(processed_messages): + content = msg.get("content") + if isinstance(content, str): + processed_messages[i] = {**msg, "content": [{"type": "text", "text": content}]} + + processed_messages = AnthropicCacheControlHook._apply_message_injections( + points=message_points, + messages=cast(List[AllMessageValues], processed_messages), + max_blocks=max_blocks - used_blocks, + ) + + return processed_messages, processed_system, remaining_points + + @staticmethod + def maybe_inject_cache_control( + messages: List[Dict], + system: str | list | None, + kwargs: Dict[str, Any], + ) -> Tuple[List[Dict], str | list | None]: + """Extract cache_control_injection_points from kwargs and apply if present. + + Pops the key from kwargs; if remaining (non-message) points exist they + are written back so downstream transforms can handle them. + """ + injection_points = kwargs.pop("cache_control_injection_points", None) + if not injection_points: + return messages, system + + messages, system, remaining = AnthropicCacheControlHook.apply_to_anthropic_messages_request( + messages=messages, + system=system, + injection_points=injection_points, + ) + if remaining: + kwargs["cache_control_injection_points"] = remaining + return messages, system + @property def integration_name(self) -> str: """Return the integration name for this hook.""" diff --git a/litellm/integrations/azure_sentinel/azure_sentinel.py b/litellm/integrations/azure_sentinel/azure_sentinel.py index 182a2e185ef..5f8afe58cb0 100644 --- a/litellm/integrations/azure_sentinel/azure_sentinel.py +++ b/litellm/integrations/azure_sentinel/azure_sentinel.py @@ -61,13 +61,15 @@ class AzureSentinelLogger(CustomBatchLogger): client_secret (str, optional): Azure Client Secret for OAuth2 authentication. If not provided, will use AZURE_SENTINEL_CLIENT_SECRET or AZURE_CLIENT_SECRET env var. audit_stream_name (str, optional): Stream name from DCR for audit logs. - If not provided, audit logs use the standard stream name. + If not provided, will use AZURE_SENTINEL_AUDIT_STREAM_NAME env var or the standard stream name. """ self.async_httpx_client = get_async_httpx_client(llm_provider=httpxSpecialProvider.LoggingCallback) resolved_dcr_immutable_id = dcr_immutable_id or os.getenv("AZURE_SENTINEL_DCR_IMMUTABLE_ID") resolved_stream_name = stream_name or os.getenv("AZURE_SENTINEL_STREAM_NAME") or "Custom-LiteLLM" - resolved_audit_stream_name = audit_stream_name or resolved_stream_name + resolved_audit_stream_name = ( + audit_stream_name or os.getenv("AZURE_SENTINEL_AUDIT_STREAM_NAME") or resolved_stream_name + ) resolved_endpoint = endpoint or os.getenv("AZURE_SENTINEL_ENDPOINT") resolved_tenant_id = tenant_id or os.getenv("AZURE_SENTINEL_TENANT_ID") or os.getenv("AZURE_TENANT_ID") resolved_client_id = client_id or os.getenv("AZURE_SENTINEL_CLIENT_ID") or os.getenv("AZURE_CLIENT_ID") diff --git a/litellm/integrations/code_interpreter_interception/handler.py b/litellm/integrations/code_interpreter_interception/handler.py index cd7b211f1a5..759b2be3a84 100644 --- a/litellm/integrations/code_interpreter_interception/handler.py +++ b/litellm/integrations/code_interpreter_interception/handler.py @@ -40,9 +40,11 @@ from litellm.types.utils import ( LITELLM_CODE_EXECUTION_TOOL_NAME = "litellm_code_execution" _INTERCEPTION_ACTIVE_KEY = "_code_interpreter_interception_active" _SANDBOX_KEY = "_code_interpreter_interception_sandbox_key" +_SESSION_SCOPED_KEY = "_code_interpreter_interception_session_scoped" _CONVERTED_STREAM_KEY = "_code_interpreter_interception_converted_stream" _LITELLM_METADATA_KEY = "litellm_metadata" _CACHE_TTL_SECONDS = 15 * 60 +_SESSION_SCOPED_PER_IDENTITY_CAP = 10 class CodeExecutionToolCall(TypedDict, total=False): @@ -107,6 +109,20 @@ class ChatCompletionFunctionToolChoice(TypedDict): CodeExecutionFunctionToolChoice = ResponsesFunctionToolChoice | ChatCompletionFunctionToolChoice +def _extract_session_id(kwargs: dict[str, Any]) -> str | None: + for meta_key in ("metadata", "litellm_metadata"): + meta = kwargs.get(meta_key) + if isinstance(meta, dict): + sid = meta.get("session_id") + if sid and isinstance(sid, str): + return sid + return None + + +def _extract_identity(kwargs: dict[str, Any]) -> str: + return kwargs.get("user_api_key_hash") or "" + + def _resolve_sandbox_tool(sandbox_tool_name: str | None) -> dict[str, Any] | None: try: from litellm.sandbox.sandbox_tools import resolve_sandbox_tool @@ -140,7 +156,7 @@ class CodeInterpreterInterceptionLogger(CustomLogger): self.enabled_providers = enabled_providers self.sandbox_tool_name = sandbox_tool_name self.sandbox_config = sandbox_config - self._container_cache: dict[str, tuple[Any, dict[str, Any] | None, float]] = {} + self._container_cache: dict[str, tuple[Any, dict[str, Any] | None, float, str | None]] = {} @classmethod def from_config_yaml(cls, config: CodeInterpreterInterceptionConfig) -> "CodeInterpreterInterceptionLogger": @@ -191,7 +207,13 @@ class CodeInterpreterInterceptionLogger(CustomLogger): return None kwargs[_INTERCEPTION_ACTIVE_KEY] = True - kwargs[_SANDBOX_KEY] = uuid.uuid4().hex + session_id = _extract_session_id(kwargs) + if session_id: + identity = _extract_identity(kwargs) + kwargs[_SANDBOX_KEY] = f"{identity}:{session_id}" if identity else session_id + kwargs[_SESSION_SCOPED_KEY] = True + else: + kwargs[_SANDBOX_KEY] = uuid.uuid4().hex if kwargs.get("stream"): kwargs["stream"] = False kwargs[_CONVERTED_STREAM_KEY] = True @@ -217,6 +239,7 @@ class CodeInterpreterInterceptionLogger(CustomLogger): if not is_interception_internal_key(key) and not key.startswith("_agentic_loop") and key != "max_agentic_loops" + and key != _SESSION_SCOPED_KEY } if filtered_metadata: kwargs[_LITELLM_METADATA_KEY] = filtered_metadata @@ -227,7 +250,7 @@ class CodeInterpreterInterceptionLogger(CustomLogger): def _write_interception_metadata(kwargs: dict[str, Any]) -> None: metadata = kwargs.get(_LITELLM_METADATA_KEY) metadata = dict(metadata) if isinstance(metadata, dict) else {} - for key in (_INTERCEPTION_ACTIVE_KEY, _SANDBOX_KEY, _CONVERTED_STREAM_KEY): + for key in (_INTERCEPTION_ACTIVE_KEY, _SANDBOX_KEY, _SESSION_SCOPED_KEY, _CONVERTED_STREAM_KEY): if key in kwargs: metadata[key] = kwargs[key] kwargs[_LITELLM_METADATA_KEY] = metadata @@ -347,7 +370,9 @@ class CodeInterpreterInterceptionLogger(CustomLogger): await self._prune_expired_cache() tool_calls = cast(list[CodeExecutionToolCall], tools.get("tool_calls", [])) sandbox_key = kwargs.get(_SANDBOX_KEY) - container, params = await self._get_or_create_container(cache_key=sandbox_key) + is_session = bool(kwargs.get(_SESSION_SCOPED_KEY)) + identity = _extract_identity(kwargs) if is_session else None + container, params = await self._get_or_create_container(cache_key=sandbox_key, identity=identity) try: container_id = cast(str | None, getattr(container, "id", None)) @@ -404,6 +429,7 @@ class CodeInterpreterInterceptionLogger(CustomLogger): metadata={ "tool_type": "code_interpreter", "sandbox_key": sandbox_key or "", + "is_session_scoped": bool(kwargs.get(_SESSION_SCOPED_KEY)), "code_interpreter_calls": code_interpreter_calls, }, ) @@ -419,7 +445,9 @@ class CodeInterpreterInterceptionLogger(CustomLogger): await self._prune_expired_cache() tool_calls = cast(list[CodeExecutionToolCall], tools.get("tool_calls", [])) sandbox_key = cast(str | None, kwargs.get(_SANDBOX_KEY)) - container, params = await self._get_or_create_container(cache_key=sandbox_key) + is_session = bool(kwargs.get(_SESSION_SCOPED_KEY)) + identity = _extract_identity(cast(dict[str, Any], kwargs)) if is_session else None + container, params = await self._get_or_create_container(cache_key=sandbox_key, identity=identity) try: container_id = cast(str | None, getattr(container, "id", None)) @@ -455,6 +483,7 @@ class CodeInterpreterInterceptionLogger(CustomLogger): metadata={ "tool_type": "code_interpreter", "sandbox_key": sandbox_key or "", + "is_session_scoped": bool(kwargs.get(_SESSION_SCOPED_KEY)), "code_interpreter_calls": code_interpreter_calls, "response_format": "openai", }, @@ -489,6 +518,8 @@ class CodeInterpreterInterceptionLogger(CustomLogger): async def async_agentic_loop_cleanup_hook(self, plan: AgenticLoopPlan, kwargs: dict) -> None: metadata = plan.metadata or {} if plan else {} + if metadata.get("is_session_scoped"): + return await self._delete_container_for_cache_key(metadata.get("sandbox_key")) @staticmethod @@ -520,7 +551,8 @@ class CodeInterpreterInterceptionLogger(CustomLogger): async def async_post_agentic_loop_response_hook(self, response: Any, plan: AgenticLoopPlan, kwargs: dict) -> Any: metadata = plan.metadata or {} if plan else {} - await self._delete_container_for_cache_key(metadata.get("sandbox_key")) + if not metadata.get("is_session_scoped"): + await self._delete_container_for_cache_key(metadata.get("sandbox_key")) calls = metadata.get("code_interpreter_calls") if not calls: @@ -565,17 +597,32 @@ class CodeInterpreterInterceptionLogger(CustomLogger): return f"[execution error] {message}" return getattr(result, "stdout", "") or "" - async def _get_or_create_container(self, cache_key: str | None) -> tuple[Any, dict[str, Any] | None]: + async def _get_or_create_container( + self, + cache_key: str | None, + identity: str | None = None, + ) -> tuple[Any, dict[str, Any] | None]: if cache_key: cached = self._container_cache.get(cache_key) if cached is not None: + self._container_cache[cache_key] = (cached[0], cached[1], time.time(), cached[3]) return cached[0], cached[1] container, params = await self._create_container() if cache_key: - self._container_cache[cache_key] = (container, params, time.time()) + if identity is not None: + await self._evict_lru_session_if_over_cap(identity) + self._container_cache[cache_key] = (container, params, time.time(), identity) return container, params + async def _evict_lru_session_if_over_cap(self, identity: str) -> None: + identity_entries = [(k, v) for k, v in self._container_cache.items() if v[3] == identity] + if len(identity_entries) < _SESSION_SCOPED_PER_IDENTITY_CAP: + return + lru_key, lru_entry = min(identity_entries, key=lambda item: item[1][2]) + self._container_cache.pop(lru_key, None) + await self._delete_container(container=lru_entry[0], params=lru_entry[1]) + async def _create_container(self) -> tuple[Any, dict[str, Any] | None]: if self.sandbox_config is not None: return await self.sandbox_config.acreate_sandbox(), None @@ -739,12 +786,8 @@ class CodeInterpreterInterceptionLogger(CustomLogger): now = time.time() expired = [ (cache_key, container, params) - for cache_key, ( - container, - params, - created_at, - ) in self._container_cache.items() - if now - created_at > _CACHE_TTL_SECONDS + for cache_key, (container, params, last_accessed, *_) in self._container_cache.items() + if now - last_accessed > _CACHE_TTL_SECONDS ] for cache_key, container, params in expired: self._container_cache.pop(cache_key, None) diff --git a/litellm/integrations/custom_guardrail.py b/litellm/integrations/custom_guardrail.py index 59d37639098..ae82e7992ed 100644 --- a/litellm/integrations/custom_guardrail.py +++ b/litellm/integrations/custom_guardrail.py @@ -757,6 +757,12 @@ class CustomGuardrail(CustomLogger): # raw provider JSON so redaction is not duplicated upstream). clean_guardrail_response = redact_nested_match_and_regex_keys(clean_guardrail_response) + from litellm.litellm_core_utils.sensitive_data_masker import ( + mask_credentials_in_payload, + ) + + clean_guardrail_response = mask_credentials_in_payload(clean_guardrail_response) + slg = StandardLoggingGuardrailInformation( guardrail_name=self.guardrail_name, guardrail_provider=guardrail_provider, diff --git a/litellm/integrations/datadog/datadog.py b/litellm/integrations/datadog/datadog.py index 6775858c124..bd62d1e303a 100644 --- a/litellm/integrations/datadog/datadog.py +++ b/litellm/integrations/datadog/datadog.py @@ -354,14 +354,14 @@ class DataDogLogger( Raises: Raises a NON Blocking verbose_logger.exception if an error occurs """ + if not self.log_queue: + verbose_logger.exception("Datadog: log_queue does not exist") + return + + batch_to_send = self.log_queue[:] + self.log_queue = [] + try: - if not self.log_queue: - verbose_logger.exception("Datadog: log_queue does not exist") - return - - batch_to_send = self.log_queue[:] - self.log_queue = [] - verbose_logger.debug( "Datadog - about to flush %s events on %s", len(batch_to_send), diff --git a/litellm/integrations/email_templates/templates.py b/litellm/integrations/email_templates/templates.py index 8df816dfecd..b4f39074a94 100644 --- a/litellm/integrations/email_templates/templates.py +++ b/litellm/integrations/email_templates/templates.py @@ -81,8 +81,7 @@ SOFT_BUDGET_ALERT_EMAIL_TEMPLATE = """ If you have any questions, please send an email to {email_support_contact}

- Best,
- The LiteLLM team
+ {email_footer} """ TEAM_SOFT_BUDGET_ALERT_EMAIL_TEMPLATE = """ @@ -105,8 +104,7 @@ TEAM_SOFT_BUDGET_ALERT_EMAIL_TEMPLATE = """ If you have any questions, please send an email to {email_support_contact}

- Best,
- The LiteLLM team
+ {email_footer} """ MAX_BUDGET_ALERT_EMAIL_TEMPLATE = """ @@ -129,6 +127,5 @@ MAX_BUDGET_ALERT_EMAIL_TEMPLATE = """ If you have any questions, please send an email to {email_support_contact}

- Best,
- The LiteLLM team
+ {email_footer} """ diff --git a/litellm/integrations/otel/README.md b/litellm/integrations/otel/README.md index 17011bb8db7..3038bdb90b2 100644 --- a/litellm/integrations/otel/README.md +++ b/litellm/integrations/otel/README.md @@ -223,6 +223,15 @@ lives in [`plumbing/`](./plumbing): readers/exporters receive them alongside the server metrics, and one is built and registered as the global only when none is set (mirroring how V2 owns trace export). +- [`events.py`](./plumbing/events.py) — GenAI client events. Gated on + `enable_events` (`LITELLM_OTEL_INTEGRATION_ENABLE_EVENTS`), a failed LLM call + records the semconv `gen_ai.client.operation.exception` log event at severity + WARN, carrying `exception.type` / `exception.message` / `exception.stacktrace` + and correlated to the failed span through the trace and span ids. The + `LoggerProvider` is resolved like the meter provider, except that an explicit + `NoOpLoggerProvider` global is an operator opt-out that builds no recorder at + all. The deprecated `error.*` span attributes and the `exception` span event + are still stamped by the emitter for backwards compatibility. ### Adapter diff --git a/litellm/integrations/otel/__init__.py b/litellm/integrations/otel/__init__.py index da3ce4af3e7..5e167e006ff 100644 --- a/litellm/integrations/otel/__init__.py +++ b/litellm/integrations/otel/__init__.py @@ -32,11 +32,13 @@ from litellm.integrations.otel.model.payloads import ( LLMCallSpanData, LLMRequestParams, LLMUsage, + MCPListToolsSpanData, MCPToolCallSpanData, ProxyRequestSpanData, ServerInfo, ServiceSpanData, SpanError, + is_mcp_list_tools, is_mcp_tool_call, ) from litellm.integrations.otel.model.semconv import ( @@ -50,6 +52,7 @@ from litellm.integrations.otel.model.semconv import ( GenAIProvider, JsonRpc, LiteLLM, + LiteLLMError, MCPMethod, Metric, Network, @@ -85,6 +88,7 @@ __all__ = [ "HTTP", "JsonRpc", "LiteLLM", + "LiteLLMError", "MCP", "MCPMethod", "Metric", @@ -106,6 +110,7 @@ __all__ = [ "LLMCallSpanData", "LLMRequestParams", "LLMUsage", + "MCPListToolsSpanData", "MCPToolCallSpanData", "ProxyRequestSpanData", "RequestContext", @@ -113,6 +118,7 @@ __all__ = [ "ServerInfo", "ServiceSpanData", "SpanError", + "is_mcp_list_tools", "is_mcp_tool_call", "promoted_baggage", ] diff --git a/litellm/integrations/otel/emitter.py b/litellm/integrations/otel/emitter.py index 69fc53c5b9d..f97f8b8394c 100644 --- a/litellm/integrations/otel/emitter.py +++ b/litellm/integrations/otel/emitter.py @@ -4,7 +4,7 @@ from collections import OrderedDict from typing import Callable, Sequence from opentelemetry.context import Context -from opentelemetry.trace import Span, Tracer +from opentelemetry.trace import Link, Span, Tracer from opentelemetry.trace.status import Status, StatusCode from litellm.integrations.otel.model.config import OpenTelemetryV2Config @@ -13,16 +13,20 @@ from litellm.integrations.otel.mappers.base import AttributeMapper, SpanData from litellm.integrations.otel.model.payloads import ( GuardrailSpanData, LLMCallSpanData, + MCPListToolsSpanData, MCPToolCallSpanData, ServiceSpanData, + SpanError, ) +from litellm.integrations.otel.plumbing.events import GenAIEventRecorder from litellm.integrations.otel.plumbing.providers import to_otel_span_kind -from litellm.integrations.otel.model.semconv import Error, ExceptionEvent +from litellm.integrations.otel.model.semconv import Error, ExceptionEvent, LiteLLMError from litellm.integrations.otel.model.spans import ( SPAN_REGISTRY, SpanRole, guardrail_span_name, llm_call_span_name, + mcp_list_tools_span_name, mcp_tool_call_span_name, service_span_name, ) @@ -33,6 +37,7 @@ from litellm.integrations.otel.model.spans import ( _NAME_BUILDERS: dict[SpanRole, Callable[..., str]] = { SpanRole.LLM_CALL: llm_call_span_name, SpanRole.MCP_TOOL_CALL: mcp_tool_call_span_name, + SpanRole.MCP_LIST_TOOLS: mcp_list_tools_span_name, SpanRole.GUARDRAIL: guardrail_span_name, # DB_CALL and SERVICE are both built from ServiceSpanData; they differ only in # span kind (CLIENT vs INTERNAL) and attribute vocabulary, not in naming. @@ -46,15 +51,38 @@ _NAME_BUILDERS: dict[SpanRole, Callable[..., str]] = { _DEDUP_CACHE_MAX = 10_000 +def _stamp_otel_error_attributes(span: Span, error_type: str, resolved_message: str) -> None: + """Stamp the OTel-semconv error attributes (``error.type`` + ``error.message``). + ``error_type`` and ``resolved_message`` are ``finish_span``'s already-computed + fallback chains, so the pair on the status, event, and attributes stays in + lockstep.""" + span.set_attribute(Error.TYPE, error_type) + span.set_attribute(Error.MESSAGE, resolved_message) + + +def _stamp_litellm_error_attributes(span: Span, error: SpanError) -> None: + """Stamp litellm-specific error detail attributes. Emitted only when the + corresponding field is populated so guardrail-shape errors carrying only a + message aren't polluted with empty detail keys.""" + if error.code: + span.set_attribute(LiteLLMError.CODE, error.code) + if error.stack_trace: + span.set_attribute(LiteLLMError.STACK_TRACE, error.stack_trace) + if error.llm_provider: + span.set_attribute(LiteLLMError.LLM_PROVIDER, error.llm_provider) + + class SpanEmitter: def __init__( self, tracer: Tracer, config: OpenTelemetryV2Config, mappers: Sequence[AttributeMapper] | None = None, + event_recorder: GenAIEventRecorder | None = None, ) -> None: self._tracer = tracer self._config = config + self._event_recorder = event_recorder # The mapper chain is the sole source of span attributes. When not # passed in, resolve it from the config so there's one source of truth. self._mappers: list[AttributeMapper] = ( @@ -74,18 +102,21 @@ class SpanEmitter: start_time_ns: int | None = None, *, tracer: Tracer | None = None, + links: Sequence[Link] | None = None, ) -> Span: """Start a span for ``role`` without dedup or attribute mapping. For callers that own and manage their own span lifecycle. ``tracer`` overrides the bound tracer for this span only, used for per-request - multi-tenant credential routing. + multi-tenant credential routing. ``links`` records related-but-not-parent + spans (e.g. the transport span of an MCP message, per MCP semconv). """ return (tracer or self._tracer).start_span( name, context=parent_context, kind=to_otel_span_kind(SPAN_REGISTRY[role].kind), start_time=start_time_ns, + links=list(links) if links else None, ) def _seen(self, dedup_key: str | None, role: SpanRole) -> bool: @@ -116,16 +147,23 @@ class SpanEmitter: start_time_ns: int | None = None, end_time_ns: int | None = None, tracer: Tracer | None = None, + links: Sequence[Link] | None = None, ) -> Span | None: """Emit one complete span: dedup, start, map attributes, status, end. Return the span, or ``None`` if it was deduplicated away. ``tracer`` overrides the bound tracer for this span, used for per-request routing. + ``links`` records related-but-not-parent spans (the transport span of an + MCP message). """ # LLM-call and MCP tool-call spans carry a dedup key (their request's # call id), so a sync+async double-firing coalesces. ``isinstance`` narrows # the type for mypy and keeps the engine free of duck-typed attribute reads. - dedup_key = data.identity.call_id if isinstance(data, (LLMCallSpanData, MCPToolCallSpanData)) else None + dedup_key = ( + data.identity.call_id + if isinstance(data, (LLMCallSpanData, MCPToolCallSpanData, MCPListToolsSpanData)) + else None + ) if self._seen(dedup_key, role): return None span = self.start_span( @@ -134,6 +172,7 @@ class SpanEmitter: parent_context=parent_context, start_time_ns=start_time_ns, tracer=tracer, + links=links, ) self.finish_span(role, span, data, end_time_ns=end_time_ns) return span @@ -166,6 +205,7 @@ class SpanEmitter: ( LLMCallSpanData, MCPToolCallSpanData, + MCPListToolsSpanData, ServiceSpanData, GuardrailSpanData, ), @@ -175,16 +215,25 @@ class SpanEmitter: if error and (error.error_type or error.message): error_type = error.error_type or "error" message = error.message or error.error_type or "error" - span.set_attribute(Error.TYPE, error_type) + _stamp_otel_error_attributes(span, error_type, message) + _stamp_litellm_error_attributes(span, error) span.set_status(Status(StatusCode.ERROR, message)) - # Carry the full message on the standard ``exception`` event so backends - # map it as full text under ``exception.message``. Setting it as a bare - # string attribute instead lets backends like Elasticsearch dynamic-map - # it to a ``keyword`` capped at 1024 chars, truncating the message. + # Also emit the semconv ``exception`` event so backends that + # dynamic-map unknown string span attrs to ``keyword`` (e.g. + # Elasticsearch with a 1024-char ``ignore_above``) still see the + # full untruncated message on the recognized event field. span.add_event( ExceptionEvent.NAME, {ExceptionEvent.TYPE: error_type, ExceptionEvent.MESSAGE: message}, ) + if self._event_recorder is not None and role is SpanRole.LLM_CALL: + self._event_recorder.record_operation_exception( + span_context=span.get_span_context(), + error_type=error_type, + message=message, + stack_trace=error.stack_trace, + timestamp_ns=end_time_ns, + ) # On success leave the status UNSET (the semconv default) rather than # forcing OK — that matches the FastAPI server span and avoids implying a # span-level health signal litellm doesn't actually evaluate. Only a diff --git a/litellm/integrations/otel/logger.py b/litellm/integrations/otel/logger.py index 44484559948..be72fabd387 100644 --- a/litellm/integrations/otel/logger.py +++ b/litellm/integrations/otel/logger.py @@ -5,7 +5,8 @@ from contextlib import contextmanager from datetime import datetime from typing import TYPE_CHECKING, Any, Callable, Iterator, Mapping, Sequence, cast -from opentelemetry.context import attach, get_current +from opentelemetry.context import Context, attach, get_current +from opentelemetry.sdk._logs import LoggerProvider from opentelemetry.sdk.trace import TracerProvider from opentelemetry.trace import Span, Tracer, get_current_span, use_span @@ -17,6 +18,7 @@ from litellm.integrations.otel.model.config import OpenTelemetryV2Config from litellm.integrations.otel.plumbing.context import ( is_recordable_span, request_root_span, + resolve_mcp_span_context, resolve_parent_context, resolve_request_span_context, set_request_baggage, @@ -32,19 +34,24 @@ from litellm.integrations.otel.model.metadata import ( from litellm.integrations.otel.model.payloads import ( GuardrailSpanData, LLMCallSpanData, + MCPListToolsSpanData, MCPToolCallSpanData, ServiceSpanData, SpanError, + is_mcp_list_tools, is_mcp_tool_call, ) +from litellm.integrations.otel.plumbing.events import GenAIEventRecorder from litellm.integrations.otel.plumbing.metrics import ( GenAIMetricRecorder, create_genai_metrics, ) from litellm.integrations.otel.plumbing.providers import ( build_tracer_provider, + get_event_logger, get_meter, get_tracer, + resolve_logger_provider, resolve_meter_provider, ) from litellm.integrations.otel.plumbing.routing import TenantTracerCache @@ -101,7 +108,7 @@ class OpenTelemetryV2(CustomLogger): config: OpenTelemetryV2Config | None = None, callback_name: str | None = None, tracer_provider: TracerProvider | None = None, - logger_provider: Any | None = None, # reserved for OTel logs + logger_provider: LoggerProvider | None = None, meter_provider: Any | None = None, **kwargs: Any, ) -> None: @@ -114,7 +121,12 @@ class OpenTelemetryV2(CustomLogger): self.tracer: Tracer = get_tracer(self._tracer_provider, LITELLM_TRACER_NAME) self._metrics_recorder = self._init_metrics(meter_provider) self._metric_filter_error_logged = False - self._emitter = SpanEmitter(self.tracer, self.config, mappers=resolve_mappers(self.config.mapper_names)) + self._emitter = SpanEmitter( + self.tracer, + self.config, + mappers=resolve_mappers(self.config.mapper_names), + event_recorder=self._init_events(logger_provider), + ) self._tenant_tracers = TenantTracerCache(self.config, callback_name, LITELLM_TRACER_NAME) self._open_llm_calls: "OrderedDict[str, _LLMCallSpan]" = OrderedDict() self._init_otel_logger_on_litellm_proxy() @@ -133,6 +145,22 @@ class OpenTelemetryV2(CustomLogger): meter = get_meter(provider, LITELLM_TRACER_NAME) return GenAIMetricRecorder(create_genai_metrics(meter), self.callback_name) + def _init_events(self, logger_provider: LoggerProvider | None) -> "GenAIEventRecorder | None": + """Create the GenAI event recorder when events are enabled, else ``None``. + + ``logger_provider`` is an explicit override (tests inject one); otherwise the + provider is resolved from the OTel global so an operator-configured logs + pipeline receives the events, building and registering one only when no + global provider is set. A ``None`` resolution means the operator opted out + of the logs signal, so no recorder is built. + """ + if not self.config.enable_events: + return None + provider = resolve_logger_provider(self.config, logger_provider) + if provider is None: + return None + return GenAIEventRecorder(get_event_logger(provider, LITELLM_TRACER_NAME)) + # ====================================================================== # # Proxy global registration # ====================================================================== # @@ -218,6 +246,8 @@ class OpenTelemetryV2(CustomLogger): async def async_log_success_event(self, kwargs, response_obj, start_time, end_time): if self._emit_mcp_tool_call(kwargs, start_time, end_time): return + if self._emit_mcp_list_tools(kwargs, start_time, end_time): + return self._close_llm_call(kwargs, start_time, end_time) self._record_metrics(kwargs, response_obj, start_time, end_time) @@ -242,8 +272,24 @@ class OpenTelemetryV2(CustomLogger): async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time): if self._emit_mcp_tool_call(kwargs, start_time, end_time): return + if self._emit_mcp_list_tools(kwargs, start_time, end_time): + return self._close_llm_call(kwargs, start_time, end_time) + def _seed_identity_baggage(self, identity: RequestIdentity, model: str | None, context: Context) -> Context: + """Seed authenticated request-identity Baggage onto ``context`` so the Baggage + processor stamps team/key/metadata onto the span. Identity is read from the + parsed payload, never the client's ``params._meta`` carrier, so it can't be + spoofed.""" + bag = promoted_baggage( + identity, + model, + promoted_keys=tuple(self.config.baggage_promoted_keys), + metadata_keys=tuple(self.config.baggage_metadata_keys), + team_metadata_keys=tuple(self.config.baggage_team_metadata_keys), + ) + return set_request_baggage(bag, context=context) if bag else context + def _emit_mcp_tool_call( self, kwargs: Mapping[str, Any], @@ -254,10 +300,12 @@ class OpenTelemetryV2(CustomLogger): MCP tool calls reach the success/failure callbacks like any other request (with ``call_type`` ``call_mcp_tool``), but they are not LLM calls and have - no ``pre_call`` carrier — so they get their own CLIENT span here, parented - to the request's server span. Returns whether it handled the event, so the - caller skips the LLM-call path. The whole span is emitted at once (there is - no boundary to open it at), deduped on the call id by the emitter. + no ``pre_call`` carrier — so they get their own CLIENT span here. Per the MCP + semconv it parents to the trace context the client propagated in + ``params._meta`` (or starts a new root) and links the transport span, rather + than nesting under the HTTP/session span. Returns whether it handled the + event, so the caller skips the LLM-call path. The whole span is emitted at + once (there is no boundary to open it at), deduped on the call id. """ raw_payload = kwargs.get("standard_logging_object") if not raw_payload or not is_mcp_tool_call(cast(Mapping[str, object], raw_payload)): @@ -271,12 +319,51 @@ class OpenTelemetryV2(CustomLogger): # as a phantom LLM span. if data.identity.call_id: self._open_llm_calls.pop(data.identity.call_id, None) + parent_context, links = resolve_mcp_span_context() + parent_context = self._seed_identity_baggage(data.identity, None, parent_context) self._emitter.emit( SpanRole.MCP_TOOL_CALL, data, - parent_context=resolve_request_span_context(), + parent_context=parent_context, start_time_ns=to_ns(start_time), end_time_ns=to_ns(end_time), + links=links, + ) + return True + + def _emit_mcp_list_tools( + self, + kwargs: Mapping[str, object], + start_time: datetime | float | None, + end_time: datetime | float | None, + ) -> bool: + """Emit an MCP ``tools/list`` span when the closed request was a discovery call. + + Like a tool call, listing reaches the success/failure callbacks (here with + ``call_type`` ``list_mcp_tools``) with no ``pre_call`` carrier, so it gets its + own CLIENT span. Per the MCP semconv it parents to the ``params._meta`` trace + context (or starts a new root) and links the transport span, rather than + nesting under the HTTP/session span. Returns whether it handled the event so + the caller skips the LLM-call path. + """ + raw_payload = kwargs.get("standard_logging_object") + if not raw_payload or not is_mcp_list_tools(cast(Mapping[str, object], raw_payload)): + return False + payload = cast("StandardLoggingPayload", raw_payload) + data = MCPListToolsSpanData.from_standard_logging_payload( + payload, capture_content=self.config.capture_span_content + ) + if data.identity.call_id: + self._open_llm_calls.pop(data.identity.call_id, None) + parent_context, links = resolve_mcp_span_context() + parent_context = self._seed_identity_baggage(data.identity, None, parent_context) + self._emitter.emit( + SpanRole.MCP_LIST_TOOLS, + data, + parent_context=parent_context, + start_time_ns=to_ns(start_time), + end_time_ns=to_ns(end_time), + links=links, ) return True @@ -306,7 +393,11 @@ class OpenTelemetryV2(CustomLogger): # it (named provisionally) so it isn't leaked as an open span. carrier.span.end(end_time=to_ns(end_time)) return None - data = LLMCallSpanData.from_standard_logging_payload(payload, capture_content=self.config.capture_span_content) + data = LLMCallSpanData.from_standard_logging_payload( + payload, + capture_content=self.config.capture_span_content, + time_to_first_chunk_seconds=call.time_to_first_chunk_seconds, + ) end_time_ns = to_ns(end_time) if carrier.span is not None: # Born at the boundary: stamp attributes from the typed payload, set @@ -319,16 +410,7 @@ class OpenTelemetryV2(CustomLogger): # root span — parent to it (ambient fallback on the SDK path). Seed identity # Baggage so the span — and the SDK path, which has none — is labeled # consistently. - parent_ctx = resolve_request_span_context() - bag = promoted_baggage( - data.identity, - data.request_model, - promoted_keys=tuple(self.config.baggage_promoted_keys), - metadata_keys=tuple(self.config.baggage_metadata_keys), - team_metadata_keys=tuple(self.config.baggage_team_metadata_keys), - ) - if bag: - parent_ctx = set_request_baggage(bag, context=parent_ctx) + parent_ctx = self._seed_identity_baggage(data.identity, data.request_model, resolve_request_span_context()) return self._emitter.emit( SpanRole.LLM_CALL, data, diff --git a/litellm/integrations/otel/mappers/base.py b/litellm/integrations/otel/mappers/base.py index 6685e34578b..809d956a9c7 100644 --- a/litellm/integrations/otel/mappers/base.py +++ b/litellm/integrations/otel/mappers/base.py @@ -7,6 +7,7 @@ from typing_extensions import Protocol, runtime_checkable from litellm.integrations.otel.model.payloads import ( GuardrailSpanData, LLMCallSpanData, + MCPListToolsSpanData, MCPToolCallSpanData, ServiceSpanData, ) @@ -20,7 +21,7 @@ AttributeMap = dict[str, AttrValue] # The closed set of span-data types the engine routes through the mapper chain. # Server spans (PROXY_REQUEST + management routes) belong to the mounted FastAPI # instrumentor, not the mapper chain. -SpanData = LLMCallSpanData | MCPToolCallSpanData | GuardrailSpanData | ServiceSpanData +SpanData = LLMCallSpanData | MCPToolCallSpanData | MCPListToolsSpanData | GuardrailSpanData | ServiceSpanData @runtime_checkable diff --git a/litellm/integrations/otel/mappers/genai.py b/litellm/integrations/otel/mappers/genai.py index ad6d3e7ff21..f568afa9e3e 100644 --- a/litellm/integrations/otel/mappers/genai.py +++ b/litellm/integrations/otel/mappers/genai.py @@ -19,6 +19,7 @@ from litellm.integrations.otel.mappers.utils import ( from litellm.integrations.otel.model.payloads import ( GuardrailSpanData, LLMCallSpanData, + MCPListToolsSpanData, MCPToolCallSpanData, ServiceSpanData, ToolDefinition, @@ -54,6 +55,7 @@ class GenAIMapper: GenAI.RESPONSE_MODEL: lambda d: d.response_model, GenAI.RESPONSE_ID: lambda d: d.response_id, GenAI.RESPONSE_FINISH_REASONS: lambda d: list(d.finish_reasons) if d.finish_reasons else None, + GenAI.RESPONSE_TIME_TO_FIRST_CHUNK: lambda d: d.time_to_first_chunk_seconds, GenAI.USAGE_INPUT_TOKENS: lambda d: d.usage.input_tokens, GenAI.USAGE_OUTPUT_TOKENS: lambda d: d.usage.output_tokens, Error.TYPE: lambda d: d.error.error_type if d.error else None, @@ -100,6 +102,15 @@ class GenAIMapper: f"{LiteLLM.COST_PREFIX}total": lambda d: d.response_cost, } + # A tools/list discovery span: the method and session only. Per semconv it must + # NOT carry gen_ai.operation.name (execute_tool) or gen_ai.tool.name — those are + # for tool calls, and listing executes no tool. + _MCP_LIST_ATTRS: dict[str, Callable[[MCPListToolsSpanData], AttrValue | None]] = { + MCP.METHOD_NAME: lambda d: d.method, + MCP.SESSION_ID: lambda d: d.session_id, + LiteLLM.CALL_ID: lambda d: d.identity.call_id or None, + } + _GUARDRAIL_ATTRS: dict[str, Callable[[GuardrailSpanData], AttrValue | None]] = { LiteLLM.GUARDRAIL_NAME: lambda d: d.guardrail_name, LiteLLM.GUARDRAIL_MODE: lambda d: d.mode, @@ -130,6 +141,8 @@ class GenAIMapper: return self._llm_call(data) case MCPToolCallSpanData(): return collect(self._MCP_ATTRS, data) + case MCPListToolsSpanData(): + return collect(self._MCP_LIST_ATTRS, data) case GuardrailSpanData(): return self._guardrail(data) case ServiceSpanData(): diff --git a/litellm/integrations/otel/model/metadata.py b/litellm/integrations/otel/model/metadata.py index 37bb5464315..7ff4f540908 100644 --- a/litellm/integrations/otel/model/metadata.py +++ b/litellm/integrations/otel/model/metadata.py @@ -41,7 +41,7 @@ from typing import TYPE_CHECKING, Any, Mapping, cast from litellm.constants import LITELLM_LOGGING_NO_UPSTREAM_LLM_CALL from litellm.integrations.otel.model.semconv import resolve_operation -from litellm.integrations.otel.model.utils import as_str +from litellm.integrations.otel.model.utils import as_str, to_seconds if TYPE_CHECKING: from litellm.types.utils import StandardLoggingPayload @@ -201,6 +201,7 @@ class LLMCallEvent: # span is renamed from the typed payload at close (``finish_span``); this only # needs to be reasonable for a span that never gets closed (a leak). provisional_span_name: str + time_to_first_chunk_seconds: float | None @classmethod def from_dict(cls, kwargs: Mapping[str, Any]) -> "LLMCallEvent": @@ -214,9 +215,25 @@ class LLMCallEvent: dynamic_params=kwargs.get("standard_callback_dynamic_params"), is_no_upstream_call=bool(kwargs.get(LITELLM_LOGGING_NO_UPSTREAM_LLM_CALL)), provisional_span_name=f"{operation.value} {model}".strip(), + time_to_first_chunk_seconds=time_to_first_chunk_seconds(kwargs), ) +def time_to_first_chunk_seconds(kwargs: Mapping[str, Any]) -> float | None: + """Seconds from the upstream request being issued (``api_call_start_time``) + to the first streamed chunk (``completion_start_time``); ``None`` for + non-streaming calls, where ``completion_start_time`` is backfilled with the + end time and would not measure first-chunk latency.""" + optional_params = cast(Mapping[str, Any], kwargs.get("optional_params") or {}) + if not optional_params.get("stream"): + return None + api_call_start = to_seconds(kwargs.get("api_call_start_time")) + completion_start = to_seconds(kwargs.get("completion_start_time")) + if api_call_start is None or completion_start is None: + return None + return completion_start - api_call_start + + def _call_id(payload: "StandardLoggingPayload | None", kwargs: Mapping[str, Any]) -> str | None: """The call id from the payload (when closed) or the bare kwargs (at pre_call).""" if payload is not None: diff --git a/litellm/integrations/otel/model/payloads.py b/litellm/integrations/otel/model/payloads.py index a368a862024..4a8f01858b5 100644 --- a/litellm/integrations/otel/model/payloads.py +++ b/litellm/integrations/otel/model/payloads.py @@ -37,12 +37,14 @@ __all__ = [ "LLMCost", "LLMRequestParams", "LLMUsage", + "MCPListToolsSpanData", "MCPToolCallSpanData", "ProxyRequestSpanData", "ServerInfo", "ServiceSpanData", "SpanError", "ToolDefinition", + "is_mcp_list_tools", "is_mcp_tool_call", ] @@ -139,6 +141,9 @@ class LLMCost: class SpanError: error_type: str | None = None message: str | None = None + code: str | None = None + stack_trace: str | None = None + llm_provider: str | None = None @dataclass(frozen=True) @@ -303,10 +308,14 @@ class LLMCallSpanData: messages_in: tuple[Mapping[str, object], ...] = () choices_out: tuple[Mapping[str, object], ...] = () system_fingerprint: str | None = None + time_to_first_chunk_seconds: float | None = None @classmethod def from_standard_logging_payload( - cls, payload: "StandardLoggingPayload", capture_content: bool = False + cls, + payload: "StandardLoggingPayload", + capture_content: bool = False, + time_to_first_chunk_seconds: float | None = None, ) -> "LLMCallSpanData": params = cast(Mapping[str, object], payload.get("model_parameters") or {}) # The single parse of the request's metadata — the request-vs-provider @@ -347,6 +356,7 @@ class LLMCallSpanData: messages_in=_dicts(payload.get("messages")) if capture_content else (), choices_out=choices_out if capture_content else (), system_fingerprint=as_str(response.get("system_fingerprint")), + time_to_first_chunk_seconds=time_to_first_chunk_seconds, ) @@ -415,6 +425,42 @@ def is_mcp_tool_call(payload: Mapping[str, object]) -> bool: return bool(_mcp_tool_call_metadata(payload)) or (payload.get("call_type") == "call_mcp_tool") +@dataclass(frozen=True) +class MCPListToolsSpanData: + """One MCP ``tools/list`` discovery call, parsed from a closed request's payload. + + The proxy is an MCP *client* enumerating an upstream server's tools, so this is + a CLIENT span. It carries neither ``gen_ai.operation.name`` nor ``gen_ai.tool.name``: + the GenAI semconv sets ``execute_tool`` (and the tool name) only for tool *calls*, + and listing executes no tool. + """ + + method: str + session_id: str | None + error: SpanError | None + identity: RequestIdentity + + @classmethod + def from_standard_logging_payload( + cls, payload: StandardLoggingPayload, capture_content: bool = False + ) -> MCPListToolsSpanData: + # The list-tools logging path does not thread an MCP session id into the + # payload (only the tool-call path stamps ``mcp_tool_call_metadata``), so + # there is none to read here; ``mcp.session.id`` is simply omitted. + return cls( + method=MCPMethod.TOOLS_LIST.value, + session_id=None, + error=_parse_error(payload), + identity=RequestContext.from_standard_logging_payload(payload).identity, + ) + + +def is_mcp_list_tools(payload: Mapping[str, object]) -> bool: + """Whether a closed request's payload is an MCP ``tools/list`` discovery call + rather than a tool call or an LLM call — true when the call type says so.""" + return payload.get("call_type") == "list_mcp_tools" + + # --- service event_metadata sanitization ------------------------------------ # # Substrings (case-insensitive) of keys that must never reach a span: secrets, @@ -528,6 +574,9 @@ def _parse_error(payload: "StandardLoggingPayload") -> SpanError | None: return SpanError( error_type=as_str(info.get("error_class")) or as_str(info.get("error_code")), message=as_str(info.get("error_message")) or as_str(payload.get("error_str")), + code=as_str(info.get("error_code")), + stack_trace=as_str(info.get("traceback")), + llm_provider=as_str(info.get("llm_provider")), ) diff --git a/litellm/integrations/otel/model/semconv.py b/litellm/integrations/otel/model/semconv.py index 6315a5a4a89..44b2f7e0488 100644 --- a/litellm/integrations/otel/model/semconv.py +++ b/litellm/integrations/otel/model/semconv.py @@ -69,6 +69,7 @@ class GenAI: RESPONSE_ID: Final = "gen_ai.response.id" RESPONSE_MODEL: Final = "gen_ai.response.model" RESPONSE_FINISH_REASONS: Final = "gen_ai.response.finish_reasons" + RESPONSE_TIME_TO_FIRST_CHUNK: Final = "gen_ai.response.time_to_first_chunk" # usage USAGE_INPUT_TOKENS: Final = "gen_ai.usage.input_tokens" USAGE_OUTPUT_TOKENS: Final = "gen_ai.usage.output_tokens" @@ -143,7 +144,24 @@ class Client: class Error: + """OTel-defined error attribute keys, from the semconv ``error.*`` registry. + ``MESSAGE`` is marked *Deprecated* upstream in favor of domain-specific + error message keys plus ``exception.message`` on the exception event, but + litellm still stamps it.""" + TYPE: Final = "error.type" + MESSAGE: Final = "error.message" + + +class LiteLLMError: + """Detail keys for the mapped provider exception of a failed LLM call. + OTel semconv does not define these, so they live under the ``litellm.*`` + vendor namespace rather than squatting on the semconv-owned ``error.*`` + namespace.""" + + CODE: Final = "litellm.provider.error.code" + STACK_TRACE: Final = "litellm.provider.error.stack_trace" + LLM_PROVIDER: Final = "litellm.provider.error.llm_provider" class ExceptionEvent: @@ -159,6 +177,19 @@ class ExceptionEvent: NAME: Final = "exception" TYPE: Final = "exception.type" MESSAGE: Final = "exception.message" + STACKTRACE: Final = "exception.stacktrace" + + +class GenAIEvent: + """GenAI semconv event names, from the GenAI registry's *events* section. + + ``gen_ai.client.operation.exception`` is defined as a log-based event + (severity WARN) carrying the ``exception.*`` trio, correlated to the failed + span via the trace/span ids — the semconv-compliant home for GenAI failure + details, unlike the deprecated ``error.message`` span attribute. + """ + + OPERATION_EXCEPTION: Final = "gen_ai.client.operation.exception" class Server: diff --git a/litellm/integrations/otel/model/spans.py b/litellm/integrations/otel/model/spans.py index bc624cf6a57..c93f95ec97d 100644 --- a/litellm/integrations/otel/model/spans.py +++ b/litellm/integrations/otel/model/spans.py @@ -18,6 +18,13 @@ before the LLM call even starts), so a guardrail is a sibling of the LLM call, not a child of it. The emitter parents every span to the ambient OTel context (the active server span), which matches this. +MCP spans (``MCP_TOOL_CALL``, ``MCP_LIST_TOOLS``) are intentionally NOT in this +tree. Per the OTel GenAI MCP semconv, MCP and the HTTP transport are independent +contexts, so an MCP span parents to the trace context the client propagated in +``params._meta`` (or starts its own root when none is propagated) and records the +``PROXY_REQUEST`` transport span as a span *link*, never a parent. The registry +encodes this as ``parent=None, links=PROXY_REQUEST``. + Not every service call becomes a span — :func:`span_role_for_service` decides: - ``DB_CALL`` (CLIENT) — outbound datastores (redis, postgres, @@ -46,6 +53,7 @@ if TYPE_CHECKING: from litellm.integrations.otel.model.payloads import ( GuardrailSpanData, LLMCallSpanData, + MCPListToolsSpanData, MCPToolCallSpanData, ProxyRequestSpanData, ServiceSpanData, @@ -56,6 +64,7 @@ class SpanRole(str, Enum): PROXY_REQUEST = "proxy_request" LLM_CALL = "llm_call" MCP_TOOL_CALL = "mcp_tool_call" + MCP_LIST_TOOLS = "mcp_list_tools" GUARDRAIL = "guardrail" DB_CALL = "db_call" SERVICE = "service" @@ -74,14 +83,24 @@ class SpanSpec: role: SpanRole kind: LiteLLMSpanKind parent: SpanRole | None + links: SpanRole | None = None SPAN_REGISTRY: dict[SpanRole, SpanSpec] = { SpanRole.PROXY_REQUEST: SpanSpec(SpanRole.PROXY_REQUEST, LiteLLMSpanKind.SERVER, parent=None), SpanRole.LLM_CALL: SpanSpec(SpanRole.LLM_CALL, LiteLLMSpanKind.CLIENT, parent=SpanRole.PROXY_REQUEST), - # The proxy is an MCP client to the upstream server it dispatches the tool - # call to, so this is a CLIENT span, sibling of the LLM call under the request. - SpanRole.MCP_TOOL_CALL: SpanSpec(SpanRole.MCP_TOOL_CALL, LiteLLMSpanKind.CLIENT, parent=SpanRole.PROXY_REQUEST), + # MCP and the HTTP transport are independent contexts (OTel GenAI MCP semconv), + # so an MCP span does not nest under the transport span. The proxy is an MCP + # client to the upstream server, so it's a CLIENT span; it parents to the trace + # context the client propagated in ``params._meta`` (or starts its own root when + # none is propagated) and records the PROXY_REQUEST transport span as a span + # *link*, never a parent — hence ``parent=None, links=PROXY_REQUEST``. + SpanRole.MCP_TOOL_CALL: SpanSpec( + SpanRole.MCP_TOOL_CALL, LiteLLMSpanKind.CLIENT, parent=None, links=SpanRole.PROXY_REQUEST + ), + SpanRole.MCP_LIST_TOOLS: SpanSpec( + SpanRole.MCP_LIST_TOOLS, LiteLLMSpanKind.CLIENT, parent=None, links=SpanRole.PROXY_REQUEST + ), SpanRole.GUARDRAIL: SpanSpec(SpanRole.GUARDRAIL, LiteLLMSpanKind.INTERNAL, parent=SpanRole.PROXY_REQUEST), SpanRole.DB_CALL: SpanSpec(SpanRole.DB_CALL, LiteLLMSpanKind.CLIENT, parent=SpanRole.PROXY_REQUEST), SpanRole.SERVICE: SpanSpec(SpanRole.SERVICE, LiteLLMSpanKind.INTERNAL, parent=SpanRole.PROXY_REQUEST), @@ -163,6 +182,12 @@ def mcp_tool_call_span_name(data: "MCPToolCallSpanData") -> str: return f"{data.method} {data.tool_name}".strip() +def mcp_list_tools_span_name(data: "MCPListToolsSpanData") -> str: + """``"{mcp.method.name}"`` i.e. ``"tools/list"`` — no low-cardinality target, so + the method name alone names the span (MCP semconv).""" + return data.method + + def proxy_request_span_name(data: "ProxyRequestSpanData") -> str: """``"{method} {route}"`` (HTTP semconv).""" return f"{data.http_method} {data.route}".strip() @@ -179,7 +204,8 @@ def service_span_name(data: "ServiceSpanData") -> str: def root_roles() -> list[SpanRole]: - """Roles that start a new trace (no in-process parent).""" + """Roles with no in-process parent. They start a new trace unless they adopt a + remote parent (e.g. an MCP span joining the client's propagated context).""" return [role for role, spec in SPAN_REGISTRY.items() if spec.parent is None] @@ -196,6 +222,8 @@ def validate_registry( raise ValueError(f"SPAN_REGISTRY[{role}] has mismatched role {spec.role}") if spec.parent is not None and spec.parent not in reg: raise ValueError(f"span role {role} declares unknown parent {spec.parent}") + if spec.links is not None and spec.links not in reg: + raise ValueError(f"span role {role} declares unknown link target {spec.links}") missing = [role for role in SpanRole if role not in reg] if missing: raise ValueError(f"SPAN_REGISTRY is missing roles: {missing}") diff --git a/litellm/integrations/otel/plumbing/context.py b/litellm/integrations/otel/plumbing/context.py index ff513c84d95..8acac112c3d 100644 --- a/litellm/integrations/otel/plumbing/context.py +++ b/litellm/integrations/otel/plumbing/context.py @@ -1,11 +1,11 @@ """Trace-context + Baggage helpers.""" -from contextvars import ContextVar +from contextvars import ContextVar, Token from typing import Mapping from opentelemetry import baggage from opentelemetry.context import Context, get_current -from opentelemetry.trace import Span, get_current_span, set_span_in_context +from opentelemetry.trace import Link, Span, get_current_span, set_span_in_context from opentelemetry.trace.propagation.tracecontext import ( TraceContextTextMapPropagator, ) @@ -47,6 +47,31 @@ def request_root_span() -> "Span | None": return span if is_recordable_span(span) else None +# The W3C trace-context carrier (``traceparent``/``tracestate``/``baggage``) the +# MCP client propagated in the current request's ``params._meta``. The MCP gateway +# sets it per message so the MCP span can parent to the client's span rather than +# to the transport. A ``ContextVar`` because, like the root-span anchor, it must +# ride the request task and be readable by the inline success-logging callback. +_mcp_message_trace_carrier: "ContextVar[Mapping[str, str] | None]" = ContextVar( + "litellm_otel_mcp_message_trace_carrier", default=None +) + + +def set_mcp_message_trace_carrier( + carrier: "Mapping[str, str] | None", +) -> "Token[Mapping[str, str] | None]": + """Stash the current MCP message's propagated trace-context carrier. + + Returns the reset token; the caller must reset it once the message is handled + so the carrier never leaks to the next message on the same session task. + """ + return _mcp_message_trace_carrier.set(carrier) + + +def reset_mcp_message_trace_carrier(token: "Token[Mapping[str, str] | None]") -> None: + _mcp_message_trace_carrier.reset(token) + + def set_request_baggage(values: Mapping[str, str], context: Context | None = None) -> Context: """Return a context with ``values`` written into Baggage.""" ctx = context @@ -104,6 +129,38 @@ def resolve_request_span_context() -> Context: return get_current() +def resolve_mcp_span_context( + carrier: "Mapping[str, str] | None" = None, +) -> "tuple[Context, tuple[Link, ...]]": + """Parent context + links for an MCP message span, per the OTel GenAI MCP semconv. + + MCP and the underlying transport (HTTP) are independent lifecycles — one + streamable-HTTP session multiplexes many messages, so nesting the message span + under the HTTP/session span is wrong (it renders the message at the session's + start, skewed by however long the session has been open). Instead: + + * parent to the trace context the client propagated in the request's + ``params._meta`` (a *remote* parent), and + * record the transport/session span as a *link*, never the parent. + + Only trace context (``traceparent``/``tracestate``) is extracted, never the + client's W3C Baggage: ``params._meta`` is caller-controlled, and the otel + baggage processor stamps allowlisted baggage keys (``litellm.team.id``, + ``litellm.metadata.*``, ...) onto the span as attributes, so honoring remote + baggage would let a client spoof a span's identity attribution. + + With no propagated context the returned context carries no span, so the span + starts its own root trace (still linked to the transport). The base context is + explicitly empty so an absent ``traceparent`` can never fall through to the + ambient (stale session) span. + """ + source = carrier if carrier is not None else _mcp_message_trace_carrier.get() + parent = _PROPAGATOR.extract(dict(source or {}), context=Context()) + transport = request_root_span() + links = (Link(transport.get_span_context()),) if transport is not None else () + return parent, links + + def is_recordable_span(obj: object) -> bool: """True if ``obj`` is a live span with a valid context (safe to parent under).""" if not isinstance(obj, Span): diff --git a/litellm/integrations/otel/plumbing/events.py b/litellm/integrations/otel/plumbing/events.py new file mode 100644 index 00000000000..f674526d04f --- /dev/null +++ b/litellm/integrations/otel/plumbing/events.py @@ -0,0 +1,52 @@ +"""GenAI client events: the ``gen_ai.client.operation.exception`` log event. + +The GenAI semantic conventions define exception recording for client +operations as a log-based event (severity WARN) carrying the ``exception.*`` +attribute trio, correlated to the failed span through the trace/span ids — +not as a span attribute or span event. This module owns building and +emitting that event; the exporter pipeline it rides is built in +:mod:`litellm.integrations.otel.plumbing.providers`. +""" + +from dataclasses import dataclass + +from opentelemetry._events import Event, EventLogger +from opentelemetry._logs.severity import SeverityNumber +from opentelemetry.trace import SpanContext + +from litellm.integrations.otel.model.semconv import ExceptionEvent, GenAIEvent + + +@dataclass(frozen=True, slots=True) +class GenAIEventRecorder: + event_logger: EventLogger + + def record_operation_exception( + self, + span_context: SpanContext, + error_type: str, + message: str, + stack_trace: str | None, + timestamp_ns: int | None, + ) -> None: + # ``exception.type`` and ``exception.message`` are the semconv-required + # pair and always ride the event; only the recommended stacktrace is + # conditional on the payload carrying one. + stacktrace = ((ExceptionEvent.STACKTRACE, stack_trace),) if stack_trace else () + self.event_logger.emit( + Event( + name=GenAIEvent.OPERATION_EXCEPTION, + timestamp=timestamp_ns, + trace_id=span_context.trace_id, + span_id=span_context.span_id, + trace_flags=span_context.trace_flags, + severity_number=SeverityNumber.WARN, + attributes=dict( + ( + (ExceptionEvent.TYPE, error_type), + (ExceptionEvent.MESSAGE, message), + *stacktrace, + ) + ), + ) + ) diff --git a/litellm/integrations/otel/plumbing/metrics.py b/litellm/integrations/otel/plumbing/metrics.py index cb1f9214876..50d0fb75962 100644 --- a/litellm/integrations/otel/plumbing/metrics.py +++ b/litellm/integrations/otel/plumbing/metrics.py @@ -21,6 +21,7 @@ from litellm.integrations.opentelemetry import ( _build_metric_attribute_filter, _resolve_metric_attribute_filter, ) +from litellm.integrations.otel.model.metadata import time_to_first_chunk_seconds from litellm.integrations.otel.model.semconv import Metric, resolve_operation from litellm.integrations.otel.model.utils import to_seconds from litellm.litellm_core_utils.safe_json_dumps import safe_dumps @@ -181,13 +182,10 @@ class GenAIMetricRecorder: self._metrics.token_usage.record(usage.get("completion_tokens", 0), attributes=out_attrs) def _record_time_to_first_token(self, kwargs: Mapping[str, Any], common_attrs: dict) -> None: - if not kwargs.get("optional_params", {}).get("stream", False): + time_to_first_chunk = time_to_first_chunk_seconds(kwargs) + if time_to_first_chunk is None: return - api_call_start = to_seconds(kwargs.get("api_call_start_time")) - completion_start = to_seconds(kwargs.get("completion_start_time")) - if api_call_start is None or completion_start is None: - return - self._metrics.time_to_first_token.record(completion_start - api_call_start, attributes=common_attrs) + self._metrics.time_to_first_token.record(time_to_first_chunk, attributes=common_attrs) def _record_time_per_output_token( self, diff --git a/litellm/integrations/otel/plumbing/providers.py b/litellm/integrations/otel/plumbing/providers.py index ac971c6daa8..ced65aa1ec3 100644 --- a/litellm/integrations/otel/plumbing/providers.py +++ b/litellm/integrations/otel/plumbing/providers.py @@ -2,9 +2,20 @@ from typing import TYPE_CHECKING, Any, Callable, Iterable -from opentelemetry import baggage, metrics +from opentelemetry import _logs, baggage, metrics +from opentelemetry._events import EventLogger +from opentelemetry._logs import LoggerProvider, NoOpLoggerProvider from opentelemetry.context import Context from opentelemetry.metrics import MeterProvider, NoOpMeterProvider +from opentelemetry.sdk._events import EventLoggerProvider +from opentelemetry.sdk._logs import LoggerProvider as SDKLoggerProvider +from opentelemetry.sdk._logs.export import ( + BatchLogRecordProcessor, + ConsoleLogExporter, + InMemoryLogExporter, + LogExporter, + SimpleLogRecordProcessor, +) from opentelemetry.sdk.metrics import MeterProvider as SDKMeterProvider from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import ReadableSpan, SpanProcessor, TracerProvider @@ -224,6 +235,112 @@ def build_metric_reader(config: OpenTelemetryV2Config) -> "MetricReader": return PeriodicExportingMetricReader(exporter, export_interval_millis=5000) +def _otlp_logs_endpoint(endpoint: str | None) -> str | None: + """Point an OTLP/HTTP base endpoint at the ``/v1/logs`` signal path. + + The OTLP/HTTP exporter only appends ``/v1/logs`` when it reads + ``OTEL_EXPORTER_OTLP_ENDPOINT`` itself; an explicitly passed endpoint is used + verbatim, so a base URL would POST to the root. Mirror ``_otlp_traces_endpoint`` + for the logs signal (rewriting a sibling signal path when present). + """ + if not endpoint: + return endpoint + endpoint = endpoint.rstrip("/") + if endpoint.endswith("/v1/logs"): + return endpoint + for other_signal in ("/v1/traces", "/v1/metrics"): + if endpoint.endswith(other_signal): + return endpoint[: -len(other_signal)] + "/v1/logs" + return endpoint + "/v1/logs" + + +def build_log_exporter(config: OpenTelemetryV2Config) -> LogExporter: + """Build a log exporter mirroring the exporter selection of the other signals. + + ``console`` (and any unrecognized kind) exports to the console; ``otlp_http`` + and ``otlp_grpc`` export over OTLP with the configured endpoint/headers; + ``in_memory`` buffers for tests. Like GenAI metrics, events ride the + single-destination shorthand fields, not the multi-exporter ``exporters`` list. + """ + kind = (config.exporter or "console").lower() + if kind in ("in_memory", "inmemory", "memory"): + return InMemoryLogExporter() + if kind in ("otlp_http", "http", "http/protobuf", "http/json"): + from opentelemetry.exporter.otlp.proto.http._log_exporter import ( + OTLPLogExporter as HTTPLogExporter, + ) + + return HTTPLogExporter( + endpoint=_otlp_logs_endpoint(config.endpoint), + headers=parse_headers(config.headers), + ) + if kind in ("otlp_grpc", "grpc"): + try: + from opentelemetry.exporter.otlp.proto.grpc._log_exporter import ( + OTLPLogExporter as GRPCLogExporter, + ) + except ImportError as exc: + raise ImportError( + "OpenTelemetry OTLP gRPC log exporter is not available. Install " + "`opentelemetry-exporter-otlp` and `grpcio` (or `litellm[grpc]`)." + ) from exc + + return GRPCLogExporter(endpoint=config.endpoint, headers=parse_headers(config.headers)) + return ConsoleLogExporter() + + +def build_logger_provider( + config: OpenTelemetryV2Config, + log_exporter: LogExporter | None = None, +) -> SDKLoggerProvider: + """Build the :class:`LoggerProvider` GenAI events export through. + + ``log_exporter`` is an explicit override (tests inject an + ``InMemoryLogExporter``); otherwise the exporter is selected from the config's + exporter kind via :func:`build_log_exporter`. Console and in-memory exporters + get a Simple processor (synchronous export, which tests rely on), everything + else a Batch processor — the same split as span processing. + """ + exporter = log_exporter if log_exporter is not None else build_log_exporter(config) + provider = SDKLoggerProvider(resource=build_resource(config)) + use_simple = isinstance(exporter, (ConsoleLogExporter, InMemoryLogExporter)) + provider.add_log_record_processor( + SimpleLogRecordProcessor(exporter) if use_simple else BatchLogRecordProcessor(exporter) + ) + return provider + + +def resolve_logger_provider( + config: OpenTelemetryV2Config, + logger_provider: SDKLoggerProvider | None = None, +) -> SDKLoggerProvider | None: + """Resolve the :class:`LoggerProvider` GenAI events record through, or ``None`` + when the operator has opted out of the logs signal. + + Same resolution order as :func:`resolve_meter_provider`: an injected provider + wins (DI/tests); an operator-configured SDK global is reused so events ride + their pipeline; an explicit ``NoOpLoggerProvider`` global is an opt-out and + yields ``None``, so no event is ever built. Only the default placeholder + global makes V2 build a provider from the config and publish it as the global. + """ + if logger_provider is not None: + return logger_provider + + existing: LoggerProvider = _logs.get_logger_provider() + if isinstance(existing, SDKLoggerProvider): + return existing + if isinstance(existing, NoOpLoggerProvider): + return None + + provider = build_logger_provider(config) + _logs.set_logger_provider(provider) + return provider + + +def get_event_logger(provider: SDKLoggerProvider, name: str = "litellm") -> EventLogger: + return EventLoggerProvider(logger_provider=provider).get_event_logger(name, litellm_version) + + def build_meter_provider( config: OpenTelemetryV2Config, metric_reader: "MetricReader | None" = None, diff --git a/litellm/integrations/otel/runtime.py b/litellm/integrations/otel/runtime.py index ac3b991c971..eb512375023 100644 --- a/litellm/integrations/otel/runtime.py +++ b/litellm/integrations/otel/runtime.py @@ -8,7 +8,23 @@ identity unconditionally. """ from contextlib import contextmanager -from typing import Any, Iterator +from functools import cache +from typing import Any, Callable, Iterator, Optional + + +@cache +def _otel_runtime() -> "Optional[tuple[Callable[[str], Any], Callable[..., None]]]": + """Resolve the SDK-backed hooks once and cache the outcome, absence included. + + CPython never caches a failed import, so without this memoization every call + site re-attempts the import on each request; when the OTel SDK is not installed + that re-scans ``sys.path`` and contends on the import lock on the hot path. + """ + try: + from litellm.integrations.otel import logger + except Exception: + return None + return (logger.phase_span, logger.seed_request_identity) @contextmanager @@ -18,21 +34,17 @@ def phase_span(name: str) -> "Iterator[Any]": Yields ``None`` (a plain no-op) when the OTel SDK is unavailable or V2 is not the active logger. """ - try: - from litellm.integrations.otel.logger import phase_span as _phase_span - except Exception: + runtime = _otel_runtime() + if runtime is None: yield None return - with _phase_span(name) as span: + with runtime[0](name) as span: yield span def seed_request_identity(user_api_key_dict: Any, model: Any = None) -> None: """Seed request-identity Baggage at the auth boundary (no-op without V2).""" - try: - from litellm.integrations.otel.logger import ( - seed_request_identity as _seed_request_identity, - ) - except Exception: + runtime = _otel_runtime() + if runtime is None: return - _seed_request_identity(user_api_key_dict, model=model) + runtime[1](user_api_key_dict, model=model) diff --git a/litellm/integrations/prometheus.py b/litellm/integrations/prometheus.py index fcec551f25a..60fc021a6a8 100644 --- a/litellm/integrations/prometheus.py +++ b/litellm/integrations/prometheus.py @@ -4,6 +4,7 @@ from __future__ import annotations import asyncio +import math import os import sys from datetime import datetime, timedelta @@ -49,22 +50,48 @@ from litellm.proxy._types import ( from litellm.repositories.organization_repository import OrganizationRepository from litellm.repositories.team_repository import TeamRepository from litellm.repositories.user_repository import UserRepository +from litellm.types.guardrails import GuardrailEventHooks from litellm.types.integrations.prometheus import * from litellm.types.integrations.prometheus import ( _sanitize_prometheus_label_name, _sanitize_prometheus_label_value, ) -from litellm.types.utils import StandardLoggingPayload +from litellm.types.utils import ( + StandardLoggingGuardrailInformation, + StandardLoggingPayload, +) if TYPE_CHECKING: from apscheduler.schedulers.asyncio import AsyncIOScheduler else: AsyncIOScheduler = Any +_DEFAULT_BUDGET_METRICS_PER_REQUEST_TIMEOUT = 5.0 + + +def _get_budget_metrics_per_request_timeout() -> float: + raw = os.getenv("PROMETHEUS_BUDGET_METRICS_PER_REQUEST_TIMEOUT") + if raw is None: + return _DEFAULT_BUDGET_METRICS_PER_REQUEST_TIMEOUT + try: + parsed = float(raw) + except ValueError: + parsed = None + if parsed is None or not math.isfinite(parsed) or parsed <= 0: + verbose_logger.debug( + "[Non-Blocking] Prometheus: invalid PROMETHEUS_BUDGET_METRICS_PER_REQUEST_TIMEOUT=%r; using default %ss.", + raw, + _DEFAULT_BUDGET_METRICS_PER_REQUEST_TIMEOUT, + ) + return _DEFAULT_BUDGET_METRICS_PER_REQUEST_TIMEOUT + return parsed + class PrometheusLogger(CustomLogger): # Class variables or attributes + _ADDITIVE_GUARDRAIL_MODES = frozenset((GuardrailEventHooks.pre_call.value, GuardrailEventHooks.post_call.value)) + @staticmethod def get_instance() -> Optional["PrometheusLogger"]: """Find the PrometheusLogger instance from litellm.callbacks, if registered.""" @@ -343,6 +370,14 @@ class PrometheusLogger(CustomLogger): buckets=self.latency_buckets, ) + self.litellm_overhead_with_guardrails_latency_metric = self._histogram_factory( + "litellm_overhead_with_guardrails_latency_metric", + "Total internal latency (seconds) added by LiteLLM, including " + "pre/post-call guardrails (excludes the LLM API call)", + labelnames=self.get_labels_for_metric("litellm_overhead_with_guardrails_latency_metric"), + buckets=self.latency_buckets, + ) + # Request queue time metric self.litellm_request_queue_time_metric = self._histogram_factory( "litellm_request_queue_time_seconds", @@ -579,6 +614,21 @@ class PrometheusLogger(CustomLogger): labelnames=[], ) + ######################################## + # MCP Tool Call Metrics + ######################################## + self.litellm_mcp_tool_calls_total = self._counter_factory( + name="litellm_mcp_tool_calls_total", + documentation="Total MCP tool calls, segmented by tool and server name", + labelnames=self.get_labels_for_metric("litellm_mcp_tool_calls_total"), + ) + + self.litellm_mcp_tool_call_spend_metric = self._counter_factory( + name="litellm_mcp_tool_call_spend_metric", + documentation="Total spend on MCP tool calls, segmented by tool and server name", + labelnames=self.get_labels_for_metric("litellm_mcp_tool_call_spend_metric"), + ) + except Exception as e: print_verbose(f"Got exception on init prometheus client {str(e)}") raise e @@ -1001,6 +1051,67 @@ class PrometheusLogger(CustomLogger): self._cached_metric_labels[metric_name] = filtered_labels return filtered_labels + @staticmethod + def _guardrail_is_additive(info: StandardLoggingGuardrailInformation) -> bool: + mode = info.get("guardrail_mode") + modes = mode if isinstance(mode, list) else [mode] + mode_values = frozenset( + m.value if isinstance(m, GuardrailEventHooks) else m for m in modes if isinstance(m, str) + ) + return bool(mode_values) and mode_values <= PrometheusLogger._ADDITIVE_GUARDRAIL_MODES + + @staticmethod + def _get_guardrail_overhead_seconds( + standard_logging_payload: StandardLoggingPayload, + ) -> float: + """Seconds of additive guardrail time (pre/post-call only) on the payload. + + during_call guardrails run concurrently with the LLM call, so their + wall-clock overlaps the provider call and is not additive overhead; + logging_only and MCP modes never block the user-facing response. A + guardrail counts only when every mode it carries is pre/post-call, so a + mixed list such as ["pre_call", "during_call"] is excluded. + + guardrail_information is typed as a list, but some guardrails assign a + single dict directly, so normalize that shape to a one-item list. + """ + guardrail_information = standard_logging_payload.get("guardrail_information") + entries: list[StandardLoggingGuardrailInformation] = ( + [cast("StandardLoggingGuardrailInformation", guardrail_information)] + if isinstance(guardrail_information, dict) + else guardrail_information or [] + ) + return sum( + (float(info.get("duration") or 0.0) for info in entries if PrometheusLogger._guardrail_is_additive(info)), + 0.0, + ) + + def _set_overhead_with_guardrails_metric( + self, + standard_logging_payload: StandardLoggingPayload, + enum_values: UserAPIKeyLabelValues, + label_context: Optional[PrometheusLabelFactoryContext] = None, + ) -> None: + """Record litellm_overhead_with_guardrails_latency_metric (seconds): SDK overhead + + pre/post-call guardrail time. Recorded outside the SDK-overhead gate so + guardrail-only overhead is still captured when litellm_overhead_time_ms + is 0 or absent. + """ + litellm_overhead_time_ms = standard_logging_payload["hidden_params"].get("litellm_overhead_time_ms") + guardrail_overhead_seconds = self._get_guardrail_overhead_seconds(standard_logging_payload) + if litellm_overhead_time_ms is None and guardrail_overhead_seconds <= 0: + return + labels = prometheus_label_factory( + supported_enum_labels=self.get_labels_for_metric( + metric_name="litellm_overhead_with_guardrails_latency_metric" + ), + enum_values=enum_values, + label_context=label_context, + ) + self.litellm_overhead_with_guardrails_latency_metric.labels(**labels).observe( + ((litellm_overhead_time_ms or 0.0) / 1000) + guardrail_overhead_seconds + ) + def _track_end_user_metric_series( self, metric: Any, @@ -1225,6 +1336,13 @@ class PrometheusLogger(CustomLogger): label_context=label_context, ) + # MCP tool call metrics + self._increment_mcp_tool_call_metrics( + standard_logging_payload=standard_logging_payload, + enum_values=enum_values, + response_cost=response_cost, + ) + # increment litellm_proxy_total_requests_metric for all successful requests # (both streaming and non-streaming) in this single location to prevent # double-counting that occurs when async_post_call_success_hook also increments @@ -1446,6 +1564,49 @@ class PrometheusLogger(CustomLogger): amount=float(provider_cache_creation_tokens), ) + def _increment_mcp_tool_call_metrics( + self, + standard_logging_payload: StandardLoggingPayload, + enum_values: UserAPIKeyLabelValues, + response_cost: float, + ) -> None: + metadata = standard_logging_payload.get("metadata") + if not isinstance(metadata, dict): + return + mcp_meta = metadata.get("mcp_tool_call_metadata") + if not isinstance(mcp_meta, dict): + return + + mcp_enum_values = UserAPIKeyLabelValues( + mcp_tool_name=mcp_meta.get("name"), + mcp_server_name=mcp_meta.get("mcp_server_name"), + hashed_api_key=enum_values.hashed_api_key, + api_key_alias=enum_values.api_key_alias, + team=enum_values.team, + team_alias=enum_values.team_alias, + user=enum_values.user, + end_user=enum_values.end_user, + ) + mcp_label_context = PrometheusLabelFactoryContext(mcp_enum_values) + + PrometheusLogger._inc_labeled_counter( + self, + self.litellm_mcp_tool_calls_total, + "litellm_mcp_tool_calls_total", + mcp_enum_values, + label_context=mcp_label_context, + ) + + if response_cost > 0: + PrometheusLogger._inc_labeled_counter( + self, + self.litellm_mcp_tool_call_spend_metric, + "litellm_mcp_tool_call_spend_metric", + mcp_enum_values, + label_context=mcp_label_context, + amount=response_cost, + ) + async def _increment_remaining_budget_metrics( self, user_api_team: Optional[str], @@ -1467,7 +1628,15 @@ class PrometheusLogger(CustomLogger): _user_spend = _metadata.get("user_api_key_user_spend", None) _user_max_budget = _metadata.get("user_api_key_user_max_budget", None) - results = await asyncio.gather( + # Bound the per-request budget-metric emission so that slow Redis/DB + # lookups under load cannot consume the whole LoggingWorker watchdog + # (LOGGING_WORKER_MAX_TIME_PER_COROUTINE, default 20s) and get the entire + # success-logging event cancelled. Budget gauges are also refreshed by the + # periodic cron every PROMETHEUS_BUDGET_METRICS_REFRESH_INTERVAL_MINUTES, + # so dropping one slow per-request emission only loses sub-cron real-time + # detail, not correctness. + budget_metrics_timeout = _get_budget_metrics_per_request_timeout() + gather_coro = asyncio.gather( self._set_api_key_budget_metrics_after_api_request( user_api_key=user_api_key, user_api_key_alias=user_api_key_alias, @@ -1494,6 +1663,16 @@ class PrometheusLogger(CustomLogger): ), return_exceptions=True, ) + try: + results = await asyncio.wait_for(gather_coro, timeout=budget_metrics_timeout) + except asyncio.TimeoutError: + verbose_logger.debug( + "[Non-Blocking] Prometheus: per-request budget metric emission " + "exceeded %ss under load; skipping (values are refreshed by the " + "periodic budget-metrics cron job).", + budget_metrics_timeout, + ) + return for i, r in enumerate(results): if isinstance(r, Exception): verbose_logger.debug( @@ -1864,6 +2043,43 @@ class PrometheusLogger(CustomLogger): return False + @staticmethod + def _extract_api_provider_from_request_data(request_data: dict) -> Optional[str]: + """ + Best-effort provider for the client-side failure path. + + A request can fail before a deployment is resolved, so the provider is + not always known. Prefer the resolved ``custom_llm_provider`` on + ``litellm_params``, then any provider recovered onto a partial + ``standard_logging_object`` (e.g. a stream that broke mid-flight), and + finally infer it from the requested model name (e.g. ``gpt-4o-mini`` -> + ``openai``) since the proxy's failure ``request_data`` usually carries + only the client-supplied model. Return ``None`` when it cannot be + determined so the label emits empty rather than a guess. + """ + litellm_params = request_data.get("litellm_params") or {} + provider = litellm_params.get("custom_llm_provider") + if provider: + return provider + standard_logging_object = request_data.get("standard_logging_object") or {} + provider = standard_logging_object.get("custom_llm_provider") + if provider: + return provider + model = litellm_params.get("model") or request_data.get("model") + if not model: + return None + try: + return litellm.get_llm_provider(model=model)[1] or None + except litellm.exceptions.BadRequestError: + return None + except Exception as e: # noqa: BLE001 - metrics labeling must never break request/failure handling + verbose_logger.debug( + "prometheus: unexpected error inferring api_provider from model=%s: %s", + model, + e, + ) + return None + async def async_post_call_failure_hook( self, request_data: dict, @@ -1899,6 +2115,7 @@ class PrometheusLogger(CustomLogger): _metadata = request_data.get("metadata", {}) or {} model_id = _metadata.get("model_info", {}).get("id") or request_data.get("model_info", {}).get("id") rate_limit_category, rate_limit_type = self._extract_rate_limit_labels(original_exception) + api_provider = self._extract_api_provider_from_request_data(request_data) enum_values = UserAPIKeyLabelValues( end_user=user_api_key_dict.end_user_id, user=user_api_key_dict.user_id, @@ -1920,6 +2137,7 @@ class PrometheusLogger(CustomLogger): client_ip=_metadata.get("requester_ip_address"), user_agent=_metadata.get("user_agent"), model_id=model_id, + api_provider=api_provider, stream=(str(request_data.get("stream")) if litellm.prometheus_emit_stream_label else None), ) _label_ctx = PrometheusLabelFactoryContext(enum_values) @@ -2346,6 +2564,12 @@ class PrometheusLogger(CustomLogger): litellm_overhead_time_ms / 1000 ) # set as seconds + self._set_overhead_with_guardrails_metric( + standard_logging_payload=standard_logging_payload, + enum_values=enum_values, + label_context=label_context, + ) + if remaining_requests: """ "model_group", @@ -3395,6 +3619,7 @@ class PrometheusLogger(CustomLogger): hashed_token=user_api_key_dict.token, prisma_client=prisma_client, user_api_key_cache=user_api_key_cache, + check_cache_only=True, ) if key_object: user_api_key_dict.budget_reset_at = key_object.budget_reset_at @@ -3723,6 +3948,10 @@ def _get_combined_custom_metadata_from_standard_logging_payload( ) -> Dict[str, Any]: """ Combine the metadata sources that can supply custom Prometheus labels. + + Includes top-level scalar fields from the standard logging metadata (e.g. + user_api_key_project_alias, user_api_key_team_alias) so they are accessible + via custom_prometheus_metadata_labels configuration. """ if not isinstance(standard_logging_payload, dict): return {} @@ -3736,6 +3965,7 @@ def _get_combined_custom_metadata_from_standard_logging_payload( spend_logs_metadata = standard_logging_metadata.get("spend_logs_metadata") return { + **{k: v for k, v in standard_logging_metadata.items() if not isinstance(v, dict)}, **(requester_metadata if isinstance(requester_metadata, dict) else {}), **(user_api_key_auth_metadata if isinstance(user_api_key_auth_metadata, dict) else {}), **(spend_logs_metadata if isinstance(spend_logs_metadata, dict) else {}), diff --git a/litellm/integrations/s3_v2.py b/litellm/integrations/s3_v2.py index 939289f96ea..5b953035cfd 100644 --- a/litellm/integrations/s3_v2.py +++ b/litellm/integrations/s3_v2.py @@ -54,6 +54,7 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM): s3_strip_base64_files: bool = False, s3_use_key_prefix: bool = False, s3_use_virtual_hosted_style: bool = False, + s3_server_side_encryption: Optional[str] = None, s3_callback_params_override: Optional[dict] = None, **kwargs, ): @@ -92,6 +93,7 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM): s3_strip_base64_files=s3_strip_base64_files, s3_use_key_prefix=s3_use_key_prefix, s3_use_virtual_hosted_style=s3_use_virtual_hosted_style, + s3_server_side_encryption=s3_server_side_encryption, ) verbose_logger.debug(f"s3 logger using endpoint url {s3_endpoint_url}") @@ -145,6 +147,7 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM): s3_strip_base64_files: bool = False, s3_use_key_prefix: bool = False, s3_use_virtual_hosted_style: bool = False, + s3_server_side_encryption: Optional[str] = None, params_source: Optional[dict] = None, ): """ @@ -194,6 +197,8 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM): bool(params.get("s3_use_virtual_hosted_style", False)) or s3_use_virtual_hosted_style ) + self.s3_server_side_encryption = params.get("s3_server_side_encryption") or s3_server_side_encryption + return async def async_log_success_event(self, kwargs, response_obj, start_time, end_time): @@ -273,6 +278,7 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM): async def async_upload_data_to_s3(self, batch_logging_element: s3BatchLoggingElement): try: + import base64 import hashlib import requests @@ -317,14 +323,23 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM): # Calculate SHA256 hash of the content content_hash = hashlib.sha256(json_string.encode("utf-8")).hexdigest() + content_md5 = base64.b64encode( + hashlib.md5(json_string.encode("utf-8"), usedforsecurity=False).digest() + ).decode() # Prepare the request headers = { "Content-Type": "application/json", + "Content-MD5": content_md5, "x-amz-content-sha256": content_hash, "Content-Language": "en", "Content-Disposition": f'inline; filename="{batch_logging_element.s3_object_download_filename}"', "Cache-Control": "private, immutable, max-age=31536000, s-maxage=0", + **( + {"x-amz-server-side-encryption": self.s3_server_side_encryption} + if self.s3_server_side_encryption + else {} + ), } req = requests.Request("PUT", url, data=json_string, headers=headers) prepped = req.prepare() @@ -447,6 +462,7 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM): def upload_data_to_s3(self, batch_logging_element: s3BatchLoggingElement): try: + import base64 import hashlib import requests @@ -482,14 +498,23 @@ class S3Logger(CustomBatchLogger, BaseAWSLLM): # Calculate SHA256 hash of the content content_hash = hashlib.sha256(json_string.encode("utf-8")).hexdigest() + content_md5 = base64.b64encode( + hashlib.md5(json_string.encode("utf-8"), usedforsecurity=False).digest() + ).decode() # Prepare the request headers = { "Content-Type": "application/json", + "Content-MD5": content_md5, "x-amz-content-sha256": content_hash, "Content-Language": "en", "Content-Disposition": f'inline; filename="{batch_logging_element.s3_object_download_filename}"', "Cache-Control": "private, immutable, max-age=31536000, s-maxage=0", + **( + {"x-amz-server-side-encryption": self.s3_server_side_encryption} + if self.s3_server_side_encryption + else {} + ), } req = requests.Request("PUT", url, data=json_string, headers=headers) prepped = req.prepare() diff --git a/litellm/integrations/websearch_interception/handler.py b/litellm/integrations/websearch_interception/handler.py index 2e11405af3f..00c67e9f0fb 100644 --- a/litellm/integrations/websearch_interception/handler.py +++ b/litellm/integrations/websearch_interception/handler.py @@ -31,6 +31,7 @@ from litellm.types.integrations.websearch_interception import ( WebSearchInterceptionConfig, ) from litellm.types.integrations.custom_logger import ( + CHAT_COMPLETION_AGENTIC_SURFACE, AgenticLoopPlan, AgenticLoopRequestPatch, ) @@ -90,6 +91,7 @@ class WebSearchInterceptionLogger(CustomLogger): messages: List[Dict], tools: Optional[List[Dict]], custom_llm_provider: Optional[str], + kwargs: Optional[dict[str, Any]] = None, ) -> Optional[Dict[str, Any]]: """ Short-circuit web-search-only requests by executing the search directly. @@ -119,21 +121,26 @@ class WebSearchInterceptionLogger(CustomLogger): if self.enabled_providers is not None and provider_str not in self.enabled_providers: return None - # Only short-circuit for providers without native Anthropic Messages - # support. Providers that have a BaseAnthropicMessagesConfig (bedrock, - # vertex_ai, azure_ai, anthropic) already use the agentic loop, which - # includes a follow-up LLM call to synthesize the answer from search - # results. Short-circuiting those would skip that synthesis step and - # return raw search text — a regression for existing users. + # Only short-circuit for providers whose Anthropic Messages agentic loop + # does not run web_search itself. Providers that have a + # BaseAnthropicMessagesConfig which handles web search natively (bedrock, + # vertex_ai, azure_ai, anthropic) already perform the search plus a + # follow-up LLM synthesis step; short-circuiting those would skip that + # synthesis and return raw search text — a regression for existing users. + # + # github_copilot has a BaseAnthropicMessagesConfig (added for thinking + # passthrough) but does not handle web_search natively, so its config + # returns handles_web_search_natively() == False and we still short-circuit + # web-search-only requests against it. try: provider_enum = LlmProviders(provider_str) anthropic_config = ProviderConfigManager.get_provider_anthropic_messages_config( model=model, provider=provider_enum ) - if anthropic_config is not None: + if anthropic_config is not None and anthropic_config.handles_web_search_natively(): verbose_logger.debug( f"WebSearchInterception: Skipping short-circuit for {provider_str} " - "(provider has native Anthropic Messages support, using agentic loop)" + "(provider handles web search natively via the agentic loop)" ) return None except (ValueError, Exception): @@ -170,7 +177,10 @@ class WebSearchInterceptionLogger(CustomLogger): # Execute search — keep the structured SearchResponse so the native # block can carry per-result url/title/page_age. try: - search_result_text, structured = await self._execute_search(query) + if kwargs is None: + search_result_text, structured = await self._execute_search(query) + else: + search_result_text, structured = await self._execute_search(query, kwargs=kwargs) except Exception as e: verbose_logger.error(f"WebSearchInterception: Short-circuit search failed: {e}") search_result_text, structured = f"Search failed: {e}", None @@ -440,12 +450,16 @@ class WebSearchInterceptionLogger(CustomLogger): custom_llm_provider: str, kwargs: Dict, ) -> Tuple[bool, Dict]: - """ - Check if WebSearch tool interception is needed for Anthropic Messages API. - - This is the legacy method for Anthropic-style responses. - For chat completions, use async_should_run_chat_completion_agentic_loop instead. - """ + if kwargs.get("_agentic_loop_api_surface") == CHAT_COMPLETION_AGENTIC_SURFACE: + return await self.async_should_run_chat_completion_agentic_loop( + response=response, + model=model, + messages=messages, + tools=tools, + stream=stream, + custom_llm_provider=custom_llm_provider, + kwargs=kwargs, + ) verbose_logger.debug(f"WebSearchInterception: Hook called! provider={custom_llm_provider}, stream={stream}") verbose_logger.debug(f"WebSearchInterception: Response type: {type(response)}") @@ -629,6 +643,18 @@ class WebSearchInterceptionLogger(CustomLogger): stream: bool, kwargs: Dict, ) -> AgenticLoopPlan: + if kwargs.get("_agentic_loop_api_surface") == CHAT_COMPLETION_AGENTIC_SURFACE: + return await self.async_build_chat_completion_agentic_loop_plan( + tools=tools, + model=model, + messages=messages, + response=response, + optional_params=anthropic_messages_optional_request_params, + logging_obj=logging_obj, + stream=stream, + kwargs=kwargs, + ) + tool_calls = tools["tool_calls"] thinking_blocks = tools.get("thinking_blocks", []) request_patch, structured_results = await self._build_anthropic_request_patch( @@ -914,7 +940,7 @@ class WebSearchInterceptionLogger(CustomLogger): query = tool_call["input"].get("query") if query: verbose_logger.debug(f"WebSearchInterception: Queuing search for query='{query}'") - search_tasks.append(self._execute_search(query)) + search_tasks.append(self._execute_search(query, kwargs=kwargs)) else: verbose_logger.debug(f"WebSearchInterception: Tool call {tool_call['id']} has no query") # Add empty result for tools without query @@ -987,7 +1013,9 @@ class WebSearchInterceptionLogger(CustomLogger): ) return patch, structured_results - async def _execute_search(self, query: str) -> Tuple[str, Optional[SearchResponse]]: + async def _execute_search( + self, query: str, kwargs: Optional[dict[str, Any]] = None + ) -> Tuple[str, Optional[SearchResponse]]: """ Execute a single web search using router's search tools. @@ -1009,36 +1037,13 @@ class WebSearchInterceptionLogger(CustomLogger): ) llm_router = None - # Determine search provider from router's search_tools + search_tool = self._select_search_tool_from_router(llm_router=llm_router) search_provider: Optional[str] = None - if llm_router is not None and hasattr(llm_router, "search_tools"): - if self.search_tool_name: - # Find specific search tool by name - matching_tools = [ - tool - for tool in llm_router.search_tools - if tool.get("search_tool_name") == self.search_tool_name - ] - if matching_tools: - search_tool = matching_tools[0] - search_provider = search_tool.get("litellm_params", {}).get("search_provider") - verbose_logger.debug( - f"WebSearchInterception: Found search tool '{self.search_tool_name}' " - f"with provider '{search_provider}'" - ) - else: - verbose_logger.debug( - f"WebSearchInterception: Search tool '{self.search_tool_name}' not found in router, " - "falling back to first available or perplexity" - ) - - # If no specific tool or not found, use first available - if not search_provider and llm_router.search_tools: - first_tool = llm_router.search_tools[0] - search_provider = first_tool.get("litellm_params", {}).get("search_provider") - verbose_logger.debug( - f"WebSearchInterception: Using first available search tool with provider '{search_provider}'" - ) + search_litellm_params: dict[str, Any] = {} + if search_tool is not None: + await self._authorize_search_tool(search_tool=search_tool, kwargs=kwargs) + search_litellm_params = dict(search_tool.get("litellm_params", {}) or {}) + search_provider = search_litellm_params.get("search_provider") # Fallback to perplexity if no router or no search tools configured if not search_provider: @@ -1051,7 +1056,12 @@ class WebSearchInterceptionLogger(CustomLogger): verbose_logger.debug( f"WebSearchInterception: Executing search for '{query}' using provider '{search_provider}'" ) - result = await litellm.asearch(query=query, search_provider=search_provider) + search_kwargs = { + key: value + for key, value in search_litellm_params.items() + if key != "search_provider" and value is not None + } + result = await litellm.asearch(query=query, search_provider=search_provider, **search_kwargs) # Format using transformation function search_result_text = WebSearchTransformation.format_search_response(result) @@ -1064,6 +1074,107 @@ class WebSearchInterceptionLogger(CustomLogger): verbose_logger.error(f"WebSearchInterception: Search failed for '{query}': {str(e)}") raise + async def _authorize_search_tool( + self, + search_tool: dict[str, Any], + kwargs: Optional[dict[str, Any]], + ) -> None: + search_tool_name = search_tool.get("search_tool_name") + if not isinstance(search_tool_name, str) or not search_tool_name: + return + + user_api_key_auth = self._get_user_api_key_auth_from_kwargs(kwargs) + if user_api_key_auth is None: + return + + from litellm.proxy.auth.auth_checks import ( + can_key_call_search_tool, + can_team_call_search_tool, + get_team_object, + ) + + await can_key_call_search_tool( + search_tool_name=search_tool_name, + valid_token=user_api_key_auth, + ) + + team_id = getattr(user_api_key_auth, "team_id", None) + if team_id: + from litellm.proxy.proxy_server import ( + prisma_client, + proxy_logging_obj, + user_api_key_cache, + ) + + team_object = await get_team_object( + team_id=team_id, + prisma_client=prisma_client, + user_api_key_cache=user_api_key_cache, + parent_otel_span=getattr(user_api_key_auth, "parent_otel_span", None), + proxy_logging_obj=proxy_logging_obj, + ) + await can_team_call_search_tool( + search_tool_name=search_tool_name, + team_object=team_object, + ) + + @staticmethod + def _get_user_api_key_auth_from_kwargs(kwargs: Optional[dict[str, Any]]) -> Any: + if not kwargs: + return None + + for metadata_key in ("metadata", "litellm_metadata"): + metadata = kwargs.get(metadata_key) + if isinstance(metadata, dict) and metadata.get("user_api_key_auth") is not None: + return metadata["user_api_key_auth"] + + litellm_params = kwargs.get("litellm_params") + if not isinstance(litellm_params, dict): + return None + + for metadata_key in ("metadata", "litellm_metadata"): + metadata = litellm_params.get(metadata_key) + if isinstance(metadata, dict) and metadata.get("user_api_key_auth") is not None: + return metadata["user_api_key_auth"] + + return None + + def _select_search_tool_from_router(self, llm_router: Any) -> Optional[dict[str, Any]]: + if llm_router is None or not hasattr(llm_router, "search_tools"): + return None + search_tools = list(getattr(llm_router, "search_tools") or []) + return self._select_search_tool_from_list(search_tools=search_tools, source="router") + + def _select_search_tool_from_list( + self, + search_tools: list[dict[str, Any]], + source: str, + ) -> Optional[dict[str, Any]]: + if self.search_tool_name: + matching_tools = [tool for tool in search_tools if tool.get("search_tool_name") == self.search_tool_name] + if matching_tools: + search_provider = (matching_tools[0].get("litellm_params", {}) or {}).get("search_provider") + verbose_logger.debug( + f"WebSearchInterception: Found search tool '{self.search_tool_name}' " + f"from {source} with provider '{search_provider}'" + ) + return matching_tools[0] + verbose_logger.debug( + f"WebSearchInterception: Search tool '{self.search_tool_name}' not found in {source}, " + "falling back to first available or perplexity" + ) + + if search_tools: + first_tool = search_tools[0] + search_provider = (first_tool.get("litellm_params", {}) or {}).get("search_provider") + verbose_logger.debug( + f"WebSearchInterception: Using first available search tool from {source} " + f"with provider '{search_provider}'" + ) + return first_tool + + return None + async def _execute_chat_completion_agentic_loop( self, model: str, @@ -1088,6 +1199,7 @@ class WebSearchInterceptionLogger(CustomLogger): raise ValueError("WebSearchInterception: missing follow-up messages") params = dict(optional_params) params.update(request_patch.optional_params) + params.pop("tool_choice", None) return await litellm.acompletion( model=request_patch.model or model, messages=request_patch.messages, @@ -1122,7 +1234,7 @@ class WebSearchInterceptionLogger(CustomLogger): if query: verbose_logger.debug(f"WebSearchInterception: Queuing search for query='{query}'") - search_tasks.append(self._execute_search(query)) + search_tasks.append(self._execute_search(query, kwargs=kwargs)) else: verbose_logger.debug(f"WebSearchInterception: Tool call {tool_call.get('id')} has no query") # Add empty result for tools without query @@ -1203,6 +1315,7 @@ class WebSearchInterceptionLogger(CustomLogger): if k not in { "tools", + "tool_choice", "extra_body", "model_alias_map", "stream_response", diff --git a/litellm/interactions/streaming_iterator.py b/litellm/interactions/streaming_iterator.py index 45c5443cfd2..0d9d1b4579c 100644 --- a/litellm/interactions/streaming_iterator.py +++ b/litellm/interactions/streaming_iterator.py @@ -174,22 +174,15 @@ class InteractionsAPIStreamingIterator(BaseInteractionsAPIStreamingIterator): logging_response = copy.deepcopy(self.completed_response) asyncio.create_task( - self.logging_obj.async_success_handler( - result=logging_response, + self.logging_obj.dispatch_success_handlers( + logging_response, start_time=self.start_time, end_time=datetime.now(), cache_hit=None, + prefer_async_handlers=True, ) ) - executor.submit( - self.logging_obj.success_handler, - result=logging_response, - cache_hit=None, - start_time=self.start_time, - end_time=datetime.now(), - ) - class SyncInteractionsAPIStreamingIterator(BaseInteractionsAPIStreamingIterator): """ diff --git a/litellm/litellm_core_utils/audio_utils/utils.py b/litellm/litellm_core_utils/audio_utils/utils.py index f86243c73b7..e5007ceec34 100644 --- a/litellm/litellm_core_utils/audio_utils/utils.py +++ b/litellm/litellm_core_utils/audio_utils/utils.py @@ -123,6 +123,34 @@ def process_audio_file(audio_file: FileTypes) -> ProcessedAudioFile: return ProcessedAudioFile(file_content=file_content, filename=filename, content_type=content_type) +BARE_ISO_639_1_TO_BCP47 = { + "en": "en-US", + "es": "es-ES", + "de": "de-DE", + "fr": "fr-FR", + "it": "it-IT", + "pt": "pt-BR", + "ja": "ja-JP", + "ko": "ko-KR", + "zh": "zh-CN", + "ru": "ru-RU", + "hi": "hi-IN", + "ar": "ar-SA", +} + + +def normalize_transcription_language_to_bcp47(language: str) -> str: + """ + OpenAI's transcription `language` param accepts bare ISO-639-1 codes like + ``en``; speech APIs such as Google Speech-to-Text and NVIDIA Riva require + BCP-47 like ``en-US``. Map the most common bare codes and pass through + anything already region-qualified (or unknown, for a clear provider error). + """ + if "-" in language: + return language + return BARE_ISO_639_1_TO_BCP47.get(language.lower(), language) + + def get_audio_file_name(file_obj: FileTypes) -> str: """ Safely get the name of a file-like object or return its string representation. diff --git a/litellm/litellm_core_utils/chat_completion_agentic_loop.py b/litellm/litellm_core_utils/chat_completion_agentic_loop.py index 828605d5ef8..b7262a42324 100644 --- a/litellm/litellm_core_utils/chat_completion_agentic_loop.py +++ b/litellm/litellm_core_utils/chat_completion_agentic_loop.py @@ -137,8 +137,8 @@ async def _execute_chat_completion_agentic_plan( optional_params_for_followup = {**optional_params, **patch.optional_params} if patch.tools is not None: optional_params_for_followup["tools"] = patch.tools - if "tool_choice" not in patch.optional_params: - optional_params_for_followup.pop("tool_choice", None) + if "tool_choice" not in patch.optional_params: + optional_params_for_followup.pop("tool_choice", None) kwargs_for_followup = _filter_followup_kwargs(kwargs) kwargs_for_followup.update( @@ -206,10 +206,11 @@ async def maybe_run_chat_completion_agentic_loop( for callback in callbacks: if not isinstance(callback, CustomLogger): continue + if not _gate_overridden(callback): continue - gate_kwargs = { + hook_kwargs = { **kwargs, "_agentic_loop_api_surface": CHAT_COMPLETION_AGENTIC_SURFACE, "custom_llm_provider": custom_llm_provider, @@ -222,7 +223,7 @@ async def maybe_run_chat_completion_agentic_loop( tools=tools, stream=stream, custom_llm_provider=custom_llm_provider, - kwargs=gate_kwargs, + kwargs=hook_kwargs, ) except Exception as e: verbose_logger.exception( @@ -243,11 +244,6 @@ async def maybe_run_chat_completion_agentic_loop( ) try: - plan_kwargs = { - **kwargs, - "_agentic_loop_api_surface": CHAT_COMPLETION_AGENTIC_SURFACE, - "custom_llm_provider": custom_llm_provider, - } if not _build_plan_overridden(callback): return await callback.async_run_agentic_loop( tools=tool_calls, @@ -258,7 +254,7 @@ async def maybe_run_chat_completion_agentic_loop( anthropic_messages_optional_request_params=optional_params, logging_obj=logging_obj, stream=stream, - kwargs=plan_kwargs, + kwargs=hook_kwargs, ) plan = await callback.async_build_agentic_loop_plan( @@ -270,7 +266,7 @@ async def maybe_run_chat_completion_agentic_loop( anthropic_messages_optional_request_params=optional_params, logging_obj=logging_obj, stream=stream, - kwargs=plan_kwargs, + kwargs=hook_kwargs, ) if plan.response_override is not None: diff --git a/litellm/litellm_core_utils/exception_mapping_utils.py b/litellm/litellm_core_utils/exception_mapping_utils.py index 2441cbb3903..fdab3d5b9d4 100644 --- a/litellm/litellm_core_utils/exception_mapping_utils.py +++ b/litellm/litellm_core_utils/exception_mapping_utils.py @@ -95,6 +95,9 @@ class ExceptionCheckers: if "current length is" in _error_str_lowercase and "while limit is" in _error_str_lowercase: return True + if "maximum input length is" in _error_str_lowercase and "tokens" in _error_str_lowercase: + return True + return False @staticmethod @@ -1944,7 +1947,7 @@ def _map_azure_exception( response=getattr(original_exception, "response", None), body=getattr(original_exception, "body", None), ) - elif "invalid_request_error" in error_str: + elif "invalid_request_error" in error_str and getattr(original_exception, "status_code", None) in (None, 400): raise BadRequestError( message=f"AzureException BadRequestError - {message}", llm_provider="azure", @@ -1986,6 +1989,14 @@ def _map_azure_exception( litellm_debug_info=extra_information, response=getattr(original_exception, "response", None), ) + elif original_exception.status_code == 404: + raise NotFoundError( + message=f"AzureException NotFoundError - {message}", + llm_provider="azure", + model=model, + litellm_debug_info=extra_information, + response=getattr(original_exception, "response", None), + ) elif original_exception.status_code == 408: raise Timeout( message=f"AzureException Timeout - {message}", @@ -2173,7 +2184,7 @@ def exception_type( # type: ignore litellm_response_headers = _get_response_headers(original_exception=original_exception) try: error_str = redact_string(str(original_exception)) if _ENABLE_SECRET_REDACTION else str(original_exception) - if model: + if model or custom_llm_provider: if hasattr(original_exception, "message"): error_str = ( redact_string(str(original_exception.message)) diff --git a/litellm/litellm_core_utils/get_litellm_params.py b/litellm/litellm_core_utils/get_litellm_params.py index fbed9594a0b..352e55e9c23 100644 --- a/litellm/litellm_core_utils/get_litellm_params.py +++ b/litellm/litellm_core_utils/get_litellm_params.py @@ -36,6 +36,8 @@ OPTIONAL_KWARGS_KEYS = frozenset( "aws_bedrock_project_id", "tpm", "rpm", + "itpm", + "otpm", "use_xai_oauth", } ) @@ -74,6 +76,7 @@ def get_litellm_params( proxy_server_request=None, acompletion=None, aembedding=None, + allm_passthrough_route=None, preset_cache_key=None, no_log=None, input_cost_per_second=None, @@ -116,6 +119,7 @@ def get_litellm_params( # Build base dict with explicit parameters (always included) litellm_params = { "acompletion": acompletion, + "allm_passthrough_route": allm_passthrough_route, "api_key": api_key, "force_timeout": force_timeout, "logger_fn": logger_fn, diff --git a/litellm/litellm_core_utils/get_llm_provider_logic.py b/litellm/litellm_core_utils/get_llm_provider_logic.py index 122d09c855b..fa8ffe1ba1d 100644 --- a/litellm/litellm_core_utils/get_llm_provider_logic.py +++ b/litellm/litellm_core_utils/get_llm_provider_logic.py @@ -346,6 +346,9 @@ def get_llm_provider( elif endpoint == "https://pinstripes.io/v1": custom_llm_provider = "pinstripes" dynamic_api_key = get_secret_str("PINSTRIPES_API_KEY") + elif endpoint == "https://api.meta.ai/v1": + custom_llm_provider = "meta" + dynamic_api_key = get_secret_str("META_API_KEY") if api_base is not None and not isinstance(api_base, str): raise Exception("api base needs to be a string. api_base={}".format(api_base)) @@ -446,6 +449,8 @@ def get_llm_provider( # bytez models elif model.startswith("bytez/"): custom_llm_provider = "bytez" + elif model.startswith("gdc/"): + custom_llm_provider = "gdc" elif model.startswith("lemonade/"): custom_llm_provider = "lemonade" elif model.startswith("heroku/"): @@ -650,6 +655,10 @@ def _get_openai_compatible_provider_info( api_base = api_base or get_secret("DEEPSEEK_API_BASE") or "https://api.deepseek.com/beta" # type: ignore dynamic_api_key = api_key or get_secret_str("DEEPSEEK_API_KEY") + elif custom_llm_provider == "tencent": + api_base = api_base or get_secret("TENCENT_API_BASE") or "https://tokenhub-intl.tencentcloudmaas.com/v1" + + dynamic_api_key = api_key or get_secret_str("TENCENT_API_KEY") elif custom_llm_provider == "fireworks_ai": # fireworks is openai compatible, we just need to set this to custom_openai and have the api_base be https://api.fireworks.ai/inference/v1 ( diff --git a/litellm/litellm_core_utils/get_supported_openai_params.py b/litellm/litellm_core_utils/get_supported_openai_params.py index c4ddb4b7ee0..19149da0316 100644 --- a/litellm/litellm_core_utils/get_supported_openai_params.py +++ b/litellm/litellm_core_utils/get_supported_openai_params.py @@ -106,6 +106,8 @@ def get_supported_openai_params( return litellm.VLLMConfig().get_supported_openai_params(model=model) elif custom_llm_provider == "deepseek": return litellm.DeepSeekChatConfig().get_supported_openai_params(model=model) + elif custom_llm_provider == "tencent": + return litellm.TencentChatConfig().get_supported_openai_params(model=model) elif custom_llm_provider == "cohere_chat" or custom_llm_provider == "cohere": return litellm.CohereChatConfig().get_supported_openai_params(model=model) elif custom_llm_provider == "maritalk": diff --git a/litellm/litellm_core_utils/health_check_helpers.py b/litellm/litellm_core_utils/health_check_helpers.py index 405366382a1..9fc036e2a99 100644 --- a/litellm/litellm_core_utils/health_check_helpers.py +++ b/litellm/litellm_core_utils/health_check_helpers.py @@ -95,6 +95,17 @@ class HealthCheckHelpers: """ import litellm + logging_obj = filtered_model_params.get("litellm_logging_obj") + if logging_obj is not None: + api_base = filtered_model_params.get("api_base") + logging_obj.update_from_kwargs( + kwargs=filtered_model_params, + model=filtered_model_params.get("model"), + user=None, + optional_params={}, + litellm_params={"api_base": api_base} if api_base else None, + ) + if custom_llm_provider in LIST_BATCHES_SUPPORTED_PROVIDERS: return await litellm.alist_batches(**filtered_model_params) else: @@ -188,6 +199,7 @@ class HealthCheckHelpers: api_base=model_params.get("api_base", None), api_key=model_params.get("api_key", None), api_version=model_params.get("api_version", None), + model_params=model_params, ), "batch": lambda: HealthCheckHelpers._batch_health_check( custom_llm_provider=custom_llm_provider, diff --git a/litellm/litellm_core_utils/initialize_dynamic_callback_params.py b/litellm/litellm_core_utils/initialize_dynamic_callback_params.py index d0a6ec30c9e..06a9e98c5ac 100644 --- a/litellm/litellm_core_utils/initialize_dynamic_callback_params.py +++ b/litellm/litellm_core_utils/initialize_dynamic_callback_params.py @@ -1,7 +1,23 @@ -from typing import Dict, Optional +from typing import Any, Dict, Iterator, Optional from litellm.types.utils import StandardCallbackDynamicParams +_CLIENT_CALLBACK_METADATA_SLOTS: tuple[str, ...] = ("litellm_metadata", "metadata") + + +def iter_client_callback_metadata_dicts( + kwargs: dict[str, Any], +) -> Iterator[tuple[str, dict[str, Any]]]: + litellm_params = kwargs.get("litellm_params") + if isinstance(litellm_params, dict): + nested = litellm_params.get("metadata") + if isinstance(nested, dict): + yield "litellm_params.metadata", nested + for key in _CLIENT_CALLBACK_METADATA_SLOTS: + candidate = kwargs.get(key) + if isinstance(candidate, dict): + yield key, candidate + def _is_env_reference(value: object) -> bool: return isinstance(value, str) and "os.environ/" in value @@ -55,6 +71,7 @@ _supported_callback_params = [ "dd_site", "dd_agent_host", "dd_agent_port", + "turn_off_message_logging", ] _request_blocked_callback_params = { @@ -87,19 +104,13 @@ def initialize_standard_callback_dynamic_params( validate_no_callback_env_reference(param, _param_value, source="request body") standard_callback_dynamic_params[param] = _param_value # type: ignore - # 2. Fallback: check "metadata" or "litellm_params" -> "metadata" - metadata = (kwargs.get("metadata") or {}).copy() - litellm_params = kwargs.get("litellm_params") or {} - if isinstance(litellm_params, dict): - metadata.update(litellm_params.get("metadata") or {}) - - if isinstance(metadata, dict): + for slot_label, metadata in iter_client_callback_metadata_dicts(kwargs): for param in _supported_callback_params: if param in _request_blocked_callback_params: continue if param not in standard_callback_dynamic_params and param in metadata: _param_value = metadata.get(param) - validate_no_callback_env_reference(param, _param_value, source="metadata") + validate_no_callback_env_reference(param, _param_value, source=slot_label) standard_callback_dynamic_params[param] = _param_value # type: ignore return standard_callback_dynamic_params diff --git a/litellm/litellm_core_utils/litellm_logging.py b/litellm/litellm_core_utils/litellm_logging.py index da204855465..936d79b22d6 100644 --- a/litellm/litellm_core_utils/litellm_logging.py +++ b/litellm/litellm_core_utils/litellm_logging.py @@ -1530,6 +1530,7 @@ class Logging(LiteLLMLoggingBaseClass): and litellm_params.get(CallTypes.aembedding.value, False) is not True and litellm_params.get(CallTypes.aimage_generation.value, False) is not True and litellm_params.get(CallTypes.atranscription.value, False) is not True + and litellm_params.get(CallTypes.allm_passthrough_route.value, False) is not True ) def _is_assembled_stream_success(self, result=None) -> bool: @@ -4722,7 +4723,7 @@ class StandardLoggingPayloadSetup: api_base: Optional[str] = None, ) -> StandardLoggingModelInformation: model_cost_name = _select_model_name_for_cost_calc( - model=None, + model=base_model if custom_pricing else None, completion_response=init_response_obj, # type: ignore base_model=base_model, custom_pricing=custom_pricing, @@ -5268,6 +5269,11 @@ def get_standard_logging_object_payload( ## Get model cost information ## base_model = _get_base_model_from_metadata(model_call_details=kwargs) + # The router overrides completion_response.model to the model-group alias before + # this payload is built, so cost-map lookup via that alias always misses. + # Fall back to the actual deployment model set by the router in metadata. + if base_model is None: + base_model = metadata.get("deployment") custom_pricing = use_custom_pricing_for_model(litellm_params=litellm_params) raw_response_cost = kwargs.get("response_cost") response_cost: float = raw_response_cost or 0.0 @@ -5389,7 +5395,7 @@ def get_standard_logging_object_payload( def emit_standard_logging_payload(payload: StandardLoggingPayload): if os.getenv("LITELLM_PRINT_STANDARD_LOGGING_PAYLOAD"): - print(json.dumps(payload, indent=4)) # noqa: T201 + print(json.dumps(payload, indent=4), flush=True) # noqa: T201 def get_standard_logging_metadata( diff --git a/litellm/litellm_core_utils/llm_response_utils/convert_dict_to_response.py b/litellm/litellm_core_utils/llm_response_utils/convert_dict_to_response.py index 58107d9804b..47daf33824e 100644 --- a/litellm/litellm_core_utils/llm_response_utils/convert_dict_to_response.py +++ b/litellm/litellm_core_utils/llm_response_utils/convert_dict_to_response.py @@ -656,7 +656,7 @@ def convert_to_model_response_object( message: Optional[Message] = None finish_reason: Optional[str] = None - if _should_convert_tool_call_to_json_mode( + if tool_calls is not None and _should_convert_tool_call_to_json_mode( tool_calls=tool_calls, convert_tool_call_to_json_mode=convert_tool_call_to_json_mode, ): diff --git a/litellm/litellm_core_utils/prompt_templates/factory.py b/litellm/litellm_core_utils/prompt_templates/factory.py index 1f0df51d7de..8bb0e12905e 100644 --- a/litellm/litellm_core_utils/prompt_templates/factory.py +++ b/litellm/litellm_core_utils/prompt_templates/factory.py @@ -6,7 +6,7 @@ import mimetypes import re import xml.etree.ElementTree as ET from enum import Enum -from typing import Any, Dict, List, Optional, Set, Tuple, Union, cast, overload +from typing import Any, Dict, List, Optional, Set, Tuple, TypedDict, Union, cast, overload from jinja2.sandbox import ImmutableSandboxedEnvironment @@ -3626,6 +3626,7 @@ class BedrockImageProcessor: def _convert_to_bedrock_tool_call_invoke( tool_calls: list, + model: Optional[str] = None, ) -> List[BedrockContentBlock]: """ OpenAI tool invokes: @@ -3701,7 +3702,13 @@ def _convert_to_bedrock_tool_call_invoke( # cache_control applies to the whole original # tool call; attach after the last split block. if tool.get("cache_control", None) is not None: - _parts_list.append(BedrockContentBlock(cachePoint=CachePointBlock(type="default"))) + _cache_point_block = litellm.AmazonConverseConfig()._get_cache_point_block( + {"cache_control": tool["cache_control"]}, + block_type="content_block", + model=model, + ) + if _cache_point_block is not None: + _parts_list.append(_cache_point_block) continue # Fallback: no objects extracted — use empty dict. arguments_dict = {} @@ -3712,8 +3719,13 @@ def _convert_to_bedrock_tool_call_invoke( # Check for cache_control and add a separate cachePoint block if tool.get("cache_control", None) is not None: - cache_point_block = BedrockContentBlock(cachePoint=CachePointBlock(type="default")) - _parts_list.append(cache_point_block) + cache_point_block = litellm.AmazonConverseConfig()._get_cache_point_block( + {"cache_control": tool["cache_control"]}, + block_type="content_block", + model=model, + ) + if cache_point_block is not None: + _parts_list.append(cache_point_block) return _parts_list except Exception as e: raise Exception( @@ -4377,6 +4389,7 @@ class BedrockConverseMessagesProcessor: _cache_point_block = litellm.AmazonConverseConfig()._get_cache_point_block( message_block=cast(OpenAIMessageContentListBlock, element), block_type="content_block", + model=model, ) if _cache_point_block is not None: _parts.append(_cache_point_block) @@ -4384,7 +4397,7 @@ class BedrockConverseMessagesProcessor: elif message_block["content"] and isinstance(message_block["content"], str): _part = BedrockContentBlock(text=messages[msg_i]["content"]) _cache_point_block = litellm.AmazonConverseConfig()._get_cache_point_block( - message_block, block_type="content_block" + message_block, block_type="content_block", model=model ) user_content.append(_part) if _cache_point_block is not None: @@ -4416,22 +4429,27 @@ class BedrockConverseMessagesProcessor: tool_content.append(tool_call_result) # Check if we need to add a separate cachePoint block - has_cache_control = False + tool_msg_cache_control = None # Check for message-level cache_control if current_message.get("cache_control", None) is not None: - has_cache_control = True + tool_msg_cache_control = current_message["cache_control"] # Check for content-level cache_control in list content elif isinstance(current_message.get("content"), list): for content_element in current_message["content"]: if isinstance(content_element, dict) and content_element.get("cache_control", None) is not None: - has_cache_control = True + tool_msg_cache_control = content_element["cache_control"] break # Add a separate cachePoint block if cache_control is present - if has_cache_control: - cache_point_block = BedrockContentBlock(cachePoint=CachePointBlock(type="default")) - tool_content.append(cache_point_block) + if tool_msg_cache_control is not None: + cache_point_block = litellm.AmazonConverseConfig()._get_cache_point_block( + {"cache_control": tool_msg_cache_control}, + block_type="content_block", + model=model, + ) + if cache_point_block is not None: + tool_content.append(cache_point_block) msg_i += 1 # Deduplicate toolResult blocks with the same toolUseId @@ -4509,6 +4527,7 @@ class BedrockConverseMessagesProcessor: _cache_point_block = litellm.AmazonConverseConfig()._get_cache_point_block( message_block=cast(OpenAIMessageContentListBlock, element), block_type="content_block", + model=model, ) if _cache_point_block is not None: assistants_parts.append(_cache_point_block) @@ -4520,14 +4539,14 @@ class BedrockConverseMessagesProcessor: # If content is empty/whitespace, skip it (don't add a placeholder) # Add cache point block for assistant string content _cache_point_block = litellm.AmazonConverseConfig()._get_cache_point_block( - assistant_message_block, block_type="content_block" + assistant_message_block, block_type="content_block", model=model ) if _cache_point_block is not None: assistant_content.append(_cache_point_block) _tool_calls = assistant_message_block.get("tool_calls", []) if _tool_calls: - assistant_content.extend(_convert_to_bedrock_tool_call_invoke(_tool_calls)) + assistant_content.extend(_convert_to_bedrock_tool_call_invoke(_tool_calls, model=model)) msg_i += 1 @@ -4745,6 +4764,7 @@ def _bedrock_converse_messages_pt( _cache_point_block = litellm.AmazonConverseConfig()._get_cache_point_block( message_block=cast(OpenAIMessageContentListBlock, element), block_type="content_block", + model=model, ) if _cache_point_block is not None: _parts.append(_cache_point_block) @@ -4752,7 +4772,7 @@ def _bedrock_converse_messages_pt( elif message_block["content"] and isinstance(message_block["content"], str): _part = BedrockContentBlock(text=messages[msg_i]["content"]) _cache_point_block = litellm.AmazonConverseConfig()._get_cache_point_block( - message_block, block_type="content_block" + message_block, block_type="content_block", model=model ) user_content.append(_part) if _cache_point_block is not None: @@ -4786,22 +4806,27 @@ def _bedrock_converse_messages_pt( tool_content.append(tool_call_result) # Check if we need to add a separate cachePoint block - has_cache_control = False + tool_msg_cache_control = None # Check for message-level cache_control if current_message.get("cache_control", None) is not None: - has_cache_control = True + tool_msg_cache_control = current_message["cache_control"] # Check for content-level cache_control in list content elif isinstance(current_message.get("content"), list): for content_element in current_message["content"]: if isinstance(content_element, dict) and content_element.get("cache_control", None) is not None: - has_cache_control = True + tool_msg_cache_control = content_element["cache_control"] break # Add a separate cachePoint block if cache_control is present - if has_cache_control: - cache_point_block = BedrockContentBlock(cachePoint=CachePointBlock(type="default")) - tool_content.append(cache_point_block) + if tool_msg_cache_control is not None: + cache_point_block = litellm.AmazonConverseConfig()._get_cache_point_block( + {"cache_control": tool_msg_cache_control}, + block_type="content_block", + model=model, + ) + if cache_point_block is not None: + tool_content.append(cache_point_block) msg_i += 1 # Deduplicate toolResult blocks with the same toolUseId @@ -4882,6 +4907,7 @@ def _bedrock_converse_messages_pt( _cache_point_block = litellm.AmazonConverseConfig()._get_cache_point_block( message_block=cast(OpenAIMessageContentListBlock, element), block_type="content_block", + model=model, ) if _cache_point_block is not None: assistants_parts.append(_cache_point_block) @@ -4892,13 +4918,13 @@ def _bedrock_converse_messages_pt( assistant_content.append(BedrockContentBlock(text=_assistant_content)) # Add cache point block for assistant string content _cache_point_block = litellm.AmazonConverseConfig()._get_cache_point_block( - assistant_message_block, block_type="content_block" + assistant_message_block, block_type="content_block", model=model ) if _cache_point_block is not None: assistant_content.append(_cache_point_block) _tool_calls = assistant_message_block.get("tool_calls", []) if _tool_calls: - assistant_content.extend(_convert_to_bedrock_tool_call_invoke(_tool_calls)) + assistant_content.extend(_convert_to_bedrock_tool_call_invoke(_tool_calls, model=model)) msg_i += 1 @@ -5035,15 +5061,18 @@ def _bedrock_tools_pt(tools: List, model: Optional[str] = None) -> List[BedrockT ] """ from litellm.llms.bedrock.common_utils import ( - get_bedrock_base_model, + bedrock_converse_supports_strict_tools, normalize_json_schema_custom_types_to_object, ) from litellm.litellm_core_utils.prompt_templates.common_utils import unpack_defs _valid_json_schema_root_types = frozenset(("array", "boolean", "integer", "null", "number", "object", "string")) # Only Claude on Bedrock honours strict tool schemas; other families - # (Nova, Llama, GPT-OSS) reject the strict field outright. - supports_strict_tools = bool(model and get_bedrock_base_model(model).startswith("anthropic")) + # (Nova, Llama, GPT-OSS) reject the strict field outright. Opus 4.7/4.8 + # also reject `strict` on Bedrock Converse (see #31582) — their validator + # maps toolSpec to the native Anthropic tool shape, which has no strict + # field, even though Anthropic's native API accepts it as a top-level key. + supports_strict_tools = bool(model and bedrock_converse_supports_strict_tools(model)) tool_block_list: List[BedrockToolBlock] = [] for tool_idx, tool in enumerate(tools): # Check if tool is already a BedrockToolBlock (e.g., systemTool for Nova grounding) @@ -5322,3 +5351,146 @@ def get_attribute_or_key(tool_or_function, attribute, default=None): if hasattr(tool_or_function, attribute): return getattr(tool_or_function, attribute) return tool_or_function.get(attribute, default) + + +class NormalizedToolCall(TypedDict): + id: Optional[str] + name: Optional[str] + arguments: dict[str, Any] + + +def _parse_tool_call_arguments(raw: Any, tool_name: Optional[str], context: str) -> dict[str, Any]: + # Anthropic's tool_use blocks already carry a parsed dict in "input"; + # chat completions and the Responses API carry a JSON string that may be + # truncated by the model, so route those through the repair-aware parser. + if isinstance(raw, dict): + return raw + if not isinstance(raw, str): + return {} + from litellm.litellm_core_utils.prompt_templates.common_utils import ( + parse_tool_call_arguments, + ) + + try: + parsed = parse_tool_call_arguments(raw, tool_name=tool_name, context=context) + except ValueError as e: + verbose_logger.warning("Failed to parse tool call arguments: %s", e) + return {} + return parsed if isinstance(parsed, dict) else {} + + +def _tool_calls_from_chat_completion_response(response: Any) -> list[NormalizedToolCall]: + choices = get_attribute_or_key(response, "choices", None) + if not (isinstance(choices, list) and choices): + return [] + message = get_attribute_or_key(choices[0], "message", None) + tool_calls = get_attribute_or_key(message, "tool_calls", None) if message else None + if not isinstance(tool_calls, list): + return [] + result: list[NormalizedToolCall] = [] + for tc in tool_calls: + fn = get_attribute_or_key(tc, "function", None) + if fn is None: + continue + name = get_attribute_or_key(fn, "name") + result.append( + NormalizedToolCall( + id=get_attribute_or_key(tc, "id"), + name=name, + arguments=_parse_tool_call_arguments( + get_attribute_or_key(fn, "arguments", "{}"), + tool_name=name, + context="chat completions", + ), + ) + ) + return result + + +def _tool_calls_from_responses_api_response(response: Any) -> list[NormalizedToolCall]: + output = get_attribute_or_key(response, "output", None) + if not isinstance(output, list): + return [] + result: list[NormalizedToolCall] = [] + for item in output: + if get_attribute_or_key(item, "type") != "function_call": + continue + name = get_attribute_or_key(item, "name") + result.append( + NormalizedToolCall( + id=get_attribute_or_key(item, "call_id") or get_attribute_or_key(item, "id"), + name=name, + arguments=_parse_tool_call_arguments( + get_attribute_or_key(item, "arguments", "{}"), + tool_name=name, + context="responses API", + ), + ) + ) + return result + + +def _tool_calls_from_anthropic_messages_response(response: Any) -> list[NormalizedToolCall]: + content = get_attribute_or_key(response, "content", None) + if not isinstance(content, list): + return [] + result: list[NormalizedToolCall] = [] + for block in content: + if get_attribute_or_key(block, "type") != "tool_use": + continue + raw_input = get_attribute_or_key(block, "input", {}) + result.append( + NormalizedToolCall( + id=get_attribute_or_key(block, "id"), + name=get_attribute_or_key(block, "name"), + arguments=raw_input if isinstance(raw_input, dict) else {}, + ) + ) + return result + + +def get_tool_calls_from_response(response: Any) -> list[NormalizedToolCall]: + """ + Extract tool/function calls from a response object into a normalized + ``{"id", "name", "arguments"}`` shape, regardless of which API surface + produced it: chat completions (``choices[].message.tool_calls``), + the Responses API (``output`` items of type ``function_call``), or the + Anthropic Messages API (``content`` blocks of type ``tool_use``). + + Callers that only care about a specific tool should filter the result by + ``name`` themselves -- this returns every tool call found. + """ + for extractor in ( + _tool_calls_from_chat_completion_response, + _tool_calls_from_responses_api_response, + _tool_calls_from_anthropic_messages_response, + ): + tool_calls = extractor(response) + if tool_calls: + return tool_calls + return [] + + +def has_tool_with_name(tools: Any, tool_name: str) -> bool: + """ + Check whether a tools list (as sent to an LLM) includes a tool with the + given name, regardless of shape: OpenAI-style function tools + (``{"type": "function", "function": {"name": ...}}``) or Anthropic's + native tool shape (a top-level ``"name"``, e.g. + ``{"name": ..., "input_schema": ...}``). Anthropic's documented client + tool format doesn't require a ``"type"`` key at all -- ``"custom"`` is + only one of several possible values -- so any non-OpenAI-shaped tool is + matched on its top-level ``"name"``. + """ + if not isinstance(tools, list): + return False + for tool in tools: + if not isinstance(tool, dict): + continue + function = tool.get("function") + if tool.get("type") == "function" and isinstance(function, dict): + if function.get("name") == tool_name: + return True + elif tool.get("name") == tool_name: + return True + return False diff --git a/litellm/litellm_core_utils/prompt_templates/image_handling.py b/litellm/litellm_core_utils/prompt_templates/image_handling.py index 7129d6bba81..92a4296c432 100644 --- a/litellm/litellm_core_utils/prompt_templates/image_handling.py +++ b/litellm/litellm_core_utils/prompt_templates/image_handling.py @@ -72,6 +72,9 @@ def _process_image_response(response: Response, url: str) -> str: async def async_convert_url_to_base64(url: str) -> str: + if url.startswith("data:") and ";base64," in url: + return url + # If MAX_IMAGE_URL_DOWNLOAD_SIZE_MB is 0, block all image downloads if MAX_IMAGE_URL_DOWNLOAD_SIZE_MB == 0: raise litellm.ImageFetchError( @@ -95,6 +98,9 @@ async def async_convert_url_to_base64(url: str) -> str: def convert_url_to_base64(url: str) -> str: + if url.startswith("data:") and ";base64," in url: + return url + # If MAX_IMAGE_URL_DOWNLOAD_SIZE_MB is 0, block all image downloads if MAX_IMAGE_URL_DOWNLOAD_SIZE_MB == 0: raise litellm.ImageFetchError( diff --git a/litellm/litellm_core_utils/realtime_streaming.py b/litellm/litellm_core_utils/realtime_streaming.py index bd6406c6241..220d1caa3d2 100644 --- a/litellm/litellm_core_utils/realtime_streaming.py +++ b/litellm/litellm_core_utils/realtime_streaming.py @@ -1,10 +1,10 @@ import asyncio -import concurrent.futures import json from typing import TYPE_CHECKING, Any, Dict, List, Optional, Protocol, Union, cast import litellm from litellm._logging import verbose_logger +from litellm.litellm_core_utils.logging_worker import GLOBAL_LOGGING_WORKER from litellm.llms.base_llm.realtime.transformation import BaseRealtimeConfig from litellm.types.llms.openai import ( OpenAIRealtimeEvents, @@ -24,9 +24,6 @@ if TYPE_CHECKING: else: CLIENT_CONNECTION_CLASS = Any -# Create a thread pool with a maximum of 10 threads -executor = concurrent.futures.ThreadPoolExecutor(max_workers=10) - class RealtimeEventNormalizer(Protocol): def should_drop(self, event: object) -> bool: ... @@ -314,11 +311,12 @@ class RealTimeStreaming: if self.session_tools or self.tool_calls: self.logging_obj.model_call_details["realtime_tools"] = self.session_tools self.logging_obj.model_call_details["realtime_tool_calls"] = self.tool_calls - ## ASYNC LOGGING - # Create an event loop for the new thread - asyncio.create_task(self.logging_obj.async_success_handler(self.messages)) - ## SYNC LOGGING - executor.submit(self.logging_obj.success_handler(self.messages)) + # Route through the bounded logging worker (per-coroutine timeout + + # concurrency cap) instead of a bare create_task, so a slow callback + # can't leave suspended tasks pinning each call's response in memory. + GLOBAL_LOGGING_WORKER.ensure_initialized_and_enqueue( + self.logging_obj.dispatch_success_handlers(self.messages, prefer_async_handlers=True) + ) async def _send_to_backend(self, message: str) -> bool: """Send a message to the backend WebSocket. diff --git a/litellm/litellm_core_utils/sensitive_data_masker.py b/litellm/litellm_core_utils/sensitive_data_masker.py index daca48120cd..7861e13bae5 100644 --- a/litellm/litellm_core_utils/sensitive_data_masker.py +++ b/litellm/litellm_core_utils/sensitive_data_masker.py @@ -1,6 +1,8 @@ from collections.abc import Mapping from typing import Any, Dict, List, Optional, Set +from pydantic import BaseModel + from litellm.constants import DEFAULT_MAX_RECURSE_DEPTH_SENSITIVE_DATA_MASKER @@ -131,8 +133,59 @@ class SensitiveDataMasker: return masked_data + def mask(self, data: object) -> object: + if isinstance(data, Mapping): + return self.mask_dict(dict(data)) + if isinstance(data, list): + return self._mask_sequence( + data, + 0, + DEFAULT_MAX_RECURSE_DEPTH_SENSITIVE_DATA_MASKER, + None, + False, + ) + return data + _default_masker = SensitiveDataMasker() +_error_masker = SensitiveDataMasker(visible_prefix=4, visible_suffix=0) + + +def mask_sensitive_structure(data: object) -> object: + return _error_masker.mask(data) + + +def mask_credentials_in_payload(data: object) -> object: + """Return a copy of ``data`` where string values under sensitive-named keys + are masked but every other value (``None``, ``int``, ``float``, ``bool``, + ``bytes``, ``datetime``, tuples, sets, typed objects) is preserved by + identity, and dicts/lists are rebuilt structurally. + + Use this for logging payloads that carry response data through to + SpendLogs / OTel / Langfuse, where :meth:`SensitiveDataMasker.mask`'s + config-dump semantics (``None`` -> ``"None"``, tuples stringified, + objects flattened via ``__dict__``) would silently distort the record. + + Sensitive-key detection is delegated to the shared + :class:`SensitiveDataMasker` so pattern updates stay in one place. + """ + return _walk_payload(data, key_is_sensitive=False, depth=0) + + +def _walk_payload(node: object, key_is_sensitive: bool, depth: int) -> object: + if depth >= DEFAULT_MAX_RECURSE_DEPTH_SENSITIVE_DATA_MASKER: + return node + if isinstance(node, Mapping): + return {k: _walk_payload(v, _default_masker.is_sensitive_key(k), depth + 1) for k, v in node.items()} + if isinstance(node, list): + return [_walk_payload(item, key_is_sensitive, depth + 1) for item in node] + if isinstance(node, tuple): + return tuple(_walk_payload(item, key_is_sensitive, depth + 1) for item in node) + if isinstance(node, BaseModel): + return _walk_payload(node.model_dump(), key_is_sensitive, depth) + if key_is_sensitive and isinstance(node, str) and node: + return _default_masker._mask_value(node) + return node def mask_sensitive_keys(data: Dict[str, Any], sensitive_fields: Set[str]) -> Dict[str, Any]: diff --git a/litellm/litellm_core_utils/streaming_chunk_builder_utils.py b/litellm/litellm_core_utils/streaming_chunk_builder_utils.py index deeee3b7daf..38bc68f2f78 100644 --- a/litellm/litellm_core_utils/streaming_chunk_builder_utils.py +++ b/litellm/litellm_core_utils/streaming_chunk_builder_utils.py @@ -7,6 +7,7 @@ from litellm.types.llms.openai import ( ChatCompletionAudioDelta, ) from litellm.types.utils import ( + CacheCreationTokenDetails, ChatCompletionAudioResponse, ChatCompletionMessageToolCall, Choices, @@ -541,6 +542,12 @@ class ChunkProcessor: web_search_requests: Optional[int] = None completion_tokens_details: Optional[CompletionTokensDetails] = None prompt_tokens_details: Optional[PromptTokensDetailsWrapper] = None + # Anthropic emits the cache-creation TTL breakdown (5m/1h split) only on + # the `message_start` event; the later `message_delta` carries the flat + # cache-creation count but drops the nested breakdown. prompt_tokens_details + # is last-wins, so without preserving this separately the 1h breakdown is + # lost and 1h cache writes get billed at the 5m rate. + cache_creation_token_details: Optional[CacheCreationTokenDetails] = None for chunk in chunks: usage_chunk: Optional[Usage] = None if "usage" in chunk: @@ -594,7 +601,18 @@ class ChunkProcessor: "web_search_requests", ) - prompt_tokens_details = usage_chunk_dict["prompt_tokens_details"] + prompt_tokens_details = cast( + Optional[PromptTokensDetailsWrapper], + usage_chunk_dict["prompt_tokens_details"], + ) + + cache_creation_token_details = self._capture_cache_creation_token_details( + prompt_tokens_details, cache_creation_token_details + ) + + prompt_tokens_details = self._attach_cache_creation_token_details( + prompt_tokens_details, cache_creation_token_details + ) completion_tokens = self._reset_anthropic_cursor_completion_tokens( chunks=chunks, @@ -613,6 +631,34 @@ class ChunkProcessor: prompt_tokens_details=prompt_tokens_details, ) + @staticmethod + def _capture_cache_creation_token_details( + prompt_tokens_details: Optional[PromptTokensDetailsWrapper], + current: Optional[CacheCreationTokenDetails], + ) -> Optional[CacheCreationTokenDetails]: + incoming = cast( + Optional[CacheCreationTokenDetails], + getattr(prompt_tokens_details, "cache_creation_token_details", None), + ) + if incoming is not None: + return incoming + return current + + @staticmethod + def _attach_cache_creation_token_details( + prompt_tokens_details: Optional[PromptTokensDetailsWrapper], + cache_creation_token_details: Optional[CacheCreationTokenDetails], + ) -> Optional[PromptTokensDetailsWrapper]: + if prompt_tokens_details is None or cache_creation_token_details is None: + return prompt_tokens_details + existing = cast( + Optional[CacheCreationTokenDetails], + getattr(prompt_tokens_details, "cache_creation_token_details", None), + ) + if existing is not None: + return prompt_tokens_details + return prompt_tokens_details.model_copy(update={"cache_creation_token_details": cache_creation_token_details}) + @staticmethod def _reset_anthropic_cursor_completion_tokens( chunks: list[dict[str, Any] | ModelResponse], diff --git a/litellm/litellm_core_utils/streaming_handler.py b/litellm/litellm_core_utils/streaming_handler.py index 587a3a58a94..128ba0bf3ab 100644 --- a/litellm/litellm_core_utils/streaming_handler.py +++ b/litellm/litellm_core_utils/streaming_handler.py @@ -1884,7 +1884,7 @@ class CustomStreamWrapper: await self.fetch_stream() if is_async_iterable(self.completion_stream): - async for chunk in self.completion_stream: # type: ignore[union-attr] + async for chunk in self.completion_stream: # pyright: ignore[reportOptionalIterable] # is_async_iterable guard proves __aiter__ if chunk == "None" or chunk is None: continue # skip None chunks diff --git a/litellm/litellm_core_utils/token_counter.py b/litellm/litellm_core_utils/token_counter.py index 56b9d42092c..071b16c8378 100644 --- a/litellm/litellm_core_utils/token_counter.py +++ b/litellm/litellm_core_utils/token_counter.py @@ -407,6 +407,37 @@ def token_counter( return num_tokens +def _count_function_call_tokens( + key: str, + value: Any, + message: Mapping[str, Any], + count_function: TokenCounterFunction, +) -> int: + """ + Count tokens contributed by an assistant message's tool/function call payload. + + Handles both the modern `tool_calls` list and the legacy OpenAI + `function_call` dict. Only the `arguments` string is counted (matching the + existing tool_calls behavior); names are accounted for elsewhere via the + tool/function definitions and `tool_choice`. + """ + if key == "tool_calls": + if not isinstance(value, List): + raise ValueError(f"Unsupported type {type(value)} for key tool_calls in message {message}") + total = 0 + for tool_call in value: + if "function" not in tool_call: + raise ValueError(f"Unsupported tool call {tool_call} must contain a function key") + function_arguments = tool_call["function"].get("arguments", "") + total += count_function(str(function_arguments)) + return total + if key == "function_call": + if not isinstance(value, Mapping): + raise ValueError(f"Unsupported type {type(value)} for key function_call in message {message}") + return count_function(str(value.get("arguments", ""))) + raise ValueError(f"Unexpected key {key!r}; expected 'tool_calls' or 'function_call'") + + def _count_messages( params: _MessageCountParams, messages: List[AllMessageValues], @@ -430,16 +461,8 @@ def _count_messages( for key, value in message.items(): if value is None: pass - elif key == "tool_calls": - if isinstance(value, List): - for tool_call in value: - if "function" in tool_call: - function_arguments = tool_call["function"].get("arguments", []) - num_tokens += params.count_function(str(function_arguments)) - else: - raise ValueError(f"Unsupported tool call {tool_call} must contain a function key") - else: - raise ValueError(f"Unsupported type {type(value)} for key tool_calls in message {message}") + elif key in ("tool_calls", "function_call"): + num_tokens += _count_function_call_tokens(key, value, message, params.count_function) elif isinstance(value, str): num_tokens += params.count_function(value) if key == "name": diff --git a/litellm/llms/a2a/chat/transformation.py b/litellm/llms/a2a/chat/transformation.py index c9623a817bf..113c000f352 100644 --- a/litellm/llms/a2a/chat/transformation.py +++ b/litellm/llms/a2a/chat/transformation.py @@ -10,7 +10,7 @@ import httpx from litellm.llms.base_llm.base_model_iterator import BaseModelResponseIterator from litellm.llms.base_llm.chat.transformation import BaseConfig, BaseLLMException from litellm.types.llms.openai import AllMessageValues -from litellm.types.utils import Choices, Message, ModelResponse +from litellm.types.utils import Choices, Message, ModelResponse, Usage from ..common_utils import ( A2AError, @@ -312,6 +312,25 @@ class A2AConfig(BaseConfig): # Set ID from response model_response.id = response_json.get("id", str(uuid.uuid4())) + # A2A agents don't return token usage; estimate it so per-token pricing + # produces real cost and callers don't receive usage of 0/0/0. + try: + from litellm.utils import token_counter + + prompt_tokens = token_counter(model="gpt-3.5-turbo", messages=messages) + completion_tokens = token_counter(model="gpt-3.5-turbo", text=text, count_response_tokens=True) + setattr( + model_response, + "usage", + Usage( + prompt_tokens=prompt_tokens, + completion_tokens=completion_tokens, + total_tokens=prompt_tokens + completion_tokens, + ), + ) + except Exception: # noqa: BLE001 - best-effort estimate; a tokenizer hiccup must not break the response + pass + return model_response def get_model_response_iterator( diff --git a/litellm/llms/anthropic/chat/guardrail_translation/handler.py b/litellm/llms/anthropic/chat/guardrail_translation/handler.py index 4506c114208..7000c20d9c4 100644 --- a/litellm/llms/anthropic/chat/guardrail_translation/handler.py +++ b/litellm/llms/anthropic/chat/guardrail_translation/handler.py @@ -48,7 +48,10 @@ from litellm.types.utils import ( ) if TYPE_CHECKING: - from litellm.integrations.custom_guardrail import CustomGuardrail + from litellm.integrations.custom_guardrail import ( + CustomGuardrail, + ModifyResponseException, + ) from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj from litellm.types.llms.anthropic_messages.anthropic_response import ( AnthropicMessagesResponse, @@ -70,6 +73,170 @@ class AnthropicMessagesHandler(BaseTranslation): super().__init__() self.adapter = LiteLLMAnthropicMessagesAdapter() + @staticmethod + def _build_streaming_usage_response( + responses_so_far: list[Any], + request_data: Optional[dict], + ) -> Optional[ModelResponse]: + chunks = tuple(response for response in responses_so_far if isinstance(response, (str, bytes))) + if not chunks: + return None + try: + return AnthropicPassthroughLoggingHandler._build_usage_only_response_from_chunks( + all_chunks=chunks, + model=str((request_data or {}).get("model") or ""), + ) + except (AttributeError, TypeError, ValueError): + return None + + def build_block_sse_chunks( + self, + exc: "ModifyResponseException", + stream_started: bool = False, + responses_so_far: Optional[list[Any]] = None, + ) -> list[bytes]: + """ + Build an Anthropic SSE sequence delivering the guardrail block message + and terminating the stream cleanly. + + - ``stream_started`` False (buffered / pre-stream): nothing has been + sent, so emit a complete standalone message (message_start -> + content_block_* -> message_delta -> message_stop) via + FakeAnthropicMessagesStreamIterator, the same converter the + /v1/messages pre-stream block handler uses. + - ``stream_started`` True (sampling / detect-only end-of-stream): real + chunks were already sent, so *continue* the in-progress message -- + close the open content block, append the block message as a new text + block, then end the message. Emitting a second ``message_start`` here + would make Anthropic clients reject the stream. + """ + if stream_started: + return self._block_continuation_chunks(exc, responses_so_far or []) + return self._standalone_block_chunks(exc) + + def _standalone_block_chunks(self, exc: "ModifyResponseException") -> list[bytes]: + import uuid + + from litellm.llms.anthropic.experimental_pass_through.messages.fake_stream_iterator import ( + FakeAnthropicMessagesStreamIterator, + ) + from litellm.llms.base_llm.guardrail_translation.utils import ( + blocked_response_usage, + ) + from litellm.types.utils import AnthropicMessagesResponse + + block_response = AnthropicMessagesResponse( + id=f"msg_{uuid.uuid4()}", + type="message", + role="assistant", + content=[{"type": "text", "text": exc.message}], + model=exc.model, + stop_reason="end_turn", + usage=blocked_response_usage(getattr(exc, "original_response", None)), + ) + return list(FakeAnthropicMessagesStreamIterator(response=block_response)) + + def _block_continuation_chunks(self, exc: "ModifyResponseException", responses_so_far: list[Any]) -> list[bytes]: + """Continue an already-started message: close the open content block, + append the block message as a new text block, then end the message -- + without a second message_start.""" + + from litellm.llms.base_llm.guardrail_translation.utils import ( + blocked_response_usage, + ) + + def _sse(event_type: str, payload: dict) -> bytes: + return f"event: {event_type}\ndata: {json.dumps(payload)}\n\n".encode() + + output_tokens = blocked_response_usage(getattr(exc, "original_response", None))["output_tokens"] + open_index, max_index = self._content_block_state(responses_so_far) + new_index = (max_index + 1) if max_index is not None else 0 + chunks: list[bytes] = [] + if open_index is not None: + chunks.append(_sse("content_block_stop", {"type": "content_block_stop", "index": open_index})) + chunks += [ + _sse( + "content_block_start", + { + "type": "content_block_start", + "index": new_index, + "content_block": {"type": "text", "text": ""}, + }, + ), + _sse( + "content_block_delta", + { + "type": "content_block_delta", + "index": new_index, + "delta": {"type": "text_delta", "text": exc.message}, + }, + ), + _sse("content_block_stop", {"type": "content_block_stop", "index": new_index}), + _sse( + "message_delta", + { + "type": "message_delta", + "delta": {"stop_reason": "end_turn", "stop_sequence": None}, + "usage": {"output_tokens": output_tokens}, + }, + ), + _sse("message_stop", {"type": "message_stop"}), + ] + return chunks + + @staticmethod + def _content_block_state( + responses_so_far: list[Any], + ) -> tuple[Optional[int], Optional[int]]: + """From the SSE chunks already sent to the client, return (open + content-block index or None, highest content-block index seen or None). + + A single streamed item may bundle multiple SSE events (raw bytes) or be + an already-parsed event dict, so every event across every item is + considered -- matching how ``get_streaming_string_so_far`` reads the + same stream.""" + open_indices: set[int] = set() + max_index: Optional[int] = None + for item in responses_so_far: + for data in AnthropicMessagesHandler._iter_sse_events(item): + event_type = data.get("type") + index = data.get("index") + if not isinstance(index, int): + continue + if event_type == "content_block_start": + open_indices.add(index) + max_index = index if max_index is None else max(max_index, index) + elif event_type == "content_block_stop": + open_indices.discard(index) + open_index = max(open_indices) if open_indices else None + return open_index, max_index + + @staticmethod + def _iter_sse_events(item: Any) -> list[dict]: + """Yield the event-data dicts in one stream chunk. + + Handles both formats this stream can carry (see + ``get_streaming_string_so_far``): raw SSE ``bytes`` -- which may bundle + several events separated by a blank line -- and an already-parsed event + ``dict``.""" + if isinstance(item, dict): + return [item] + if not isinstance(item, (bytes, bytearray)): + return [] + events: list[dict] = [] + for block in item.decode("utf-8", errors="replace").split("\n\n"): + for line in block.split("\n"): + line = line.strip() + if not line.startswith("data:"): + continue + try: + parsed = json.loads(line[len("data:") :].strip()) + except json.JSONDecodeError: + continue + if isinstance(parsed, dict): + events.append(parsed) + return events + def _translate_to_openai(self, data: dict) -> ChatCompletionRequest: """Translate Anthropic request to OpenAI chat completion format.""" ( @@ -406,6 +573,8 @@ class AnthropicMessagesHandler(BaseTranslation): Get the string so far, check the apply guardrail to the string so far, and return the list of responses so far. """ + from litellm.integrations.custom_guardrail import ModifyResponseException + has_ended = self._check_streaming_has_ended(responses_so_far) if has_ended: # build the model response from the responses_so_far @@ -430,25 +599,35 @@ class AnthropicMessagesHandler(BaseTranslation): if tool_calls_list: guardrail_inputs["tool_calls"] = tool_calls_list - _guardrailed_inputs = ( - await guardrail_to_apply.apply_guardrail( # allow rejecting the response, if invalid + try: + _guardrailed_inputs = await guardrail_to_apply.apply_guardrail( inputs=guardrail_inputs, request_data=request_data if request_data is not None else {}, input_type="response", logging_obj=litellm_logging_obj, ) - ) + except ModifyResponseException as e: + if e.original_response is None: + e.original_response = built_response or self._build_streaming_usage_response( + responses_so_far, request_data + ) + raise else: verbose_proxy_logger.debug("Skipping output guardrail - model response has no choices") return responses_so_far string_so_far = self.get_streaming_string_so_far(responses_so_far) - _guardrailed_inputs = await guardrail_to_apply.apply_guardrail( # allow rejecting the response, if invalid - inputs={"texts": [string_so_far]}, - request_data=request_data if request_data is not None else {}, - input_type="response", - logging_obj=litellm_logging_obj, - ) + try: + _guardrailed_inputs = await guardrail_to_apply.apply_guardrail( + inputs={"texts": [string_so_far]}, + request_data=request_data if request_data is not None else {}, + input_type="response", + logging_obj=litellm_logging_obj, + ) + except ModifyResponseException as e: + if e.original_response is None: + e.original_response = self._build_streaming_usage_response(responses_so_far, request_data) + raise return responses_so_far def _prepare_request_data( diff --git a/litellm/llms/anthropic/experimental_pass_through/adapters/handler.py b/litellm/llms/anthropic/experimental_pass_through/adapters/handler.py index 812e0f62c96..7299fc16897 100644 --- a/litellm/llms/anthropic/experimental_pass_through/adapters/handler.py +++ b/litellm/llms/anthropic/experimental_pass_through/adapters/handler.py @@ -78,7 +78,7 @@ async def _prepare_context_managed_request( system: Optional[Any], context_management_spec: Any, litellm_metadata: Optional[Dict], - drop_params: Optional[bool], + additional_drop_params: Optional[list[str]], llm_router: Any, user_api_key_auth: Any = None, ) -> Optional[PolyfillResult]: @@ -95,7 +95,7 @@ async def _prepare_context_managed_request( # silently drop intermediate turns. polyfill_will_run = _polyfill_will_run( context_management_spec=context_management_spec, - drop_params=drop_params, + additional_drop_params=additional_drop_params, ) if polyfill_will_run: @@ -117,7 +117,7 @@ async def _prepare_context_managed_request( system=working_system, context_management_spec=context_management_spec, litellm_metadata=litellm_metadata, - drop_params=drop_params, + additional_drop_params=additional_drop_params, llm_router=llm_router, user_api_key_auth=user_api_key_auth, ) @@ -143,18 +143,19 @@ async def _prepare_context_managed_request( def _polyfill_will_run( *, context_management_spec: Any, - drop_params: Optional[bool], + additional_drop_params: Optional[list[str]], ) -> bool: """Return True when ``compact_20260112`` will run via the polyfill dispatcher. - Mirrors the gating in ``_run_polyfill_if_enabled``: an empty spec or - effective ``drop_params`` short-circuits the polyfill. The pre-processing - skip only applies when the dispatcher will actually invoke - ``apply_compact_20260112`` (which has its own compaction-block slicing). + Mirrors the gating in ``_run_polyfill_if_enabled``: an empty spec or an + explicit ``context_management`` entry in ``additional_drop_params`` + short-circuits the polyfill. The pre-processing skip only applies when the + dispatcher will actually invoke ``apply_compact_20260112`` (which has its + own compaction-block slicing). """ edits = _normalize_spec_edits( context_management_spec=context_management_spec, - drop_params=drop_params, + additional_drop_params=additional_drop_params, ) if edits is None: return False @@ -169,7 +170,7 @@ def _polyfill_will_run( def _spec_has_non_compact_edits( *, context_management_spec: Any, - drop_params: Optional[bool], + additional_drop_params: Optional[list[str]], ) -> bool: """Return True when the spec includes edits other than ``compact_20260112``. @@ -180,7 +181,7 @@ def _spec_has_non_compact_edits( """ edits = _normalize_spec_edits( context_management_spec=context_management_spec, - drop_params=drop_params, + additional_drop_params=additional_drop_params, ) if edits is None: return False @@ -195,10 +196,22 @@ def _spec_has_non_compact_edits( ) +def _context_management_explicitly_dropped(additional_drop_params: Optional[list[str]]) -> bool: + """True when the caller opted out of context_management via ``additional_drop_params``. + + ``drop_params`` deliberately does NOT gate the polyfill: ``context_management`` + is a LiteLLM-supported param (native on Anthropic, polyfilled elsewhere), and + ``drop_params`` only exists to drop genuinely unsupported params. + """ + if not isinstance(additional_drop_params, list): + return False + return "context_management" in additional_drop_params + + def _normalize_spec_edits( *, context_management_spec: Any, - drop_params: Optional[bool], + additional_drop_params: Optional[list[str]], ) -> Optional[List[Dict[str, Any]]]: """Return the normalized ``edits`` list, or ``None`` if the polyfill won't run. @@ -208,8 +221,7 @@ def _normalize_spec_edits( if not context_management_spec: return None - effective_drop_params = drop_params if drop_params is not None else litellm.drop_params - if effective_drop_params: + if _context_management_explicitly_dropped(additional_drop_params): return None from litellm.llms.anthropic.experimental_pass_through.context_management.dispatcher import ( @@ -230,22 +242,23 @@ async def _run_polyfill_if_enabled( system: Optional[Any], context_management_spec: Any, litellm_metadata: Optional[Dict], - drop_params: Optional[bool], + additional_drop_params: Optional[list[str]], llm_router: Any, user_api_key_auth: Any = None, ) -> Optional[PolyfillResult]: """Run the async context_management polyfill if a spec is present. - Returns ``None`` when the spec is empty or drop_params is on. Raises - ``AnthropicContextManagementError`` so the /v1/messages endpoint can - emit an Anthropic-format 400. All other exceptions are best-effort - swallowed (matches v0 behavior). + Returns ``None`` when the spec is empty or ``context_management`` is + listed in ``additional_drop_params`` (the explicit opt-out; ``drop_params`` + does not disable the polyfill because context_management is a supported + param). Raises ``AnthropicContextManagementError`` so the /v1/messages + endpoint can emit an Anthropic-format 400. All other exceptions are + best-effort swallowed (matches v0 behavior). """ if not context_management_spec: return None - effective_drop_params = drop_params if drop_params is not None else litellm.drop_params - if effective_drop_params: + if _context_management_explicitly_dropped(additional_drop_params): return None try: @@ -274,7 +287,7 @@ async def _run_polyfill_if_enabled( # emits an Anthropic-format error. if _spec_has_non_compact_edits( context_management_spec=context_management_spec, - drop_params=drop_params, + additional_drop_params=additional_drop_params, ): raise AnthropicContextManagementError( status_code=500, @@ -533,7 +546,7 @@ class LiteLLMMessagesToCompletionTransformationHandler: ) -> Union[AnthropicMessagesResponse, AsyncIterator[Any], Iterator[bytes]]: """Handle non-Anthropic models asynchronously using the adapter""" context_management = kwargs.pop("context_management", None) - drop_params: Optional[bool] = kwargs.get("drop_params", None) + additional_drop_params: Optional[list[str]] = kwargs.get("additional_drop_params", None) litellm_router = kwargs.pop("litellm_router", None) if litellm_router is None: try: @@ -555,7 +568,7 @@ class LiteLLMMessagesToCompletionTransformationHandler: system=system, context_management_spec=context_management, litellm_metadata=proxy_litellm_metadata, - drop_params=drop_params, + additional_drop_params=additional_drop_params, llm_router=litellm_router, user_api_key_auth=user_api_key_auth, ) @@ -661,7 +674,7 @@ class LiteLLMMessagesToCompletionTransformationHandler: # ``compact_20260112`` editor can ``await`` the summarization model); # bridge to it via ``run_async_function``. context_management = kwargs.pop("context_management", None) - drop_params: Optional[bool] = kwargs.get("drop_params", None) + additional_drop_params: Optional[list[str]] = kwargs.get("additional_drop_params", None) # Deliberately do NOT auto-attach the proxy ``llm_router`` here: # ``run_async_function`` spawns a new event loop in a worker thread # to bridge to the async dispatcher, but the proxy router's httpx @@ -696,7 +709,7 @@ class LiteLLMMessagesToCompletionTransformationHandler: system=system, context_management_spec=context_management, litellm_metadata=proxy_litellm_metadata, - drop_params=drop_params, + additional_drop_params=additional_drop_params, llm_router=litellm_router, user_api_key_auth=user_api_key_auth, ) diff --git a/litellm/llms/anthropic/experimental_pass_through/messages/agentic_streaming_iterator.py b/litellm/llms/anthropic/experimental_pass_through/messages/agentic_streaming_iterator.py index cb37725d79c..4bf36a0d5c6 100644 --- a/litellm/llms/anthropic/experimental_pass_through/messages/agentic_streaming_iterator.py +++ b/litellm/llms/anthropic/experimental_pass_through/messages/agentic_streaming_iterator.py @@ -193,6 +193,14 @@ class AgenticAnthropicStreamingIterator: raise StopAsyncIteration + async def aclose(self) -> None: + from litellm.llms.anthropic.experimental_pass_through.messages.streaming_iterator import ( + aclose_if_supported, + ) + + await aclose_if_supported(self._inner) + await aclose_if_supported(self._follow_up_iterator) + async def _process_agentic_hooks(self) -> None: """Rebuild the Anthropic response from collected SSE bytes and call hooks.""" if self._hook_processing_done: diff --git a/litellm/llms/anthropic/experimental_pass_through/messages/handler.py b/litellm/llms/anthropic/experimental_pass_through/messages/handler.py index 9c9427c7302..dd983f0c344 100644 --- a/litellm/llms/anthropic/experimental_pass_through/messages/handler.py +++ b/litellm/llms/anthropic/experimental_pass_through/messages/handler.py @@ -61,6 +61,19 @@ def _should_route_to_responses_api(custom_llm_provider: Optional[str]) -> bool: return custom_llm_provider in _RESPONSES_API_PROVIDERS +def _deployment_passes_through_anthropic_messages(model_info: object) -> bool: + """Whether the deployment opted into forwarding /v1/messages untranslated. + + The opt-in is ``model_info.supported_endpoints`` containing ``"/v1/messages"``, + declared per deployment in config.yaml and plumbed here as ``kwargs["model_info"]`` + by the router. + """ + if not isinstance(model_info, dict): + return False + supported_endpoints = model_info.get("supported_endpoints") + return isinstance(supported_endpoints, (list, tuple)) and "/v1/messages" in supported_endpoints + + ####### ENVIRONMENT VARIABLES ################### # Initialize any necessary instances or variables here base_llm_http_handler = BaseLLMHTTPHandler() @@ -135,6 +148,7 @@ async def _try_websearch_short_circuit( tools: Optional[List[Dict]], custom_llm_provider: Optional[str], stream: Optional[bool], + kwargs: Optional[dict] = None, ) -> Optional[Union[AnthropicMessagesResponse, AsyncIterator]]: """ Attempt to short-circuit a web-search-only request. @@ -164,6 +178,7 @@ async def _try_websearch_short_circuit( messages=messages, tools=tools, custom_llm_provider=custom_llm_provider, + kwargs=kwargs, ) if response is not None: anthropic_response = cast(AnthropicMessagesResponse, response) @@ -186,7 +201,7 @@ async def anthropic_messages( metadata: Optional[Dict] = None, stop_sequences: Optional[List[str]] = None, stream: Optional[bool] = False, - system: Optional[str] = None, + system: Optional[Union[str, list]] = None, temperature: Optional[float] = None, thinking: Optional[Dict] = None, tool_choice: Optional[Dict] = None, @@ -217,6 +232,12 @@ async def anthropic_messages( # ids like ``functions.Bash:0`` that violate Anthropic's id pattern. messages = sanitize_tool_use_ids_in_anthropic_messages(messages) + from litellm.integrations.anthropic_cache_control_hook import ( + AnthropicCacheControlHook, + ) + + messages, system = AnthropicCacheControlHook.maybe_inject_cache_control(messages, system, kwargs) + original_stream = stream or kwargs.get("_websearch_interception_converted_stream", False) # Execute pre-request hooks to allow CustomLoggers to modify request. @@ -273,6 +294,7 @@ async def anthropic_messages( tools=tools, custom_llm_provider=custom_llm_provider, stream=original_stream, + kwargs={**kwargs, "metadata": metadata}, ) if short_circuit_response is not None: return short_circuit_response @@ -362,7 +384,7 @@ def anthropic_messages_handler( metadata: Optional[Dict] = None, stop_sequences: Optional[List[str]] = None, stream: Optional[bool] = False, - system: Optional[str] = None, + system: Optional[Union[str, list]] = None, temperature: Optional[float] = None, thinking: Optional[Dict] = None, tool_choice: Optional[Dict] = None, @@ -399,6 +421,12 @@ def anthropic_messages_handler( messages = strip_empty_text_blocks_from_anthropic_messages(messages) messages = sanitize_tool_use_ids_in_anthropic_messages(messages) + from litellm.integrations.anthropic_cache_control_hook import ( + AnthropicCacheControlHook, + ) + + messages, system = AnthropicCacheControlHook.maybe_inject_cache_control(messages, system, kwargs) + metadata = validate_anthropic_api_metadata(metadata) local_vars = locals() @@ -456,6 +484,14 @@ def anthropic_messages_handler( model=model, provider=litellm.LlmProviders(custom_llm_provider), ) + if anthropic_messages_provider_config is None and _deployment_passes_through_anthropic_messages( + kwargs.get("model_info") + ): + from litellm.llms.openai_like.messages.transformation import ( + OpenAILikeAnthropicMessagesConfig, + ) + + anthropic_messages_provider_config = OpenAILikeAnthropicMessagesConfig() if anthropic_messages_provider_config is None: # Route to Responses API for OpenAI / Azure, chat/completions for everything else. _shared_kwargs = dict( diff --git a/litellm/llms/anthropic/experimental_pass_through/messages/interceptors/advisor.py b/litellm/llms/anthropic/experimental_pass_through/messages/interceptors/advisor.py index 6c72b7a3e00..79faa39c7a2 100644 --- a/litellm/llms/anthropic/experimental_pass_through/messages/interceptors/advisor.py +++ b/litellm/llms/anthropic/experimental_pass_through/messages/interceptors/advisor.py @@ -17,7 +17,9 @@ How it works: import uuid from typing import Any, AsyncIterator, Dict, List, Optional, Union +import litellm import litellm.constants as _c +from litellm.litellm_core_utils.url_utils import validate_url from litellm.llms.anthropic.common_utils import strip_advisor_blocks_from_messages from litellm.types.llms.anthropic_messages.anthropic_response import ( AnthropicMessagesResponse, @@ -76,16 +78,7 @@ class AdvisorOrchestrationHandler(MessagesInterceptor): raise ValueError("advisor tool definition must include a 'model' field specifying the advisor model") _raw_max_uses = advisor_tool.get("max_uses") max_uses: int = ADVISOR_MAX_USES if _raw_max_uses is None else int(_raw_max_uses) - # Optional routing overrides for the advisor sub-call (e.g. proxy routing). - # If not set in the tool definition, litellm resolves from env vars. - # The advisor tool is caller-controlled; only honor a client-supplied - # api_base/api_key when the proxy has enabled clientside credentials, - # otherwise let litellm resolve from server config. - advisor_api_key: Optional[str] = None - advisor_api_base: Optional[str] = None - if _allow_client_side_advisor_credentials(): - advisor_api_key = advisor_tool.get("api_key") - advisor_api_base = advisor_tool.get("api_base") + advisor_api_key, advisor_api_base = _resolve_advisor_credentials(advisor_tool) # Build the synthetic tool definition the provider will receive. synthetic_advisor_tool = _make_synthetic_advisor_tool() @@ -186,6 +179,49 @@ def _allow_client_side_advisor_credentials() -> bool: return general_settings.get("allow_client_side_credentials") is True +def _resolve_advisor_credentials(advisor_tool: dict) -> tuple[Optional[str], Optional[str]]: + """Resolve the (api_key, api_base) override for the advisor sub-call. + + A caller-supplied ``api_base`` is only honored alongside a caller-supplied + ``api_key``: without one, ``AnthropicModelInfo.get_auth_header()`` falls + back to the proxy's own Anthropic credentials, which would then be sent to + the caller-chosen ``api_base``. A caller-supplied ``api_base`` is also + required to be https with TLS verification on, and SSRF-validated so it + can't target a private/internal/cloud-metadata address, mirroring + ``proxy.auth.auth_utils.check_complete_credentials``. https with TLS + verification is required because ``validate_url`` only rewrites the + connection to a DNS-pinned IP for http, or for https with + ``litellm.ssl_verify`` disabled; otherwise it returns the URL unchanged + and relies on certificate validation to block DNS rebinding, so this + closes the same gap without threading the pinned URL through the whole + ``anthropic_messages()`` call chain. + """ + if not _allow_client_side_advisor_credentials(): + return None, None + api_key: Optional[str] = advisor_tool.get("api_key") + api_base: Optional[str] = advisor_tool.get("api_base") + if api_base is None: + return api_key, None + if not api_key: + raise ValueError( + "advisor tool definition sets 'api_base' without 'api_key'. A " + "caller-supplied api_base is only honored alongside a " + "caller-supplied api_key, so the proxy's own credentials are " + "never sent to a caller-chosen destination." + ) + if not api_base.startswith("https://"): + raise ValueError(f"advisor tool definition sets 'api_base'={api_base!r}, which must use the https scheme.") + if getattr(litellm, "ssl_verify", True) is False: + raise ValueError( + "advisor tool definition sets 'api_base' but the proxy has TLS verification " + "disabled (litellm.ssl_verify=False), so a caller-supplied api_base can't be " + "safely validated against DNS rebinding." + ) + if getattr(litellm, "user_url_validation", True): + validate_url(api_base) + return api_key, api_base + + def _make_synthetic_advisor_tool() -> Dict: """Build a regular tool definition the executor provider can understand.""" return { diff --git a/litellm/llms/anthropic/experimental_pass_through/messages/streaming_iterator.py b/litellm/llms/anthropic/experimental_pass_through/messages/streaming_iterator.py index 2357960f716..5f2b23d7eca 100644 --- a/litellm/llms/anthropic/experimental_pass_through/messages/streaming_iterator.py +++ b/litellm/llms/anthropic/experimental_pass_through/messages/streaming_iterator.py @@ -1,8 +1,13 @@ import asyncio import json from datetime import datetime -from typing import Any, AsyncIterator, List, Union +from typing import Any, AsyncIterator, List, Protocol, Union, runtime_checkable +import httpx +from pydantic import TypeAdapter +from typing_extensions import TypedDict + +from litellm.litellm_core_utils.core_helpers import process_response_headers from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj from litellm.proxy.pass_through_endpoints.success_handler import ( PassThroughEndpointLogging, @@ -12,6 +17,93 @@ from litellm.types.utils import GenericStreamingChunk, ModelResponseStream GLOBAL_PASS_THROUGH_SUCCESS_HANDLER_OBJ = PassThroughEndpointLogging() +INCOMPLETE_STREAM_ERROR_MESSAGE = ( + "Provider stream ended before emitting a message_stop event; " + "the response is incomplete and any partial content (e.g. tool_use input JSON) may be truncated." +) + + +def _is_message_stop_chunk(chunk: object) -> bool: + if isinstance(chunk, dict): + return chunk.get("type") == "message_stop" + if isinstance(chunk, (bytes, bytearray)): + return any(line == b"event: message_stop" for line in chunk.splitlines()) + return False + + +def _is_provider_error_chunk(chunk: object) -> bool: + if isinstance(chunk, dict): + return chunk.get("type") == "error" + if isinstance(chunk, (bytes, bytearray)): + return any(line == b"event: error" for line in chunk.splitlines()) + return False + + +def _is_terminal_stream_chunk(chunk: object) -> bool: + return _is_message_stop_chunk(chunk) or _is_provider_error_chunk(chunk) + + +def _incomplete_stream_error_sse_event() -> bytes: + payload = json.dumps( + { + "type": "error", + "error": {"type": "api_error", "message": INCOMPLETE_STREAM_ERROR_MESSAGE}, + } + ) + return f"event: error\ndata: {payload}\n\n".encode() + + +class AnthropicMessagesStreamHiddenParams(TypedDict): + additional_headers: dict[str, str] + + +@runtime_checkable +class SupportsAclose(Protocol): + async def aclose(self) -> None: ... + + +async def aclose_if_supported(stream: object) -> None: + if isinstance(stream, SupportsAclose): + await stream.aclose() + + +_RESPONSE_HEADERS_ADAPTER: TypeAdapter[dict[str, str]] = TypeAdapter(dict[str, str]) + + +def anthropic_messages_stream_hidden_params( + response_headers: httpx.Headers, +) -> AnthropicMessagesStreamHiddenParams: + return AnthropicMessagesStreamHiddenParams( + additional_headers=_RESPONSE_HEADERS_ADAPTER.validate_python(process_response_headers(response_headers)) + ) + + +class AnthropicMessagesStreamingResponse: + """ + Wraps the /v1/messages SSE byte stream so upstream provider response + headers (e.g. Bedrock's x-amzn-requestid / x-amzn-trace-id) survive as + ``_hidden_params["additional_headers"]``, which the proxy forwards to + clients as ``llm_provider-*`` response headers. Bare async generators + cannot carry attributes, so header context was previously dropped. + """ + + def __init__( + self, + completion_stream: AsyncIterator[bytes], + hidden_params: AnthropicMessagesStreamHiddenParams, + ) -> None: + self.completion_stream = completion_stream + self._hidden_params = hidden_params + + def __aiter__(self) -> "AnthropicMessagesStreamingResponse": + return self + + async def __anext__(self) -> bytes: + return await self.completion_stream.__anext__() + + async def aclose(self) -> None: + await aclose_if_supported(self.completion_stream) + class BaseAnthropicMessagesStreamingIterator: """ @@ -102,13 +194,18 @@ class BaseAnthropicMessagesStreamingIterator: This method provides the common logic for both Anthropic and Bedrock implementations. """ collected_chunks = [] + saw_terminal_event = False async for chunk in completion_stream: if self.completion_start_time is None: self.completion_start_time = datetime.now() + saw_terminal_event = saw_terminal_event or _is_terminal_stream_chunk(chunk) encoded_chunk = self._convert_chunk_to_sse_format(chunk) collected_chunks.append(encoded_chunk) yield encoded_chunk + if not saw_terminal_event: + yield _incomplete_stream_error_sse_event() + # Handle logging after all chunks are processed await self._handle_streaming_logging(collected_chunks) diff --git a/litellm/llms/anthropic/files/transformation.py b/litellm/llms/anthropic/files/transformation.py index cf12ad9ab32..0fa01e09492 100644 --- a/litellm/llms/anthropic/files/transformation.py +++ b/litellm/llms/anthropic/files/transformation.py @@ -39,6 +39,7 @@ from ..common_utils import AnthropicError, AnthropicModelInfo ANTHROPIC_FILES_API_BASE = "https://api.anthropic.com" ANTHROPIC_FILES_BETA_HEADER = "files-api-2025-04-14" +ANTHROPIC_MESSAGE_BATCH_ID_PREFIX = "msgbatch_" class AnthropicFilesConfig(BaseFilesConfig): @@ -258,6 +259,8 @@ class AnthropicFilesConfig(BaseFilesConfig): file_id = file_content_request.get("file_id") api_base = AnthropicModelInfo.get_api_base(litellm_params.get("api_base")) or ANTHROPIC_FILES_API_BASE encoded_file_id = encode_url_path_segment(file_id, field_name="file_id") + if file_id.startswith(ANTHROPIC_MESSAGE_BATCH_ID_PREFIX): + return f"{api_base.rstrip('/')}/v1/messages/batches/{encoded_file_id}/results", {} return f"{api_base.rstrip('/')}/v1/files/{encoded_file_id}/content", {} def transform_file_content_response( diff --git a/litellm/llms/azure/responses/transformation.py b/litellm/llms/azure/responses/transformation.py index fef9b7d0154..d0b0dbb070d 100644 --- a/litellm/llms/azure/responses/transformation.py +++ b/litellm/llms/azure/responses/transformation.py @@ -205,7 +205,7 @@ class AzureOpenAIResponsesAPIConfig(OpenAIResponsesAPIConfig): ######################################################### ########## DELETE RESPONSE API TRANSFORMATION ############## ######################################################### - def _construct_url_for_response_id_in_path(self, api_base: str, response_id: str) -> str: + def _construct_url_for_response_id_in_path(self, api_base: str, response_id: str, path_suffix: str = "") -> str: """ Constructs a URL for the API request with the response_id in the path. """ @@ -218,14 +218,14 @@ class AzureOpenAIResponsesAPIConfig(OpenAIResponsesAPIConfig): # Remove trailing slash if present to avoid double slashes path = parsed_url.path.rstrip("/") encoded_response_id = encode_url_path_segment(response_id, field_name="response_id") - new_path = f"{path}/{encoded_response_id}" + new_path = f"{path}/{encoded_response_id}{path_suffix}" # Reconstruct the URL with all original components but with the modified path constructed_url = urlunparse( ( parsed_url.scheme, # http, https parsed_url.netloc, # domain name, port - new_path, # path with response_id added + new_path, parsed_url.params, # parameters parsed_url.query, # query string parsed_url.fragment, # fragment @@ -288,7 +288,9 @@ class AzureOpenAIResponsesAPIConfig(OpenAIResponsesAPIConfig): limit: int = 20, order: Literal["asc", "desc"] = "desc", ) -> Tuple[str, Dict]: - url = self._construct_url_for_response_id_in_path(api_base=api_base, response_id=response_id) + "/input_items" + url = self._construct_url_for_response_id_in_path( + api_base=api_base, response_id=response_id, path_suffix="/input_items" + ) params: Dict[str, Any] = {} if after is not None: params["after"] = after @@ -322,27 +324,8 @@ class AzureOpenAIResponsesAPIConfig(OpenAIResponsesAPIConfig): This function handles URLs with query parameters by inserting the response_id at the correct location (before any query parameters). """ - from urllib.parse import urlparse, urlunparse - - # Parse the URL to separate its components - parsed_url = urlparse(api_base) - - # Insert the response_id and /cancel at the end of the path component - # Remove trailing slash if present to avoid double slashes - path = parsed_url.path.rstrip("/") - encoded_response_id = encode_url_path_segment(response_id, field_name="response_id") - new_path = f"{path}/{encoded_response_id}/cancel" - - # Reconstruct the URL with all original components but with the modified path - cancel_url = urlunparse( - ( - parsed_url.scheme, # http, https - parsed_url.netloc, # domain name, port - new_path, # path with response_id and /cancel added - parsed_url.params, # parameters - parsed_url.query, # query string - parsed_url.fragment, # fragment - ) + cancel_url = self._construct_url_for_response_id_in_path( + api_base=api_base, response_id=response_id, path_suffix="/cancel" ) data: Dict = {} diff --git a/litellm/llms/azure_ai/ocr/common_utils.py b/litellm/llms/azure_ai/ocr/common_utils.py index d1d5b80b78d..14b77338fd7 100644 --- a/litellm/llms/azure_ai/ocr/common_utils.py +++ b/litellm/llms/azure_ai/ocr/common_utils.py @@ -13,6 +13,17 @@ if TYPE_CHECKING: from litellm.llms.base_llm.ocr.transformation import BaseOCRConfig +def is_azure_document_intelligence_model(model: str) -> bool: + """Whether an azure_ai OCR model routes to Azure Document Intelligence. + + Azure AI exposes two OCR services on the same provider; the sub-route in the + model name (`azure_ai/doc-intelligence/`) selects Document Intelligence + over Mistral OCR. This is the single source of truth for that routing decision. + """ + lowered = model.lower() + return "doc-intelligence" in lowered or "documentintelligence" in lowered + + def get_azure_ai_ocr_config(model: str) -> Optional["BaseOCRConfig"]: """ Determine which Azure AI OCR configuration to use based on the model name. @@ -41,7 +52,7 @@ def get_azure_ai_ocr_config(model: str) -> Optional["BaseOCRConfig"]: from litellm.llms.azure_ai.ocr.transformation import AzureAIOCRConfig # Check for Azure Document Intelligence models - if "doc-intelligence" in model or "documentintelligence" in model: + if is_azure_document_intelligence_model(model): verbose_logger.debug(f"Routing {model} to Azure Document Intelligence OCR config") return AzureDocumentIntelligenceOCRConfig() diff --git a/litellm/llms/azure_ai/ocr/document_intelligence/transformation.py b/litellm/llms/azure_ai/ocr/document_intelligence/transformation.py index c67703f64d7..7d915892a28 100644 --- a/litellm/llms/azure_ai/ocr/document_intelligence/transformation.py +++ b/litellm/llms/azure_ai/ocr/document_intelligence/transformation.py @@ -15,6 +15,7 @@ from typing import Any, Dict from urllib.parse import quote import httpx +from pydantic import BaseModel from litellm._logging import verbose_logger from litellm.litellm_core_utils.url_utils import SSRFError, assert_same_origin @@ -38,6 +39,30 @@ from litellm.secret_managers.main import get_secret_str AZURE_DOCUMENT_INTELLIGENCE_API_KEY_ENV_VAR = "AZURE_DOCUMENT_INTELLIGENCE_API_KEY" +class AzureDocumentIntelligenceLine(BaseModel): + content: str | None = None + + +class AzureDocumentIntelligencePage(BaseModel): + pageNumber: int | None = None + width: float | None = None + height: float | None = None + unit: str | None = None + lines: tuple[AzureDocumentIntelligenceLine, ...] = () + + +class AzureDocumentIntelligenceAnalyzeResult(BaseModel): + content: str | None = None + pages: tuple[AzureDocumentIntelligencePage, ...] = () + tables: list[dict[str, object]] | None = None + keyValuePairs: list[dict[str, object]] | None = None + + +class AzureDocumentIntelligenceOperation(BaseModel): + status: str | None = None + analyzeResult: AzureDocumentIntelligenceAnalyzeResult | None = None + + class AzureDocumentIntelligenceOCRConfig(BaseOCRConfig): """ Azure Document Intelligence OCR transformation configuration. @@ -67,11 +92,14 @@ class AzureDocumentIntelligenceOCRConfig(BaseOCRConfig): (1-based, e.g. "1-3,5,7-9"). To keep the public request shape aligned with Mistral OCR, callers pass `pages` using Mistral semantics — a list of 0-based integers — or a pre-formatted - Azure-style string. Other Mistral-specific params (e.g. + Azure-style string. Azure DI also exposes a `features` query + parameter enabling add-on capabilities (e.g. "keyValuePairs", + "languages"), passed as a list of feature names or a + comma-separated string. Other Mistral-specific params (e.g. `include_image_base64`) are not supported by Azure DI and are ignored during transformation. """ - return ["pages"] + return ["pages", "features"] def map_ocr_params( self, @@ -85,16 +113,18 @@ class AzureDocumentIntelligenceOCRConfig(BaseOCRConfig): Translates Mistral-style `pages` (list[int], 0-based) into Azure's `pages` query string (1-based, e.g. "1,2,3" or "1-3,5"). A raw string that already matches Azure's format is passed through - unchanged. + unchanged. `features` (list[str] or comma-separated string) is + normalized into Azure's comma-joined `features` query string. """ pages = non_default_params.get("pages") - if pages is None: - return optional_params - - normalized = self._normalize_pages_param(pages) - if normalized: - optional_params["pages"] = normalized - return optional_params + features = non_default_params.get("features") + normalized_pages = self._normalize_pages_param(pages) if pages is not None else "" + normalized_features = self._normalize_features_param(features) if features is not None else "" + return { + **optional_params, + **({"pages": normalized_pages} if normalized_pages else {}), + **({"features": normalized_features} if normalized_features else {}), + } @staticmethod def _normalize_pages_param(pages: Any) -> str: @@ -140,6 +170,39 @@ class AzureDocumentIntelligenceOCRConfig(BaseOCRConfig): raise ValueError("`pages` must be a list[int] (0-based, Mistral-style) or a string like '1-3,5,7-9'.") + @staticmethod + def _normalize_features_param(features: object) -> str: + """ + Convert a caller-provided `features` value to Azure DI's query-string + form (comma-joined feature names, e.g. "keyValuePairs,languages"). + + Accepted inputs: + - list[str]: feature names like ["keyValuePairs", "languages"]. + - str: a single feature name or comma-separated names. + """ + invalid_features_error = ValueError( + f"Invalid `features` for Azure Document Intelligence: {features!r}. " + f"Expected a list of feature names or a comma-separated string like " + f"'keyValuePairs' or 'keyValuePairs,languages'." + ) + + if isinstance(features, str): + raw_tokens = features.split(",") + elif isinstance(features, list): + if len(features) == 0: + return "" + raw_tokens = [feature for feature in features if isinstance(feature, str)] + if len(raw_tokens) != len(features): + raise invalid_features_error + else: + raise invalid_features_error + + tokens = tuple(token.strip() for token in raw_tokens) + feature_pattern = re.compile(r"^[A-Za-z][A-Za-z0-9]*$") + if not all(feature_pattern.match(token) for token in tokens): + raise invalid_features_error + return ",".join(tokens) + def validate_environment( self, headers: Dict, @@ -228,13 +291,15 @@ class AzureDocumentIntelligenceOCRConfig(BaseOCRConfig): f"?api-version={AZURE_DOCUMENT_INTELLIGENCE_API_VERSION}" ) - # Azure DI accepts `pages` as a query param (1-based, e.g. "1-3,5"). + # Azure DI accepts `pages` (1-based, e.g. "1-3,5") and `features` + # (comma-joined names, e.g. "keyValuePairs") as query params. # `optional_params` has already been normalized in `map_ocr_params`. pages = optional_params.get("pages") if optional_params else None - if pages: - url += f"&pages={quote(str(pages), safe=',-')}" + features = optional_params.get("features") if optional_params else None + pages_query = f"&pages={quote(str(pages), safe=',-')}" if pages else "" + features_query = f"&features={quote(str(features), safe=',')}" if features else "" - return url + return f"{url}{pages_query}{features_query}" def _extract_base64_from_data_uri(self, data_uri: str) -> str: """ @@ -328,27 +393,15 @@ class AzureDocumentIntelligenceOCRConfig(BaseOCRConfig): return OCRRequestData(data=data, files=None) - def _extract_page_markdown(self, page_data: Dict[str, Any]) -> str: - """ - Extract text from Azure DI page and format as markdown. - - Azure DI provides text in 'lines' array. We concatenate them with newlines. - - Args: - page_data: Azure DI page object - - Returns: - Markdown-formatted text - """ - lines = page_data.get("lines", []) - if not lines: - return "" - - # Extract text content from each line - text_lines = [line.get("content", "") for line in lines] - - # Join with newlines to preserve structure - return "\n".join(text_lines) + def _transform_azure_page(self, azure_page: AzureDocumentIntelligencePage) -> OCRPage: + page_number = azure_page.pageNumber if azure_page.pageNumber is not None else 1 + markdown = "\n".join(line.content or "" for line in azure_page.lines) + dimensions = self._convert_dimensions( + width=azure_page.width if azure_page.width is not None else 8.5, + height=azure_page.height if azure_page.height is not None else 11, + unit=azure_page.unit if azure_page.unit is not None else "inch", + ) + return OCRPage(index=page_number - 1, markdown=markdown, dimensions=dimensions) def _convert_dimensions(self, width: float, height: float, unit: str) -> OCRPageDimensions: """ @@ -526,6 +579,52 @@ class AzureDocumentIntelligenceOCRConfig(BaseOCRConfig): retry_after = self._get_retry_after(response=response) await asyncio.sleep(retry_after) + def _get_polling_target(self, raw_response: httpx.Response) -> tuple[str, Dict[str, str]]: + operation_url = raw_response.headers.get("Operation-Location") + if not operation_url: + raise ValueError("Azure Document Intelligence returned 202 but no Operation-Location header found") + + # Reject cross-origin polling URLs — the auth headers + # below would otherwise leak to whatever URL the upstream + # (or an attacker-controlled upstream) returns. VERIA-51. + try: + assert_same_origin(operation_url, str(raw_response.request.url)) + except SSRFError as ssrf_err: + raise ValueError(f"Azure Document Intelligence: rejected polling URL ({ssrf_err})") + + poll_headers = {"Ocp-Apim-Subscription-Key": raw_response.request.headers.get("Ocp-Apim-Subscription-Key", "")} + return operation_url, poll_headers + + def _transform_completed_response(self, model: str, raw_response: httpx.Response) -> OCRResponse: + """ + Transform a completed Azure Document Intelligence analyze operation + into the Mistral OCR response shape, preserving Azure-native + `analyzeResult` fields (`content`, `tables`, `keyValuePairs`) as + top-level response fields. + """ + operation = AzureDocumentIntelligenceOperation.model_validate(raw_response.json()) + + verbose_logger.debug(f"Azure Document Intelligence response status: {operation.status}") + + if operation.status != "succeeded": + raise ValueError(f"Azure Document Intelligence analysis failed with status: {operation.status}") + + analyze_result = ( + operation.analyzeResult if operation.analyzeResult is not None else AzureDocumentIntelligenceAnalyzeResult() + ) + mistral_pages = [self._transform_azure_page(azure_page) for azure_page in analyze_result.pages] + usage_info = OCRUsageInfo(pages_processed=len(mistral_pages), doc_size_bytes=None) + + return OCRResponse( + pages=mistral_pages, + model=model, + usage_info=usage_info, + object="ocr", + content=analyze_result.content, + tables=analyze_result.tables, + keyValuePairs=analyze_result.keyValuePairs, + ) + def transform_ocr_response( self, model: str, @@ -552,11 +651,13 @@ class AzureDocumentIntelligenceOCRConfig(BaseOCRConfig): "unit": "inch", "lines": [{"content": "text", "boundingBox": [...]}] } - ] + ], + "tables": [...], + "keyValuePairs": [...] } } - Mistral OCR format: + Mistral OCR format (with Azure-native fields preserved): { "pages": [ { @@ -567,7 +668,10 @@ class AzureDocumentIntelligenceOCRConfig(BaseOCRConfig): ], "model": "azure_ai/doc-intelligence/prebuilt-layout", "usage_info": {"pages_processed": 1}, - "object": "ocr" + "object": "ocr", + "content": "Full document text...", + "tables": [...], + "keyValuePairs": [...] } Args: @@ -578,86 +682,17 @@ class AzureDocumentIntelligenceOCRConfig(BaseOCRConfig): Returns: OCRResponse in Mistral format """ - try: - # Check if we got 202 Accepted (async operation started) - if raw_response.status_code == 202: - verbose_logger.debug("Azure DI returned 202 Accepted, polling operation...") + if raw_response.status_code != 202: + return self._transform_completed_response(model=model, raw_response=raw_response) - # Get Operation-Location header - operation_url = raw_response.headers.get("Operation-Location") - if not operation_url: - raise ValueError("Azure Document Intelligence returned 202 but no Operation-Location header found") - - # Reject cross-origin polling URLs — the auth headers - # below would otherwise leak to whatever URL the upstream - # (or an attacker-controlled upstream) returns. VERIA-51. - try: - assert_same_origin(operation_url, str(raw_response.request.url)) - except SSRFError as ssrf_err: - raise ValueError(f"Azure Document Intelligence: rejected polling URL ({ssrf_err})") - - # Get headers for polling (need auth) - poll_headers = { - "Ocp-Apim-Subscription-Key": raw_response.request.headers.get("Ocp-Apim-Subscription-Key", "") - } - - # Get timeout from kwargs or use default - timeout_secs = AZURE_OPERATION_POLLING_TIMEOUT - - # Poll until operation completes - raw_response = self._poll_operation_sync( - operation_url=operation_url, - headers=poll_headers, - timeout_secs=timeout_secs, - ) - - # Now parse the completed response - response_json = raw_response.json() - - verbose_logger.debug(f"Azure Document Intelligence response status: {response_json.get('status')}") - - # Check if request succeeded - status = response_json.get("status") - if status != "succeeded": - raise ValueError(f"Azure Document Intelligence analysis failed with status: {status}") - - # Extract analyze result - analyze_result = response_json.get("analyzeResult", {}) - azure_pages = analyze_result.get("pages", []) - - # Transform pages to Mistral format - mistral_pages = [] - for azure_page in azure_pages: - page_number = azure_page.get("pageNumber", 1) - index = page_number - 1 # Convert to 0-based index - - # Extract markdown text - markdown = self._extract_page_markdown(azure_page) - - # Convert dimensions - width = azure_page.get("width", 8.5) - height = azure_page.get("height", 11) - unit = azure_page.get("unit", "inch") - dimensions = self._convert_dimensions(width=width, height=height, unit=unit) - - # Build OCR page - ocr_page = OCRPage(index=index, markdown=markdown, dimensions=dimensions) - mistral_pages.append(ocr_page) - - # Build usage info - usage_info = OCRUsageInfo(pages_processed=len(mistral_pages), doc_size_bytes=None) - - # Return Mistral OCR response - return OCRResponse( - pages=mistral_pages, - model=model, - usage_info=usage_info, - object="ocr", - ) - - except Exception as e: - verbose_logger.error(f"Error parsing Azure Document Intelligence response: {e}") - raise e + verbose_logger.debug("Azure DI returned 202 Accepted, polling operation...") + operation_url, poll_headers = self._get_polling_target(raw_response) + completed_response = self._poll_operation_sync( + operation_url=operation_url, + headers=poll_headers, + timeout_secs=AZURE_OPERATION_POLLING_TIMEOUT, + ) + return self._transform_completed_response(model=model, raw_response=completed_response) async def async_transform_ocr_response( self, @@ -680,81 +715,14 @@ class AzureDocumentIntelligenceOCRConfig(BaseOCRConfig): Returns: OCRResponse in Mistral format """ - try: - # Check if we got 202 Accepted (async operation started) - if raw_response.status_code == 202: - verbose_logger.debug("Azure DI returned 202 Accepted, polling operation (async)...") + if raw_response.status_code != 202: + return self._transform_completed_response(model=model, raw_response=raw_response) - # Get Operation-Location header - operation_url = raw_response.headers.get("Operation-Location") - if not operation_url: - raise ValueError("Azure Document Intelligence returned 202 but no Operation-Location header found") - - # Reject cross-origin polling URLs (see sync path). VERIA-51. - try: - assert_same_origin(operation_url, str(raw_response.request.url)) - except SSRFError as ssrf_err: - raise ValueError(f"Azure Document Intelligence: rejected polling URL ({ssrf_err})") - - # Get headers for polling (need auth) - poll_headers = { - "Ocp-Apim-Subscription-Key": raw_response.request.headers.get("Ocp-Apim-Subscription-Key", "") - } - - # Get timeout from kwargs or use default - timeout_secs = AZURE_OPERATION_POLLING_TIMEOUT - - # Poll until operation completes (async) - raw_response = await self._poll_operation_async( - operation_url=operation_url, - headers=poll_headers, - timeout_secs=timeout_secs, - ) - - # Now parse the completed response - response_json = raw_response.json() - - verbose_logger.debug(f"Azure Document Intelligence response status: {response_json.get('status')}") - - # Check if request succeeded - status = response_json.get("status") - if status != "succeeded": - raise ValueError(f"Azure Document Intelligence analysis failed with status: {status}") - - # Extract analyze result - analyze_result = response_json.get("analyzeResult", {}) - azure_pages = analyze_result.get("pages", []) - - # Transform pages to Mistral format - mistral_pages = [] - for azure_page in azure_pages: - page_number = azure_page.get("pageNumber", 1) - index = page_number - 1 # Convert to 0-based index - - # Extract markdown text - markdown = self._extract_page_markdown(azure_page) - - # Convert dimensions - width = azure_page.get("width", 8.5) - height = azure_page.get("height", 11) - unit = azure_page.get("unit", "inch") - dimensions = self._convert_dimensions(width=width, height=height, unit=unit) - - # Build OCR page - ocr_page = OCRPage(index=index, markdown=markdown, dimensions=dimensions) - mistral_pages.append(ocr_page) - - # Build usage info - usage_info = OCRUsageInfo(pages_processed=len(mistral_pages), doc_size_bytes=None) - - # Return Mistral OCR response - return OCRResponse( - pages=mistral_pages, - model=model, - usage_info=usage_info, - object="ocr", - ) - - except Exception as e: - verbose_logger.error(f"Error parsing Azure Document Intelligence response (async): {e}") - raise e + verbose_logger.debug("Azure DI returned 202 Accepted, polling operation (async)...") + operation_url, poll_headers = self._get_polling_target(raw_response) + completed_response = await self._poll_operation_async( + operation_url=operation_url, + headers=poll_headers, + timeout_secs=AZURE_OPERATION_POLLING_TIMEOUT, + ) + return self._transform_completed_response(model=model, raw_response=completed_response) diff --git a/litellm/llms/base_llm/anthropic_messages/transformation.py b/litellm/llms/base_llm/anthropic_messages/transformation.py index 7f8403c0223..448c1d07009 100644 --- a/litellm/llms/base_llm/anthropic_messages/transformation.py +++ b/litellm/llms/base_llm/anthropic_messages/transformation.py @@ -103,6 +103,30 @@ class BaseAnthropicMessagesConfig(ABC): """ return headers, None + def should_filter_anthropic_beta_headers(self) -> bool: + """ + Whether ``anthropic-beta`` header values should be filtered down to the + ones the routed provider supports before the upstream request. + + Cross-provider translation paths (bedrock, vertex_ai, ...) need this so + unsupported betas are dropped. Configs that forward natively to an + Anthropic-compatible endpoint return False to pass betas through verbatim. + """ + return True + + def handles_web_search_natively(self) -> bool: + """ + Whether the upstream this config routes to executes ``web_search`` tools + itself as part of its Anthropic Messages agentic loop. + + The web-search interception handler short-circuits web-search-only + requests (running the search itself and returning synthetic results) only + for providers that do NOT. Providers whose agentic loop already performs + the search plus a follow-up synthesis step (bedrock, vertex_ai, ...) + return True so those requests flow through untouched. + """ + return True + def get_async_streaming_response_iterator( self, model: str, diff --git a/litellm/llms/base_llm/guardrail_translation/base_translation.py b/litellm/llms/base_llm/guardrail_translation/base_translation.py index 68db36b529e..6c41b46cfa0 100644 --- a/litellm/llms/base_llm/guardrail_translation/base_translation.py +++ b/litellm/llms/base_llm/guardrail_translation/base_translation.py @@ -2,7 +2,10 @@ from abc import ABC, abstractmethod from typing import TYPE_CHECKING, Any, Dict, List, Optional if TYPE_CHECKING: - from litellm.integrations.custom_guardrail import CustomGuardrail + from litellm.integrations.custom_guardrail import ( + CustomGuardrail, + ModifyResponseException, + ) from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj from litellm.proxy._types import UserAPIKeyAuth from litellm.types.llms.openai import AllMessageValues @@ -98,6 +101,30 @@ class BaseTranslation(ABC): """ return responses_so_far + def build_block_sse_chunks( + self, + exc: "ModifyResponseException", + stream_started: bool = False, + responses_so_far: Optional[list[Any]] = None, + ) -> Optional[list[bytes]]: + """ + Build the streaming chunks that deliver a guardrail block message and + cleanly terminate the stream in this provider's wire format. + + ``stream_started`` is True when real chunks were already sent to the + client: the result must *continue* the in-progress message (e.g. close + the open content block and append the block message) rather than start + a new one, which clients reject. ``responses_so_far`` provides the prior + chunks needed to do so. When False, nothing has been sent and a + standalone block message is emitted. + + Returns None when the format has no safe terminator; the caller then + re-raises ``exc`` so the proxy can surface a clean error instead. + Override in provider subclasses that support synthesizing a block + stream. + """ + return None + def get_structured_messages(self, data: dict) -> Optional[List["AllMessageValues"]]: """ Convert request data to OpenAI-spec structured messages. diff --git a/litellm/llms/base_llm/guardrail_translation/utils.py b/litellm/llms/base_llm/guardrail_translation/utils.py index 97ece6b5eab..8a06dd4ea52 100644 --- a/litellm/llms/base_llm/guardrail_translation/utils.py +++ b/litellm/llms/base_llm/guardrail_translation/utils.py @@ -1,10 +1,100 @@ from __future__ import annotations -from typing import Any, List +import json +from typing import Any, List, Optional +from litellm.types.llms.anthropic_messages.anthropic_response import AnthropicUsage from litellm.types.llms.openai import AllMessageValues +def _anthropic_stream_chunk_events(item: Any) -> list[dict]: + if isinstance(item, dict): + return [item] + if isinstance(item, bytes): + chunk = item.decode("utf-8", errors="replace") + elif isinstance(item, str): + chunk = item + else: + return [] + + events: list[dict] = [] + for block in chunk.split("\n\n"): + for line in block.splitlines(): + stripped = line.strip() + if not stripped.startswith("data:"): + continue + payload = stripped[len("data:") :].strip() + if not payload or payload == "[DONE]": + continue + try: + parsed = json.loads(payload) + except json.JSONDecodeError: + continue + if isinstance(parsed, dict): + events.append(parsed) + return events + + +def _usage_from_anthropic_stream_chunks(original_response: list[Any]) -> Optional[AnthropicUsage]: + input_tokens = 0 + output_tokens = 0 + found_usage = False + + for item in original_response: + for event in _anthropic_stream_chunk_events(item): + event_type = event.get("type") + if event_type == "message_start": + message = event.get("message") or {} + usage_obj = message.get("usage") or {} + elif event_type == "message_delta": + usage_obj = event.get("usage") or {} + else: + usage_obj = {} + if not isinstance(usage_obj, dict): + continue + if usage_obj.get("input_tokens") is not None: + input_tokens = int(usage_obj.get("input_tokens") or 0) + found_usage = True + if usage_obj.get("output_tokens") is not None: + output_tokens = int(usage_obj.get("output_tokens") or 0) + found_usage = True + + if not found_usage: + return None + return AnthropicUsage(input_tokens=input_tokens, output_tokens=output_tokens) + + +def blocked_response_usage(original_response: Optional[Any]) -> AnthropicUsage: + """ + Token usage for a synthetic guardrail-blocked response. + + A post-call block replaces the LLM's response with the violation message, + but the upstream call already consumed tokens -- report that real usage + (carried on ``ModifyResponseException.original_response``) rather than + discarding it. Pre-call blocks never invoked the LLM (no original_response), + so usage is zero. + """ + usage_obj: Any = None + if isinstance(original_response, list): + stream_usage = _usage_from_anthropic_stream_chunks(original_response) + if stream_usage is not None: + return stream_usage + elif isinstance(original_response, dict): + usage_obj = original_response.get("usage") + elif original_response is not None: + usage_obj = getattr(original_response, "usage", None) + + def _tokens(key: str, fallback_key: str) -> int: + if isinstance(usage_obj, dict): + return int(usage_obj.get(key, usage_obj.get(fallback_key, 0)) or 0) + return int(getattr(usage_obj, key, getattr(usage_obj, fallback_key, 0)) or 0) + + return AnthropicUsage( + input_tokens=_tokens("input_tokens", "prompt_tokens"), + output_tokens=_tokens("output_tokens", "completion_tokens"), + ) + + def effective_skip_system_message_for_guardrail(guardrail_to_apply: Any) -> bool: per = getattr(guardrail_to_apply, "skip_system_message_in_guardrail", None) if per is not None: diff --git a/litellm/llms/base_llm/ocr/transformation.py b/litellm/llms/base_llm/ocr/transformation.py index a38e5bfdcd6..0d878bd308c 100644 --- a/litellm/llms/base_llm/ocr/transformation.py +++ b/litellm/llms/base_llm/ocr/transformation.py @@ -70,6 +70,9 @@ class OCRResponse(LiteLLMPydanticObjectBase): model: str document_annotation: Any | None = None usage_info: OCRUsageInfo | None = None + content: str | None = None + tables: list[dict[str, object]] | None = None + keyValuePairs: list[dict[str, object]] | None = None object: str = "ocr" model_config = {"extra": "allow"} diff --git a/litellm/llms/bedrock/base_aws_llm.py b/litellm/llms/bedrock/base_aws_llm.py index 380cc91ed98..f449851b76f 100644 --- a/litellm/llms/bedrock/base_aws_llm.py +++ b/litellm/llms/bedrock/base_aws_llm.py @@ -50,6 +50,8 @@ _STS_REGION_FROM_ENDPOINT_PATTERN = re.compile( r"(?:^|\.)sts(?:-fips)?\.([a-z0-9-]+)\.(?:amazonaws\.com(?:\.cn)?|vpce\.amazonaws\.com)" ) +SIGV4_COMPUTED_HEADERS = frozenset({"authorization", "x-amz-date", "x-amz-security-token", "date"}) + class Boto3CredentialsInfo(BaseModel): credentials: Credentials @@ -1400,11 +1402,13 @@ class BaseAWSLLM: # Add back all original headers (including forwarded ones) after signature calculation for header_name, header_value in headers.items(): - if header_value is not None: + if header_value is not None and header_name.lower() not in SIGV4_COMPUTED_HEADERS: request.headers[header_name] = header_value if ( - extra_headers is not None and "Authorization" in extra_headers + extra_headers is not None + and "Authorization" in extra_headers + and not extra_headers["Authorization"].startswith("AWS4-HMAC-SHA256") ): # prevent sigv4 from overwriting the auth header request.headers["Authorization"] = extra_headers["Authorization"] prepped = request.prepare() @@ -1527,9 +1531,15 @@ class BaseAWSLLM: # Add back original headers after signing. Only headers in SignedHeaders # are integrity-protected; forwarded headers (x-forwarded-*) must remain unsigned. for header_name, header_value in headers.items(): - if header_value is not None: + if header_value is not None and header_name.lower() not in SIGV4_COMPUTED_HEADERS: request_headers_dict[header_name] = header_value - if headers is not None and "Authorization" in headers: # prevent sigv4 from overwriting the auth header - request_headers_dict["Authorization"] = headers["Authorization"] + incoming_authorization = next( + (value for name, value in headers.items() if name.lower() == "authorization" and value is not None), + None, + ) + if incoming_authorization is not None and not incoming_authorization.startswith( + "AWS4-HMAC-SHA256" + ): # prevent sigv4 from overwriting the auth header + request_headers_dict["Authorization"] = incoming_authorization return request_headers_dict, request.body diff --git a/litellm/llms/bedrock/chat/converse_transformation.py b/litellm/llms/bedrock/chat/converse_transformation.py index b135a116753..5a8ada45651 100644 --- a/litellm/llms/bedrock/chat/converse_transformation.py +++ b/litellm/llms/bedrock/chat/converse_transformation.py @@ -76,6 +76,7 @@ from litellm.utils import ( from ..common_utils import ( BedrockError, BedrockModelInfo, + bedrock_converse_supports_parallel_tool_use_config, get_anthropic_beta_from_headers, get_bedrock_tool_name, is_claude_4_5_on_bedrock, @@ -1106,18 +1107,28 @@ class AmazonConverseConfig(BaseConfig): if cache_control is None: return None - cache_point = CachePointBlock(type="default") - if isinstance(cache_control, dict) and "ttl" in cache_control: - ttl = cache_control["ttl"] - if ttl in ["5m", "1h"] and model is not None: - if is_claude_4_5_on_bedrock(model): - cache_point["ttl"] = ttl + cache_point = self._build_cache_point_block(cache_control, model) if block_type == "system": return SystemContentBlock(cachePoint=cache_point) else: return ContentBlock(cachePoint=cache_point) + @staticmethod + def _build_cache_point_block(control: Optional[dict], model: Optional[str] = None) -> CachePointBlock: + """Build a Bedrock ``cachePoint`` block from an OpenAI-style ``cache_control``/``control`` dict. + + ``type`` is always ``"default"`` (the only value Bedrock's Converse API + accepts). ``ttl`` is only honored for models that support extended TTL + caching (Claude 4.5 family on Bedrock). + """ + cache_point = CachePointBlock(type="default") + if isinstance(control, dict) and "ttl" in control: + ttl = control["ttl"] + if ttl in ["5m", "1h"] and model is not None and is_claude_4_5_on_bedrock(model): + cache_point["ttl"] = ttl + return cache_point + def _transform_system_message( self, messages: List[AllMessageValues], model: Optional[str] = None ) -> Tuple[List[AllMessageValues], List[SystemContentBlock]]: @@ -1241,7 +1252,7 @@ class AmazonConverseConfig(BaseConfig): # Handle parallel_tool_calls configuration parallel_tool_use_config = additional_request_params.pop("_parallel_tool_use_config", None) - if parallel_tool_use_config is not None and is_claude_4_5_on_bedrock(model): + if parallel_tool_use_config is not None and bedrock_converse_supports_parallel_tool_use_config(model): for key, value in parallel_tool_use_config.items(): if ( key in additional_request_params @@ -1526,7 +1537,8 @@ class AmazonConverseConfig(BaseConfig): if cache_injection_points and len(bedrock_tools) > 0: for point in cache_injection_points: if point.get("location") == "tool_config": - bedrock_tools.append({"cachePoint": {"type": "default"}}) + cache_point = self._build_cache_point_block(point.get("control"), model) + bedrock_tools.append(ToolBlock(cachePoint=cache_point)) break bedrock_tool_config: Optional[ToolConfigBlock] = None diff --git a/litellm/llms/bedrock/chat/invoke_handler.py b/litellm/llms/bedrock/chat/invoke_handler.py index b381b5a85fe..4c256be1ab8 100644 --- a/litellm/llms/bedrock/chat/invoke_handler.py +++ b/litellm/llms/bedrock/chat/invoke_handler.py @@ -1558,7 +1558,7 @@ class AWSEventStreamDecoder: text = chunk_data["outputText"] # ai21 mapping elif "ai21" in self.model: # fake ai21 streaming - text = chunk_data.get("completions")[0].get("data").get("text") # type: ignore + text = chunk_data["completions"][0]["data"]["text"] is_finished = True finish_reason = "stop" ######## /bedrock/converse mappings ############### diff --git a/litellm/llms/bedrock/chat/invoke_transformations/amazon_qwen2_transformation.py b/litellm/llms/bedrock/chat/invoke_transformations/amazon_qwen2_transformation.py index d63642c806f..a2aa98d6676 100644 --- a/litellm/llms/bedrock/chat/invoke_transformations/amazon_qwen2_transformation.py +++ b/litellm/llms/bedrock/chat/invoke_transformations/amazon_qwen2_transformation.py @@ -51,10 +51,7 @@ class AmazonQwen2Config(AmazonQwen3Config): Qwen2 uses "text" field, but we also support "generation" field for compatibility. """ try: - if hasattr(raw_response, "json"): - response_data = raw_response.json() - else: - response_data = raw_response + response_data = raw_response.json() # Extract the generated text - Qwen2 uses "text" field, but also support "generation" for compatibility generated_text = response_data.get("generation", "") or response_data.get("text", "") diff --git a/litellm/llms/bedrock/chat/invoke_transformations/amazon_qwen3_transformation.py b/litellm/llms/bedrock/chat/invoke_transformations/amazon_qwen3_transformation.py index 762631cac5e..4f496df084e 100644 --- a/litellm/llms/bedrock/chat/invoke_transformations/amazon_qwen3_transformation.py +++ b/litellm/llms/bedrock/chat/invoke_transformations/amazon_qwen3_transformation.py @@ -175,10 +175,7 @@ class AmazonQwen3Config(AmazonInvokeConfig, BaseConfig): Transform Qwen3 Bedrock response to OpenAI format """ try: - if hasattr(raw_response, "json"): - response_data = raw_response.json() - else: - response_data = raw_response + response_data = raw_response.json() # Extract the generated text - Qwen3 uses "generation" field generated_text = response_data.get("generation", "") diff --git a/litellm/llms/bedrock/chat/invoke_transformations/base_invoke_transformation.py b/litellm/llms/bedrock/chat/invoke_transformations/base_invoke_transformation.py index 8eaa798ddac..35907bbbd16 100644 --- a/litellm/llms/bedrock/chat/invoke_transformations/base_invoke_transformation.py +++ b/litellm/llms/bedrock/chat/invoke_transformations/base_invoke_transformation.py @@ -5,6 +5,7 @@ from functools import partial from typing import TYPE_CHECKING, Any, List, Optional, Tuple, Union, cast, get_args import httpx +from pydantic import TypeAdapter, ValidationError import litellm from litellm._logging import verbose_logger @@ -27,6 +28,7 @@ from litellm.llms.custom_httpx.http_handler import ( HTTPHandler, _get_httpx_client, ) +from litellm.types.llms.bedrock import GuardrailConfigBlock from litellm.types.llms.openai import AllMessageValues from litellm.types.utils import ModelResponse, Usage from litellm.utils import CustomStreamWrapper @@ -40,6 +42,38 @@ else: from litellm.llms.bedrock.base_aws_llm import BaseAWSLLM +_GUARDRAIL_CONFIG_VALIDATOR: "TypeAdapter[GuardrailConfigBlock]" = TypeAdapter(GuardrailConfigBlock) + +_GUARDRAIL_CONFIG_EXPECTED_FORMAT = ( + "{'guardrailIdentifier': str, 'guardrailVersion': str, 'trace': 'enabled'|'disabled'|'enabled_full'}" +) + + +def _bedrock_invoke_guardrail_headers(raw_guardrail_config: object) -> "dict[str, str]": + try: + guardrail_config = _GUARDRAIL_CONFIG_VALIDATOR.validate_python(raw_guardrail_config) + except ValidationError as e: + raise BedrockError( + status_code=400, + message="Invalid guardrailConfig={}. Expected format: {}. Error: {}".format( + raw_guardrail_config, _GUARDRAIL_CONFIG_EXPECTED_FORMAT, e + ), + ) + if "guardrailIdentifier" not in guardrail_config: + raise BedrockError( + status_code=400, + message="guardrailConfig={} is missing 'guardrailIdentifier'. Expected format: {}".format( + raw_guardrail_config, _GUARDRAIL_CONFIG_EXPECTED_FORMAT + ), + ) + trace = guardrail_config.get("trace") + candidate_headers = { + "X-Amzn-Bedrock-GuardrailIdentifier": guardrail_config.get("guardrailIdentifier"), + "X-Amzn-Bedrock-GuardrailVersion": guardrail_config.get("guardrailVersion"), + "X-Amzn-Bedrock-Trace": trace.upper() if trace is not None else None, + } + return {name: value for name, value in candidate_headers.items() if value is not None} + class AmazonInvokeConfig(BaseConfig, BaseAWSLLM): def __init__(self, **kwargs): @@ -422,7 +456,16 @@ class AmazonInvokeConfig(BaseConfig, BaseAWSLLM): api_key: Optional[str] = None, api_base: Optional[str] = None, ) -> dict: - return headers + raw_guardrail_config = optional_params.pop("guardrailConfig", None) + if raw_guardrail_config is None: + return headers + existing_header_names = frozenset(name.lower() for name in headers) + guardrail_headers = { + name: value + for name, value in _bedrock_invoke_guardrail_headers(raw_guardrail_config).items() + if name.lower() not in existing_header_names + } + return {**headers, **guardrail_headers} def get_error_class( self, error_message: str, status_code: int, headers: Union[dict, httpx.Headers] diff --git a/litellm/llms/bedrock/chat/mantle/transformation.py b/litellm/llms/bedrock/chat/mantle/transformation.py index d84e077c37b..d7ffff65ff0 100644 --- a/litellm/llms/bedrock/chat/mantle/transformation.py +++ b/litellm/llms/bedrock/chat/mantle/transformation.py @@ -7,13 +7,14 @@ The bedrock-mantle endpoint uses the Anthropic Messages API format but is served at a different endpoint (bedrock-mantle.{region}.api.aws) with AWS SigV4 auth. """ -from typing import TYPE_CHECKING, Any, List, Optional +from typing import TYPE_CHECKING, Any, AsyncIterator, Iterator, List, Optional from litellm.llms.bedrock.chat.invoke_transformations.anthropic_claude3_transformation import ( AmazonAnthropicClaudeConfig, ) from litellm.llms.bedrock.common_utils import build_mantle_messages_url from litellm.types.llms.openai import AllMessageValues +from litellm.types.utils import ModelResponse if TYPE_CHECKING: from litellm.litellm_core_utils.litellm_logging import Logging as _LiteLLMLoggingObj @@ -91,10 +92,14 @@ class AmazonMantleConfig(AmazonAnthropicClaudeConfig): litellm_params=litellm_params, headers=headers, ) - # The parent strips "model" from the body (Invoke API puts it in URL). - # The mantle endpoint (Messages API) requires "model" in the body. - request["model"] = model_id - return request + # The parent strips "model" and "stream" from the body (Invoke API puts + # the model in the URL and streams via a dedicated endpoint). The mantle + # endpoint (Messages API) requires both in the body. + return self._restore_mantle_body_fields( + request=request, + model_id=model_id, + optional_params=optional_params, + ) async def async_transform_request( self, @@ -114,5 +119,31 @@ class AmazonMantleConfig(AmazonAnthropicClaudeConfig): headers=headers, ) await self._async_convert_document_url_sources_to_base64(request) - request["model"] = model_id - return request + return self._restore_mantle_body_fields( + request=request, + model_id=model_id, + optional_params=optional_params, + ) + + @staticmethod + def _restore_mantle_body_fields(request: dict, model_id: str, optional_params: dict) -> dict: + stream_fields: dict = {"stream": True} if optional_params.get("stream") is True else {} + return {**request, "model": model_id, **stream_fields} + + @property + def has_custom_stream_wrapper(self) -> bool: + return False + + def get_model_response_iterator( + self, + streaming_response: Iterator[str] | AsyncIterator[str] | ModelResponse, + sync_stream: bool, + json_mode: Optional[bool] = False, + ) -> Any: + from litellm.llms.anthropic.chat.handler import ModelResponseIterator + + return ModelResponseIterator( + streaming_response=streaming_response, + sync_stream=sync_stream, + json_mode=json_mode, + ) diff --git a/litellm/llms/bedrock/common_utils.py b/litellm/llms/bedrock/common_utils.py index 467e1050c99..5114677ffc0 100644 --- a/litellm/llms/bedrock/common_utils.py +++ b/litellm/llms/bedrock/common_utils.py @@ -4,9 +4,11 @@ from __future__ import annotations Common utilities used across bedrock chat/embedding/image generation """ +import contextlib import functools import json import os +import re from typing import ( TYPE_CHECKING, Any, @@ -683,39 +685,72 @@ def get_bedrock_base_model(model: str) -> str: return model +def bedrock_converse_supports_parallel_tool_use_config(model: str) -> bool: + return any( + (litellm.model_cost.get(candidate) or {}).get("supports_parallel_tool_use_config") is True + for candidate in (model, get_bedrock_base_model(model)) + ) + + def is_claude_4_5_on_bedrock(model: str) -> bool: """ - Check if the model is a Claude 4.5 model on Bedrock. - Claude 4.5 models support prompt caching with '5m' and '1h' TTL on Bedrock. + Check if the model supports Bedrock prompt caching with an extended '1h' TTL + (in addition to the default 5m TTL). + + Backed by the ``cache_creation_input_token_cost_above_1hr`` field in + ``model_prices_and_context_window.json`` instead of a hardcoded list of + model-name patterns, so newly released models pick up support as soon as + their pricing entry ships, with no code change required here. """ - model_lower = model.lower() - claude_4_5_patterns = [ - "sonnet-4.5", - "sonnet_4.5", - "sonnet-4-5", - "sonnet_4_5", - "haiku-4.5", - "haiku_4.5", - "haiku-4-5", - "haiku_4_5", - "opus-4.5", - "opus_4.5", - "opus-4-5", - "opus_4_5", - "sonnet-4.6", - "sonnet_4.6", - "sonnet-4-6", - "sonnet_4_6", - "opus-4.6", - "opus_4.6", - "opus-4-6", - "opus_4_6", - "opus-4.7", - "opus_4.7", - "opus-4-7", - "opus_4_7", - ] - return any(pattern in model_lower for pattern in claude_4_5_patterns) + return any( + (litellm.model_cost.get(candidate) or {}).get("cache_creation_input_token_cost_above_1hr") is not None + for candidate in (model, get_bedrock_base_model(model)) + ) + + +_BEDROCK_MODEL_VERSION_SUFFIX_RE = re.compile(r"-v\d+(?::\d+)?$") + + +def bedrock_converse_supports_strict_tools(model: str) -> bool: + """ + Whether ``toolSpec.strict`` can be forwarded to Bedrock Converse for ``model``. + + Non-Anthropic Bedrock families (Nova, Llama, GPT-OSS) reject the field + outright. Anthropic models forward it unless their entry in + ``model_prices_and_context_window.json`` sets + ``bedrock_converse_supports_strict_tools: false`` — Bedrock routes those + (Opus 4.7/4.8, see #31582) through a stricter validator that rejects the + ``strict`` key on ``toolSpec`` even though Anthropic's native API accepts + it as a top-level tool field. + """ + base = get_bedrock_base_model(model) + if not base.startswith("anthropic"): + return False + flag = _get_bedrock_converse_strict_tools_flag(base) + return flag if flag is not None else True + + +def _get_bedrock_converse_strict_tools_flag(base_model: str) -> Optional[bool]: + candidates = dict.fromkeys((base_model, _BEDROCK_MODEL_VERSION_SUFFIX_RE.sub("", base_model))) + for candidate in candidates: + with contextlib.suppress(Exception): + model_info = get_cached_model_info()( + model=candidate, + custom_llm_provider="bedrock", + ) + + flag = model_info.get("bedrock_converse_supports_strict_tools") + if isinstance(flag, bool): + return flag + + model_cost_key = model_info.get("key") + if isinstance(model_cost_key, str): + local_flag = ( + _get_local_model_cost_map().get(model_cost_key, {}).get("bedrock_converse_supports_strict_tools") + ) + if isinstance(local_flag, bool): + return local_flag + return None def normalize_bedrock_opus_output_config_effort(model: str, output_config: Any) -> None: diff --git a/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py b/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py index f5309d521a9..155fba008d4 100644 --- a/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py +++ b/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py @@ -94,25 +94,30 @@ class AmazonAnthropicClaudeMessagesConfig( return [value] def _normalize_system_role_messages_for_bedrock(self, anthropic_messages_request: dict) -> None: - """Bedrock Invoke rejects ``role: "system"`` entries inside ``messages`` on - some Claude aliases; Anthropic Messages carries that content in the - top-level ``system`` field. Move any such entries into ``system`` before - the Invoke request is built.""" + """Bedrock Invoke rejects a conversation that opens with ``role: "system"`` + entries inside ``messages`` ("messages.0: use the top-level 'system' + parameter for the initial system prompt"); Anthropic Messages carries that + content in the top-level ``system`` field, so hoist the leading run of + system entries there. Mid-conversation system entries (e.g. Claude Code's + ``mid-conversation-system-2026-04-07`` reminders) are accepted by Invoke in + place and MUST stay in place: hoisting one mutates the ``system`` prefix + and invalidates the prompt cache for the entire message history. + Billing-header system blocks are stripped from the top-level ``system`` + field regardless of whether anything was hoisted.""" messages = anthropic_messages_request.get("messages") if not isinstance(messages, list): return - system_role_messages = [m for m in messages if isinstance(m, dict) and m.get("role") == "system"] - if not system_role_messages: - return - - anthropic_messages_request["messages"] = [ - m for m in messages if not (isinstance(m, dict) and m.get("role") == "system") - ] + leading_count = next( + (i for i, m in enumerate(messages) if not (isinstance(m, dict) and m.get("role") == "system")), + len(messages), + ) + if leading_count: + anthropic_messages_request["messages"] = messages[leading_count:] system_content = [ block for source in ( anthropic_messages_request.get("system"), - *(m.get("content") for m in system_role_messages), + *(m.get("content") for m in messages[:leading_count]), ) for block in self._as_system_content_blocks(source) ] @@ -489,24 +494,43 @@ class AmazonAnthropicClaudeMessagesConfig( if self._supports_tool_search_on_bedrock(model): beta_set.add("tool-search-tool-2025-10-19") + # Bedrock-InvokeModel-supported ``context_management.edits`` types and the + # ``anthropic-beta`` header that each one requires. ``clear_thinking_20251015`` + # is intentionally absent — it is LiteLLM-internal, consumed via + # ``_ensure_thinking_for_clear_thinking_context_management``, and forwarding + # the raw edit trips Bedrock's + # ``"context_management: Extra inputs are not permitted"`` 400. + # + # Bedrock InvokeModel DOES support ``clear_tool_uses_20250919`` under the + # ``context-management-2025-06-27`` beta. AWS docs: + # https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages-tool-use.md + _BEDROCK_INVOKE_SUPPORTED_CONTEXT_MANAGEMENT_EDITS: Dict[str, str] = { + "compact_20260112": ANTHROPIC_BETA_HEADER_VALUES.COMPACT_2026_01_12.value, + "clear_tool_uses_20250919": ANTHROPIC_BETA_HEADER_VALUES.CONTEXT_MANAGEMENT_2025_06_27.value, + } + @staticmethod def _filter_context_management_for_bedrock_invoke( anthropic_messages_request: Dict, beta_set: set, ) -> None: """ - Bedrock InvokeModel accepts ``context_management`` only when it carries - ``compact_20260112`` edits paired with the ``compact-2026-01-12`` - anthropic-beta header. Other edit types (notably ``clear_thinking_20251015``, - which Claude Code sends on every request) are LiteLLM-internal and would - cause Bedrock to 400 with ``"context_management: Extra inputs are not - permitted"``. + Filter ``context_management.edits`` to the subset that Bedrock InvokeModel + accepts and add the matching ``anthropic-beta`` header for each surviving + edit type. - Filter the edits list to the supported subset, add the beta header when - compact edits remain, and drop ``context_management`` entirely when no - supported edits are left so the safety-net allowlist can pass it through. + - ``compact_20260112`` -> ``compact-2026-01-12`` + - ``clear_tool_uses_20250919`` -> ``context-management-2025-06-27`` - Ref: https://github.com/BerriAI/litellm/issues/27532 + Other edit types (notably ``clear_thinking_20251015``, which Claude Code + sends on every request) are LiteLLM-internal: thinking is injected + separately via ``_ensure_thinking_for_clear_thinking_context_management``, + and forwarding the raw edit would trip Bedrock's + ``"context_management: Extra inputs are not permitted"`` 400. + + Refs: + * https://github.com/BerriAI/litellm/issues/27532 + * https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages-tool-use.md """ cm = anthropic_messages_request.get("context_management") if not isinstance(cm, dict): @@ -516,15 +540,17 @@ class AmazonAnthropicClaudeMessagesConfig( anthropic_messages_request.pop("context_management", None) return - compact_edits = [e for e in edits if isinstance(e, dict) and e.get("type") == "compact_20260112"] - if compact_edits: - beta_set.add(ANTHROPIC_BETA_HEADER_VALUES.COMPACT_2026_01_12.value) - anthropic_messages_request["context_management"] = { - **cm, - "edits": compact_edits, - } - else: + supported = AmazonAnthropicClaudeMessagesConfig._BEDROCK_INVOKE_SUPPORTED_CONTEXT_MANAGEMENT_EDITS + retained_edits = [e for e in edits if isinstance(e, dict) and e.get("type") in supported] + if not retained_edits: anthropic_messages_request.pop("context_management", None) + return + + beta_set.update(supported[e["type"]] for e in retained_edits) + anthropic_messages_request["context_management"] = { + **cm, + "edits": retained_edits, + } def _get_bedrock_invoke_anthropic_beta_headers( self, diff --git a/litellm/llms/bedrock/messages/mantle_transformation.py b/litellm/llms/bedrock/messages/mantle_transformation.py index a8a7b7ed1d5..da7b8697a6b 100644 --- a/litellm/llms/bedrock/messages/mantle_transformation.py +++ b/litellm/llms/bedrock/messages/mantle_transformation.py @@ -6,8 +6,13 @@ AmazonAnthropicClaudeMessagesConfig. Overrides only the URL and model-prefix stripping that are specific to the bedrock-mantle endpoint. """ -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple +from typing import TYPE_CHECKING, Any, AsyncIterator, Dict, List, Optional, Tuple +import httpx + +from litellm.llms.anthropic.experimental_pass_through.messages.transformation import ( + AnthropicMessagesConfig, +) from litellm.llms.bedrock.common_utils import build_mantle_messages_url from litellm.llms.bedrock.messages.invoke_transformations.anthropic_claude3_transformation import ( AmazonAnthropicClaudeMessagesConfig, @@ -89,8 +94,26 @@ class AmazonMantleMessagesConfig(AmazonAnthropicClaudeMessagesConfig): headers=headers, ) - # Parent (AmazonAnthropicClaudeMessagesConfig) removes "model" from the - # body (Bedrock Invoke puts model in the URL). The mantle endpoint - # (Messages API) requires "model" in the request body. - request["model"] = model_id - return request + # Parent (AmazonAnthropicClaudeMessagesConfig) removes "model" and + # "stream" from the body (Bedrock Invoke puts the model in the URL and + # streams via a dedicated endpoint). The mantle endpoint (Messages API) + # requires both in the request body. + stream_fields: dict[str, bool] = ( + {"stream": True} if anthropic_messages_optional_request_params.get("stream") is True else {} + ) + return {**request, "model": model_id, **stream_fields} + + def get_async_streaming_response_iterator( + self, + model: str, + httpx_response: httpx.Response, + request_body: dict, + litellm_logging_obj: LiteLLMLoggingObj, + ) -> AsyncIterator: + return AnthropicMessagesConfig.get_async_streaming_response_iterator( + self, + model=model, + httpx_response=httpx_response, + request_body=request_body, + litellm_logging_obj=litellm_logging_obj, + ) diff --git a/litellm/llms/bedrock/realtime/handler.py b/litellm/llms/bedrock/realtime/handler.py index 6db2571090a..b48c37791c4 100644 --- a/litellm/llms/bedrock/realtime/handler.py +++ b/litellm/llms/bedrock/realtime/handler.py @@ -5,6 +5,7 @@ This uses aws_sdk_bedrock_runtime for bidirectional streaming with Nova Sonic. """ import asyncio +import contextlib import json from typing import Any, Optional @@ -12,6 +13,7 @@ from litellm._logging import _redact_string, verbose_proxy_logger from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLogging from ..base_aws_llm import BaseAWSLLM +from ..common_utils import BedrockError from .transformation import BedrockRealtimeConfig @@ -58,9 +60,7 @@ class BedrockRealtime(BaseAWSLLM): InvokeModelWithBidirectionalStreamOperationInput, ) from aws_sdk_bedrock_runtime.config import Config - from smithy_aws_core.identity.environment import ( - EnvironmentCredentialsResolver, - ) + from smithy_aws_core.identity import StaticCredentialsResolver except ImportError: raise ImportError("Missing aws_sdk_bedrock_runtime. Install with: pip install aws-sdk-bedrock-runtime") @@ -81,11 +81,36 @@ class BedrockRealtime(BaseAWSLLM): verbose_proxy_logger.debug(f"Bedrock Realtime: Connecting to {endpoint_uri} with model {model}") + credentials = self.get_credentials( + aws_access_key_id=aws_access_key_id, + aws_secret_access_key=aws_secret_access_key, + aws_session_token=aws_session_token, + aws_region_name=aws_region_name, + aws_session_name=aws_session_name, + aws_profile_name=aws_profile_name, + aws_role_name=aws_role_name, + aws_web_identity_token=aws_web_identity_token, + aws_sts_endpoint=aws_sts_endpoint, + aws_external_id=aws_external_id, + ) + if credentials is None: + raise BedrockError( + status_code=401, + message=( + "No AWS credentials found for Bedrock realtime. Set aws_* params in litellm_params " + "or configure credentials in the environment" + ), + ) + frozen_credentials = credentials.get_frozen_credentials() + # Initialize Bedrock client with aws_sdk_bedrock_runtime config = Config( endpoint_uri=endpoint_uri, region=aws_region_name, - aws_credentials_identity_resolver=EnvironmentCredentialsResolver(), + aws_access_key_id=frozen_credentials.access_key, + aws_secret_access_key=frozen_credentials.secret_key, + aws_session_token=frozen_credentials.token, + aws_credentials_identity_resolver=StaticCredentialsResolver(), ) bedrock_client = BedrockRuntimeClient(config=config) @@ -156,12 +181,19 @@ class BedrockRealtime(BaseAWSLLM): session_state: dict, ): """Forward messages from client WebSocket to Bedrock stream.""" - try: - from aws_sdk_bedrock_runtime.models import ( - BidirectionalInputPayloadPart, - InvokeModelWithBidirectionalStreamInputChunk, - ) + from aws_sdk_bedrock_runtime.models import ( + BidirectionalInputPayloadPart, + InvokeModelWithBidirectionalStreamInputChunk, + ) + async def send_to_bedrock(bedrock_message: str) -> None: + event = InvokeModelWithBidirectionalStreamInputChunk( + value=BidirectionalInputPayloadPart(bytes_=bedrock_message.encode("utf-8")) + ) + await bedrock_stream.input_stream.send(event) + verbose_proxy_logger.debug(f"Bedrock Realtime: Sent to Bedrock: {bedrock_message[:200]}") + + try: while True: # Receive message from client message = await client_ws.receive_text() @@ -176,19 +208,15 @@ class BedrockRealtime(BaseAWSLLM): # Send transformed messages to Bedrock for bedrock_message in transformed_messages: - event = InvokeModelWithBidirectionalStreamInputChunk( - value=BidirectionalInputPayloadPart(bytes_=bedrock_message.encode("utf-8")) - ) - await bedrock_stream.input_stream.send(event) - verbose_proxy_logger.debug(f"Bedrock Realtime: Sent to Bedrock: {bedrock_message[:200]}") + await send_to_bedrock(bedrock_message) except Exception as e: verbose_proxy_logger.debug(f"Client to Bedrock forwarding ended: {e}", exc_info=True) - # Close the Bedrock stream input - try: + for close_message in transformation_config.session_close_messages(): + with contextlib.suppress(Exception): + await send_to_bedrock(close_message) + with contextlib.suppress(Exception): await bedrock_stream.input_stream.close() - except Exception: - pass async def _forward_bedrock_to_client( self, @@ -206,6 +234,10 @@ class BedrockRealtime(BaseAWSLLM): output = await bedrock_stream.await_output() result = await output[1].receive() + if result is None: + verbose_proxy_logger.debug("Bedrock Realtime: Bedrock stream ended") + break + if result.value and result.value.bytes_: bedrock_response = result.value.bytes_.decode("utf-8") verbose_proxy_logger.debug(f"Bedrock Realtime: Received from Bedrock: {bedrock_response[:200]}") @@ -252,6 +284,7 @@ class BedrockRealtime(BaseAWSLLM): except Exception as e: verbose_proxy_logger.debug(f"Bedrock to client forwarding ended: {e}", exc_info=True) + finally: # Close the client WebSocket try: await client_ws.close() diff --git a/litellm/llms/bedrock/realtime/transformation.py b/litellm/llms/bedrock/realtime/transformation.py index 498567a4ecf..fe5f0584e03 100644 --- a/litellm/llms/bedrock/realtime/transformation.py +++ b/litellm/llms/bedrock/realtime/transformation.py @@ -4,14 +4,18 @@ This file contains the transformation logic for Bedrock Nova Sonic realtime API. Transforms between OpenAI Realtime API format and Bedrock Nova Sonic format. """ +import base64 import json import uuid as uuid_lib from typing import Any, List, Optional, Union +from pydantic import BaseModel + from litellm._logging import verbose_logger from litellm._uuid import uuid from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj from litellm.llms.base_llm.realtime.transformation import BaseRealtimeConfig +from litellm.llms.bedrock.realtime.trigger_audio import ready_trigger_pcm from litellm.types.llms.openai import ( OpenAIRealtimeContentPartDone, OpenAIRealtimeDoneEvent, @@ -35,6 +39,17 @@ from litellm.types.realtime import ( from litellm.utils import get_empty_usage +class BedrockContentEnd(BaseModel): + stopReason: Optional[str] = None + + +TRIGGER_AUDIO_SAMPLE_RATE_HERTZ = 16000 +TRIGGER_AUDIO_BYTES_PER_SECOND = TRIGGER_AUDIO_SAMPLE_RATE_HERTZ * 2 +TRIGGER_LEADING_SILENCE = bytes(TRIGGER_AUDIO_BYTES_PER_SECOND // 2) +TRIGGER_TRAILING_SILENCE = bytes(TRIGGER_AUDIO_BYTES_PER_SECOND * 3) +TRIGGER_AUDIO_CHUNK_SIZE = 1024 + + class BedrockRealtimeConfig(BaseRealtimeConfig): """Configuration for Bedrock Nova Sonic realtime transformations.""" @@ -43,6 +58,8 @@ class BedrockRealtimeConfig(BaseRealtimeConfig): self.prompt_name = str(uuid_lib.uuid4()) self.content_name = str(uuid_lib.uuid4()) self.audio_content_name = str(uuid_lib.uuid4()) + self.prompt_started = False + self.client_audio_streamed = False # Default configuration values # Inference configuration @@ -247,6 +264,7 @@ class BedrockRealtimeConfig(BaseRealtimeConfig): prompt_start = {"event": {"promptStart": prompt_start_config}} messages.append(json.dumps(prompt_start)) + self.prompt_started = True # Send system prompt if provided instructions = session_config.get("instructions") @@ -304,8 +322,22 @@ class BedrockRealtimeConfig(BaseRealtimeConfig): List of Bedrock format messages (JSON strings) """ verbose_logger.debug("Handling input_audio_buffer.append") + self.client_audio_streamed = True messages: List[str] = [] + if hasattr(self, "_audio_content_started") and self._audio_content_sample_rate != self.input_sample_rate_hertz: + mismatched_content_end = { + "event": { + "contentEnd": { + "promptName": self.prompt_name, + "contentName": self.audio_content_name, + } + } + } + messages.append(json.dumps(mismatched_content_end)) + delattr(self, "_audio_content_started") + self.audio_content_name = str(uuid_lib.uuid4()) + # Check if we need to start audio content if not hasattr(self, "_audio_content_started"): audio_content_start = { @@ -329,6 +361,7 @@ class BedrockRealtimeConfig(BaseRealtimeConfig): } messages.append(json.dumps(audio_content_start)) self._audio_content_started = True + self._audio_content_sample_rate = self.input_sample_rate_hertz # Send audio chunk audio_data = json_message.get("audio", "") @@ -383,7 +416,6 @@ class BedrockRealtimeConfig(BaseRealtimeConfig): List of Bedrock format messages (JSON strings) """ verbose_logger.debug("Handling conversation.item.create") - messages: List[str] = [] item = json_message.get("item", {}) item_type = item.get("type") @@ -392,6 +424,8 @@ class BedrockRealtimeConfig(BaseRealtimeConfig): if item_type == "function_call_output": return self.transform_conversation_item_create_tool_result_event(json_message) + messages: list[str] = [] + # Handle regular message if item_type == "message": content = item.get("content", []) @@ -443,6 +477,12 @@ class BedrockRealtimeConfig(BaseRealtimeConfig): """ Transform response.create event to Bedrock format. + Nova Sonic only starts generating after it detects user speech, so text-only + sessions never get a response on their own. Injecting a short spoken "ready" + utterance (followed by silence) makes the model respond to the pending + interactive text input. Sessions where the client streams its own audio rely + on Nova Sonic's built-in turn detection instead. + Args: json_message: OpenAI response.create message @@ -450,8 +490,53 @@ class BedrockRealtimeConfig(BaseRealtimeConfig): List of Bedrock format messages (JSON strings) """ verbose_logger.debug("Handling response.create") - # Bedrock starts generating automatically, no explicit trigger needed - return [] + if not self.prompt_started or self.client_audio_streamed: + return [] + + messages: list[str] = [] + if not hasattr(self, "_audio_content_started"): + trigger_content_start = { + "event": { + "contentStart": { + "promptName": self.prompt_name, + "contentName": self.audio_content_name, + "type": "AUDIO", + "interactive": True, + "role": "USER", + "audioInputConfiguration": { + "mediaType": self.input_media_type, + "sampleRateHertz": TRIGGER_AUDIO_SAMPLE_RATE_HERTZ, + "sampleSizeBits": self.input_sample_size_bits, + "channelCount": self.input_channel_count, + "audioType": self.input_audio_type, + "encoding": self.input_encoding, + }, + } + } + } + messages.append(json.dumps(trigger_content_start)) + self._audio_content_started = True + self._audio_content_sample_rate = TRIGGER_AUDIO_SAMPLE_RATE_HERTZ + + messages.extend(self._response_trigger_audio_messages()) + return messages + + def _response_trigger_audio_messages(self) -> list[str]: + pcm = TRIGGER_LEADING_SILENCE + ready_trigger_pcm() + TRIGGER_TRAILING_SILENCE + return [ + json.dumps( + { + "event": { + "audioInput": { + "promptName": self.prompt_name, + "contentName": self.audio_content_name, + "content": base64.b64encode(pcm[offset : offset + TRIGGER_AUDIO_CHUNK_SIZE]).decode(), + } + } + } + ) + for offset in range(0, len(pcm), TRIGGER_AUDIO_CHUNK_SIZE) + ] def transform_response_cancel_event(self, json_message: dict) -> List[str]: """ @@ -467,6 +552,35 @@ class BedrockRealtimeConfig(BaseRealtimeConfig): # Send interrupt signal if needed return [] + def session_close_messages(self) -> list[str]: + """ + Build the Bedrock events that gracefully close the session + (contentEnd for any open audio content, promptEnd, sessionEnd). + + Returns: + List of Bedrock format messages (JSON strings) + """ + if not self.prompt_started: + return [] + + messages: list[str] = [] + if hasattr(self, "_audio_content_started"): + audio_content_end = { + "event": { + "contentEnd": { + "promptName": self.prompt_name, + "contentName": self.audio_content_name, + } + } + } + messages.append(json.dumps(audio_content_end)) + delattr(self, "_audio_content_started") + + messages.append(json.dumps({"event": {"promptEnd": {"promptName": self.prompt_name}}})) + messages.append(json.dumps({"event": {"sessionEnd": {}}})) + self.prompt_started = False + return messages + def transform_realtime_request( self, message: str, @@ -837,10 +951,11 @@ class BedrockRealtimeConfig(BaseRealtimeConfig): Optional[ALL_DELTA_TYPES], ]: """ - Transform Bedrock promptEnd event to OpenAI response.done. + Transform a Bedrock end-of-response event (promptEnd, completionEnd, or an + END_TURN contentEnd) to OpenAI response.done. Args: - event: Bedrock promptEnd event + event: Bedrock event that ends the response current_response_id: Current response ID current_conversation_id: Current conversation ID @@ -848,7 +963,18 @@ class BedrockRealtimeConfig(BaseRealtimeConfig): Tuple of (events, reset_output_item_id, reset_response_id, reset_delta_type) """ verbose_logger.debug("Handling promptEnd") + return self._response_done_events(current_response_id, current_conversation_id) + def _response_done_events( + self, + current_response_id: Optional[str], + current_conversation_id: Optional[str], + ) -> tuple[ + List[OpenAIRealtimeEvents], + Optional[str], + Optional[str], + Optional[ALL_DELTA_TYPES], + ]: if not current_response_id or not current_conversation_id: return [], None, None, None @@ -1084,6 +1210,14 @@ class BedrockRealtimeConfig(BaseRealtimeConfig): current_delta_chunks, ) returned_messages.extend(events) + if BedrockContentEnd.model_validate(event["contentEnd"]).stopReason == "END_TURN": + ( + done_events, + current_output_item_id, + current_response_id, + current_delta_type, + ) = self._response_done_events(current_response_id, current_conversation_id) + returned_messages.extend(done_events) elif "toolUse" in event: events, tool_call_id, tool_name = self.transform_tool_use_event( @@ -1093,7 +1227,7 @@ class BedrockRealtimeConfig(BaseRealtimeConfig): # Store tool call info for potential use verbose_logger.debug(f"Tool use event: {tool_name} (ID: {tool_call_id})") - elif "promptEnd" in event: + elif "promptEnd" in event or "completionEnd" in event: ( events, current_output_item_id, diff --git a/litellm/llms/bedrock/realtime/trigger_audio.py b/litellm/llms/bedrock/realtime/trigger_audio.py new file mode 100644 index 00000000000..5783dae54bb --- /dev/null +++ b/litellm/llms/bedrock/realtime/trigger_audio.py @@ -0,0 +1,208 @@ +""" +Pre-rendered spoken "ready" trigger audio (16kHz, 16-bit, mono PCM), generated with Amazon Polly. + +Amazon Nova Sonic v1 only starts generating after it hears the user speak, so text-only realtime +sessions inject this short utterance to trigger a response (same approach as Pipecat's +AWSNovaSonicLLMService assistant-response trigger). +""" + +import base64 +import gzip +from functools import lru_cache + +READY_TRIGGER_PCM_16KHZ_MONO_GZIP_B64 = ( + "H4sIANGpRWoC/517dXQcR9Bnw+Duis3MzMwkc8xsxxTZMTMzM0PMmJhBjpmZmWKQZSaxFrQ80H0lJXf3vXf/nev17ExPQ3Xh" + "r2wPQv8/f/D/uMP/zxv8f64YkSyiWU1AIpCcRSqyICtQCApF4SgSRaHsKCfKjfKhgqgIKo5KobKoPKqEqqFaqC5qgBqjFqg1" + "ao86o+6oF+qDYtAgNBSNQKPQODQeTUZT0Uw0B81D89ECtAgtRcvRMrQCrQRahVajNWgtWo/+QBvQJrQRbQbagraibWg70Da4" + "2/rf7zbozxyxCcaug1krYZXFaCGai2ajGWgKmgi7jYFdh6ABqB/qjXqgLqgd8NUcNQUe66CaqDJwXQaVhDMUgNNkh7NZ4bSc" + "69zLXTyVJ/Kv/BN/z9/w5/w+0B1+g1/kZ/gpfoL/zQ/xA/wvvovv5Jv5Fmjr+Tq+lq/iS/kioPl8Fp+eRRP4KKBhfBDvw3vw" + "Lrw978jb8Fa8JW8B1JQ34PV5Q2iZ1wa8Ea/Da/Ja0Gpm9TTmzXgT3hzGt+a/wNz2vBPM78TbwtyW0NuIV+fVeCWgCrwyUHmg" + "yll9NWClOrwurNA0a42GMLYerFoN3pf7j8rwYkBFeWFehOcHKshz8dw8Ow/nUTyCh/IwaDYuc4mrPATIBs8WeJMNxmTnOWF0" + "Tp4DnsK4lYscc8405mNulsFc0FKYg9lZKjQX3KXDcxJck+E5haWxRPYd2k/2hX2G9gkonr1nX6H3C7RkGOmB1QjsGckLAK+1" + "QAqdeQwfD7Jdz3fzk/we/4f/5D4uoVyoGOizOdjbMLCw+WBBO1Esuo7uoZfoE/qJnCgARq7iUByGs+G8OGcWReAQbMUCDqBk" + "FI9eoGvoGFjVSrCdAWAr9VBhsHsHf8EP87m8F8gV88dsBxvFajKJvTS3mjFmOdNnXDMWG12NUoZPf6jv0afpnfRKejadaena" + "B+219kqL0xK0oBamV9E761P1I3qcLhhVjL7GEuOckWAUMHube02nWZ/NY7dYBFjJZR4JNnsRqbgr3o7f4WykNZlJDpEH5AfR" + "SRgtQMvTarQJbUZb0JZA7Wjr/1o7+gs8N6K1aRmal9qoSRLJC3KF7CHLyUTSl7QhtUkxkptkIyEklOQghUgF0oh0IINg/WVk" + "O9lLjsI+u8kfZC4ZQ/qQZqQ6jM9DchIbkQglfpyKP+Cb+DDejBfiEbgDrogx/gftQWNRbaTx23wBjwYbuMwmsfLsq7nZ7Ghi" + "84IxHs7r1A/rA/Wiery2UeukRWiPg4uD0UEeuBSYFWgQEAPP/dv9k/xd/K387fy9/DP9x/2p/mqB1QEjMCvIg/M1m75Tr2m8" + "NuaZ5dhrNoaHQnzIDpzUIzdJLXqS5hEmCVcFJpQXu4gjxelAk8XBYgexgiiLP4XLwmphkNBAyCkk0yt0Be1HK1JCX5JdZDSp" + "D2d7htfhLmAXX9FR0H5XVAPlQDp4/xN+BezsCHj6Xrge4cfA9y/wS/w6nPUxWN97/h2ihIObXISoWASiXwxEtDPIjRriTTiA" + "B5N3pD19RH8RbgilxWXiZ7GI1EUaLU2QxkojpcHSUGmGtEO6KX2UXkvbpYaSQ7wq/iXuEleKQ8XS4gdhsVBXEISjoNd3ZBzJ" + "S27hCbgMfgeRTUGHeXfuY6tZFfbQ7G+mGmOMJH2UTvRNWnZtfjA8eBjk+srfx+/x7fQ18/m8+739veW8yPvec8nzl2ejZzXQ" + "Ns9pz2dPiLeld4+3iO+pb6t/RWBr8IL2UY8wm7Pp/AC6huPIF/pOuC1ul4bKuZVDSnF1kfpUDbPUs/xq6WmpaZEtD9TJaqi6" + "QymlHJAj5KnSM7GYOF64SYvTtSSC7MB1cALE6WbIC/GyG8QaESJKAfDm2TyWx3EZInAryA9LQfZvwOor4c54PF4B8juGn+A0" + "HEWqgAf0JkPIeDKFTCOryA5yiaQSG42mI+hf9DvNLvQXrgg2sZ+4V/wilpH6SFulT1JReYJ8WU6QsynFlbxASPkiX5S3yNPk" + "0fJkebm8RO4ox0lNpbNia/Gj0BEsYxxYhZ1cJOdJE3IWM8h0vfgpFsVGmaeNaOOL3kK/ohXV2gfnBL74R/q/+rr57N6V3ibe" + "gGevp4fnm3uuu7T7bcaJjJkZTTMsGfddm11jXF1dfVyzXBdcpTOeZFx2f/HU8j33rww207Obz9l0VJqcoBXEQ1KyXEgtYgla" + "TlgL2ZbZ/rGl2GwheUKUkHhbN9t1a6S1iWWM2kepJxeTUoQLdD5pgWuiWnwWe282Ac3vNhZBNBllTDBWGDuNNwYzmpixZgTb" + "ysqBhJtDDOyL43E0nCw/HUPP0jTwlipCKaGQQIR4eotupcNoPcrJY3KP3CEmaUKnUZ22F24KMeItcbKUXf5DrqUsUxxKe3Wc" + "+lBNVQVLW8twy2kLs2S3NrY2tFqsryytLN/VieoLpaEyV/ZLG6VGUlDcKo4VO4uR4mOhs3CI/iQyyY3t/CmLNfcaF/TT2sXg" + "+0BUoLd/r4/4fvde80ieTu6/M1Jc0a5LzvzOBY4P9qH2bPaE9Pj0T+mivaZ9sv20XbfncNR3vHY8dHbPWOQp6v9VSzXX4wpi" + "HWWK5Zw1xtbd9t46yeq0PLHkt26y9rXlDukSEh1yz5ZgPWwppw6VN4qKsIL0wQPQJH6WtQH9Kmwge8em8ZFoNP6NtKDXAf5E" + "Co/AunLQzPiZi26gFYTzgiSGiYeEdHqKNMKneW0WahY2Ruo+7Yi2SzsBkT6P3lZfol/Tdb2+McLYblw2TNDEA/MhU5FANgnD" + "5BWWniEnw6ZHDIqcGZk7ck7EzfAe4ZXDK4WvCufhvSPORFyJGBnxPJyHpYW+DEm1mdYm1o2WoDpCjVOqKmvlEvJtaaqUXWom" + "NhLiSS5cmzczF+rZtBzBsYEE/xV/G/8nXz/feu87j+zp5l6TkTfjlquFq4DrunOUs6bzo2OsQ3Vst3ezlwdJNrBXg2uUXU8v" + "YRccp5293WX85fSd/C4tIt9UW1jnW7mljWWk2k5NV1Msw21KaL6wa2F/hrUPXWOba/lFmShlE2/SPeQNfoZsaDS/xtYyCRAS" + "Q71IN+qhbYRswl+0Ab1N/OQcfSa0l47Km5X3ynilh/xSjBIakivoL/6aDWcCm21+MmoYO/WC+m1tnrZUO6p91urq8/THeg8j" + "YHw28/Ih6DO+TW+KcfJE4KVw6O2wHeHFImIi9PDocCNsadiksPSwjLA3YTfCqoZ1Cz0fcsrmsi6ydrXOtn6z5rAxqwJetNBa" + "w/qPpYflndoRYtVpeYpUW/TRu2QktqKebJtxR7se8Phue85nNHGZjuoOh32MvYy9kP1D+iOgielqesv0kukF0wdCs6ZPT7+V" + "Xsf+1Z5gz+ko6Ryc8dHr19aiuaKpbrC1BaA02rpcfaNUV7tbGtkehFQJ9YSk2aKsK9SH8hWxibCFzEM9WG/Dqbm02UYCy0W+" + "CbOlmfJ4eZf0U7whrpAaKVUsH6wOW/mQt7bBtlfWn5azqqjYxao0G+pu1tK7a39px/U4Y7hZzaxvJGoDg7kCp/yJ/seBGE00" + "jplTeE9cmhYSp0mfpXjJK54RHgmzxDxyjCU8pFrYwvBLYUbIV2tXdYjslC5IyZJPPqUsVwOWYrZFIQmhxcECK4d+tcVa21kr" + "2mJDDobVi4iNiIooGUZCcljnqcWUSPmBGCGEkv68jtle7x787v/V53UnuD44CtuT0r+m77B3dMQ4tzvDnDmcC+3v01ukR6Tt" + "TU1NiUlpnKKkzk4bm97GUdn5wFHa2cQx3jnE0zJoQy7Rp26x9rP+Zsmh7lJKKHOVEeoPJUbpLn8SL4rVwffO0R0oYAwPCv6u" + "vqf+/noV/ogchlKFC7eFH+JB+YCabmliZdZctiW2DiH3Q1qFjg2Js2ZT44VpaKJRVOOBtYGMwG/BaUF74GwgIrg9uF7bodcF" + "9HZTb2M8Z+GkjlhfGaJ6lRVyZbEEnYC9fBZCdKT4WZYtsyDnzVRtymepqFQTOLog51Z3WIbZzoa8CG0YViwsLLRqyGXbUlux" + "0Blh9cIPRoRHvo14H/4+9KXtpkVTHssnpcLSafEvYSe1ksm8tnldEwN7vf3d91yHXYMztrtPex54FnoKu486v9u/p81Lq2Zf" + "51jhDHfddaxOb5w2K+Vz0vDk2sk1UtypQ1MrplZKr5ihBYeRnmopm2RrrtaX5otLxFNSYbWvdZ/NbZmjZJPzilNoE4xMR6CJ" + "d7a7jO+e9pYdJctETTwtxNB89K6QJEdaZ4WsCWsUPjl8emT5qKURR0K3qIwW5tX1ZsHHwdMQ15jWMVjMH+mb7X3oUwLvA9O1" + "3kYF3pRUFB/LLdVcahl5s5CPHAL0nIRvkXByGM1k7dkhXhDF4TkkkgSIRNcLprRV2WM5bb1pfWxZot5TvZarNlfIr6GvQ3rb" + "zlrXWivbqobst32wVrW+VAurMapb3Q8Svw6RppVYXahEz5JpaIy5WGvk/8tb1fsNUEwzb0fvBPdJl+o8YGfpetqxlE7JD5OV" + "ZHeyJd2bylJbptLEbgkzEub8nJrUPqUa2F2T9J0Zn/RE8aytctigkHVyfmrisUKI8kW9Z+mulpSGkXGsvDnUSAi6vH9nrHYd" + "zNjjL8C60fFSXmm+MFxoJc6QhlpWhA4Mt0SWiwyNWBs+MnS+db9yQtjO8xjN9ViwpSFGV+2Cv5D3c0ZOT/NAV8PkB/FG8oHO" + "EHaJQ+W2ynO5gtiQLIQKWoUKeTeqz18YX4I5AgW110YaTyd++kpoK42RXyjvLZutO61rbKlwHWfbZntqq2UbaTmtDJDPSivE" + "Z+Im+Z1yXm2reuWncmu5lrxIvqx8VzR5tXwEUO99uh3FsbV6seBNX3VvVY+asTVjbUaM+45nrPuOa7Kjpb1C6viU96lbU3+H" + "bLAqvaj9YdqQVG9S++SMpEpJ+ZOvJfZPupU8zLFBmyuWCskRut26Rub4LkvlbmGuckC9r1SUDpJu5qLACt8Zz09XlPOKc73n" + "czBonsPRtBO5C7V/FD0rb7A5w/dGXc/2W9THsDO2CEsZOU24Txriv9EP/oYdMO/q6wKPvfc8m7xlghfMmmSdWFdC0kBxn9hf" + "6iwtkBLFPmJNcZjgpnXJYtSLbdE2Bry+rv7DOkVf6BbpqhQQZ0tHpRRptdoSLOpL6PzQyyFNbYssJRVBuihECcWFC5Ku/KME" + "lFFKafmlRKSOUi55plLUkmLxWH9YTXWaPFdcCRmpBA81rgU/Brr48/sEr83TMyObe2LGtYyKGdQlgVfOs/9m/9W+1RnpLOTa" + "6yzuLOOw2KemD087n5or7XJqVNrxlI2OzcEmwjXLGltTWz7rXsmHR6D2Qg85XGmu9FduSHVJvLbYW9Q9OKOFu6N/oLGTj0WD" + "+RjeEkXjz2SfOF5Ntk0NC4scEtUj8n3IA6Wl+E4whfeCIrYQPuKnrKYR0P4MouDvwWjdyk+SseIieaKsgLzaiGWl3+UcgL/t" + "4kmxoxCPu3HNGKiN97cEVHAv8IFtIa3EpVJuqb+0Uv6hlLXeCu0R3i78aHjZ8KuhD6wB5Z3UX2wijhFVmaiXFEWeJM2VqskN" + "lGfqaUtXywBLJ8tjS0OrWx0sj4DYeAQ/Rk9YUb2Xv41HdI/wxPk3BqoHznkPuG46cju+2rO7Jrlfuld5Orh7uMY6UtNcKcVT" + "XqRMs/d2fAFLy5WamPwlMT4h2rmcpakTbLct9eQUWhg9QOWkebarIdstneUV4lK0UkvwXM8o5U7y7AycMP38lrkkuMbPgkvM" + "R/ik/MV6JvRC2OKw26HlQ2pZtsrvpMUKs3yw3Fbmih5eTTvvzevt6m+vjTFGQs1o5fXYXwyjFrgHnSp2lgeotS0n1HxKfekG" + "nYldPC8aiUrxDuYzbV1wj57MMvA3GifIYkF5gtJC/R3QbnnrGdvvIYNCRoSsty2zrJEjxDHCNGGcmENi4haxkVhQbCkmin+K" + "1aQSck8lQemozlOGSSWFFqQCNnkzNkDPHsjh++p54tnofe4p7NnnphkhzucO2RHpPORIcrRycecl++r0hmkd0i6nXUvLbk+2" + "b007n9wv0f+z18/eSdczTqCnwEV1eSjNiYuwYby1MMYSb8WW5/IF8Q46qKV6DrivePr79wSjjFxGpDbKN80bHqhp3ECquFZ5" + "py5XO6uJ6lJLH6jdHljKWT+ABMrL+ehD9lgrGiyiLTT2mR+Nq3p+QJUHg80NiU/A2+lyyCo7lA9ST7G4oJFtpAytJ8wX2pN1" + "bKNeWauqt2Nf8HlaR9SEUmJJKb/cTj6gRFjyWX22waHZQh/aBloqKWmARLLJY+Rlsk1OETeLzaTfpUZyqNxdKg4I5Kh0XEwX" + "2gr5hFPUiVvxFMMZXO2zeX96Xnp+95z0rPBU8sx1j3P5HGccVR0THCcc+ZzvHbvBzkTHqfS/0lhq7rRHqS9SHiUfT56WJCVO" + "TinnsbM4saFcU/ydKLgl7k5LyonKCbWepaKlitKcxurEl99d2X3Jt16/ZlbVW/o2ua+5a/h6Bp+bY8k46aO62/YjZKtttGW0" + "ck8pad0Y2jS8avhj2yC5Iz5ohhvT9C/aJL2u3kZfpGXTbgS1wOBAC20qy0PGCNehIh1J+9PG9D3dJBQUDNwY70EneF+eyErx" + "bmgk/5v7UVN8nRQUZovD5EbKW6WQpT6g7t8tFdWDUGVvV+up1dRR6gGlkdJPOSvHS3OkKOmq6Befi7PEOKjLiJhIV5BsuBeP" + "NQO6qB/S2gUf+Gv5Zd8nTzvPM3fpjDEZbd0lM+yueq5RjvaOk/Yj6eUcOR2b06um9Ujbl/otJZAyJmVHct/k8Ylm6iNfPL8m" + "vBaX0p1ordnabEZqWVjotfAjEQNDk6RkZg9sDEzQn7JCZCfpx5r4H7lyu2q7b/mi9EW8HDWB1gq9hWV0jlBL2WcLhPYM/xg+" + "OmyRdbtUmJbDyxGF+nMiyYcKGPmCBX2LQKtj/cP10eCPV9l9VpdNNZuzs+gQHSzekcbJ/SQH7Yr38VH8Mxol7FBmWpLU29IY" + "KuMfqBn9JtUCpDrBgi1vlbbyWOkPaay8Us1u7R1SPjTNWly9IX2Vsit31G7WrdZfLS3Ur1I5KVaYT0fSKjSO7MLvmUNvHGwW" + "OOO/4nvtb+Xv7D/rO+dxZSxxDnDUdPZ3+jOKeVhGWsZOxxzHLOcNRzVHFfu+tI72nvYSzvN2nLYh+U5i/bRX3oJsjbBOGMP3" + "aFv9/Q2H8FvInPDVYTVsWP1NmihZAOk9JUfJCuGm+EkYgmP1OP8dL/Jv1xawW7gj+Qc/RJfZIfYnukvbyolqYVunkCe2RdZK" + "lpxqbzla2gtoNsz6QE0QFdzD1PQocx27z/2skDlK9wQHBI8Ex2pD9InGZvMMX49aoVb8EPOa7dkPvpjWlG+rpS3V1WxyEbCT" + "dKmv+tLa1bbF2tkSq4yS8ggzSXVynJwRFkh15GxSSZqEuqC9uK2wTFovj5SvSjOlN2JRsZ+whBakaaQSbUkvkTr4BDtrtDRK" + "GgWMMMOr/2oc02toAwMj/O39NPA60Dp4NoACjfzcN8g/33/eX9Pfz7/LPzJQIdDN/8i71PvIq/na+6f6fb7FvrK+VpDB6wXL" + "6T2NXUayXkq36KqxyVzBf6ApuC9ug/fg2aQY7Uo70qm0mNBHHCqFyPelUCm/+EYYLo6Ucsqq3FzaJVYRK4klxThhidBYaCa0" + "FiYLc+HuJq1I15NhZBcJp9VobjqHfMF/4K34LN6HS+JDaACajY4CXv0FHectuMRdzMds/CNY4ho2iDVi9Vg1VpR9M/+B6h2z" + "7mw2W88WsXXsFrPwxfwHb4I+o214FqlOT9FywkqhipgkXpNmyW65PlS4awFreJXcaj91rjpWbawSNZtaDjDtVSW7ckPeJJ+Q" + "H8lz5ZbyFSlacon7xV/FIuJrYa1QWfhEe9PDgJhHYILvAzYcjt7zXHwy1MjXzbNmZ/O2Ud9I0LkeYvyp59evaCF6V/2HVl+7" + "FFS1odo+bZWWR3MGfcHcWh+oD19oH7Uw3dSi9G76Dv2+Lhn9jM9GTXOYudzMxY6z3jyBt0NnUGmcgJeTNyQDNL2KZhOmCjeF" + "/cJzIVVIFz5BZXUCetqAVOsKOj0K8hxKB9ESdCqpSsaTg2Qy0fGvuDy+jQlZgp+hTegaKoPD8E70htfgE3gldB81Rvl5GkM8" + "hl/ij/g4OFNP/op3Qh3Rc76fS+hPFIeeo1j0BMWji8BREfwPfoR34qW4J/6EB0HkOIcL4J7ER6uLTQERHRMKiUfF/NI06ZM0" + "UE6Rdfmn7JQny4XlgDRIVpQIpZscKp0SPdJguZvwinQVeymX5FhiomJ0txAmuPAEEi3cEeNJB3bfIKiqsFFYgzqbETw77sH7" + "m3HGbUZxU15AfxJYbj4jt9DcQE1Pu8AEQA+GVs/XxP3I89pX3dfWc8izxVfQ9ynjJkTWFs4Qd3bPNvfbjJ0ZroyJbuQu7C7p" + "669PRXdISTyC1TNv80pCbmWEJcaaCnk3TGksL5AXKw3UfOohiGOfxIOCHw9jHY1nxjeWD6Ww7sbrYOFAw0CJYIhe1jzDCnCF" + "tTE/mJv5e9yUWoQVgiFsFpk4TmwmCDQnrSnMEE+Jd6gPcLLf+M2MZTX4HLbTKA45aoB2XCuiT9ZT9KrGZOOm0d7MzZqxsUzh" + "VxChX+gGmkSO0q/SHMs72y3bQ8vfag+L23Y47GB4IIyF/hXSPWSibYxtrO2sLbstzXJWraO+VLyyJNcBlBgqD5BbSNuEUPqV" + "nKIvwVZa0f34CLrOh/BjLM50QcyYpY/TfIFFvl7e7p47npKemu5Ql+z43V4rfaq9rn2m470jxWHY+9gD6Rn2ac69rnoZ21yf" + "nE8dCY7Rjp7OEMc654yMyoFpbANgg799Yd5xwSn4jFLWFmodofwqrKbJQnO1ZsjQsCahf1vbK1ukW2J1MVY4KcwFO9kudMOD" + "zc6Qp8ELeAymGHGXPkILaJfN3XiesEDcKRSnPch0spdeEqNkopyXndJj0SL0IrPwc2yjOv1OP+EdbIveReun7zQT2F2WYTzT" + "OgVZ4FZwmE7NLhA5Nppe44KBWU/+FY0kPehPuoLaqIcspZWFdWKsfMyywXbEdkBdIbeVN1h+C8uIbBDVOqJ9SJp1sG1m2KjI" + "6KgGkRfCZodE2wxrrDVo/cP6wTrXGmrppNjhLKOEN0J7abTUWcT0JW/DnpqLWCLfxAexNvqXwFH/BH/dAA52CTz2j/HW8XQG" + "lLnD293bx1PD43V/gadmnuvuhxnRbu555Z3pu+BZ7lrveuh65on3fvTMz3DZ36UfcO7z3te7Glv09to37atxlX8lqXK0Jdq6" + "3XLOEms9YIsIuRA6I+x0+NDwAaHRNq5slffJR2Qmq1I+YQr6aAzQl+kB46d5wLip19RcgRrB6dpdoxl7xfbwKMRRbfwb/pPs" + "p5XFNGmjlCB2E24SCy1KI0FTC2lu3IntN44bb4x044QxXN+rXQxUDZQIJPsbBotqHfW7ekv9oD7COGpW4xfRX+QSXSh4BK9Q" + "XzwjSvI4Ja/6UPkgf5RqSM2lF1DlfJcaSYOkgdI0eZTUWxorFZEHKK3VDLWL5ara1nLU8tmaIyQyJNVW0NbaehckftzaDk7K" + "1dNKXXmrVFBKEqPEAO1FC5ICOMh/5cO4G07iN8eZd40YyIHVjdzGMWO1EW6YelP9qH5Hf6/XNsrqY7SZmk+rb9zTYoJ3/N99" + "Df2T/C8Dq7SPgak+X0bLjK/uEr6R/k3+Hd5ZGcmO2/aSzrYZZXzegKwtDxjeBb6+2p/sJCkF3nxTXCMa4i35rGVZSPbQ1qGX" + "bLr1hWWv2lTNrf6i3lZ+in+SQzzNzM5izR1mE7OF/jTo9yf6EwOdtK96DVMzC7IE8xY7juKJKnaUvksDZIu8Vm6jvFA2qyfU" + "HGpRpadUV4wWooU8wgTaj1RBSWyYed/IYVY0b5g5TMmw6o81ppc3j7E/+GP+FOJ1EFUnOWgd4bQ4X5okHYT4c0s8DDX1KDmn" + "PA+qyGNCUaGTUFvYQJNJKGSFEXgjqoVa8OmQOynqie6iUtiNp5Ph9BJUtyOl7vJ+ZaQ6Sa1guWIRrUnWN9bxttfW65aClli1" + "r+pRHsjT5ZJSM/EFrUQfkglkAN6B7vETPJ2/52/5CI54bV6GV0P90Xv0GvVG1RFFQV4V18VLcF4UZAvZUraJSXwcY6YXrOpc" + "cF+wmjZYuwvect230fvYG+W96W3stXuXeZO9g72jfdhnerODx2ieGH/LwIGA7o13L3ZJbp/ns39y8F6wTGCd76gvEDxi1kHh" + "uBtksHD8lZhCWfmJMkph8g95qDJFWaeUV+Yrk2SvtFE8S+/i+ugyyG8f97L3RiftRKBioFPwnvZOf6pP174G04O59QqmzNei" + "vWgMesGroI54EJ0LFv6LcJdmh5PXhXiiCDPpFvIJsmsRXodnwNkqsjNmS3Oi4dSHAzZYaNSGDH/Q/N2MMFeb81lfNA5bSDw+" + "iC/j4WQlHSLUESPF08JZ+gQQcZTAaFPhDBVpA9IJf4As3BNvwX6UyntwkS/lW/gD/pKf5PlQTkTQRJDtZfwDHyOlSVFSjvwk" + "u2gh+ZY63BqrtBRvCLklXW1giwm5Z30ia/QsLS19scyw7lW3i4/xKvQNmbSJ1EJsSbsjJ3sC2cxEGvbgDngef8Pqs3GsJMqJ" + "LbQVOYiK8aGsNHei4kSmS/BBHg8WWYZ15dPRH3yXWc7YqjXWFL2+cc7w6D+D4wO5/B/8CwNbg9eDawNvfMu8y71nfZ/8yYGQ" + "YJVAuH+dL+hL9r8OSNru4NZAG8Cgyb7K/iHglaavju+NZ61nmfeQ/0bgQ4AGogNnA5u0O0ZDbgHc4uQd0QXcX2gnXZRySylC" + "vBAQfpME+bX0u5hBF5I5+Djglt7oGy/MT5qTjIL6ccizTfUJxndjmPGrflOL0IdB/OsAqKY72sdX8UkgwdV0hDBAuEcdZB/J" + "DnKaKPygfahIOuI/0G20D61Cy3gO/sP8Zo40k81TZln203SZO808LIZl4624xsuiQ+gn6g54NgeZSl4Dzi1L29OF9A96gQ6m" + "PWkZWp6eIevJIjKQNCTpeAh+DzY1DC1Dh9F2NBhFoIN8B//ER6FkZMWv0Snwyc+oLt6N47EXNFyG5APMlRcyZRM8F88B9DUN" + "VUWf+Tn0lGymi2htfBAsoh3ZQI+LE0VVmItr4MWkgrhPOif+IswhGjbwG1oBcvAq6sFVcB2chseSAnQJ4fgFmouao79RNL6B" + "r+LO+BmvxPvBiS5Bj4pdfAnbY3KzIH/Bz4NdTDaHGSWMQ8ZaswfrYYYZT7VnWjc9ylhotDEW6wO1O5AZLmiadlcrpcnatuCc" + "YKvg8uCtYB1tp7Zfq6sVB0RcWOurubRhejP9kvY4GAjm1dZoKcHdwa+B9oE431jfLX/rYDDYJZgW6BS4F6ivXTR6A25dzXez" + "KrwsjhS+iYa0X7oIOL28RJQNUJ8fl03psLhfKCu8A83NJs/xO/SUt2A1TQm8DvKfqZjTjRCjqNHT/MEOg9ev5PNA3m9REO8E" + "NFBHWAzzFtDFQmnxunhPdAoXaCnamJ6morALPH0XyLcxmoI+ITvUAU4+lecDC1vMG6NnaD9YksZrQ3XQAktkA7lOupAK5DeC" + "6T+0uTBCoLBCY1qf7qC1AIlFCvkA2dwFNC2CHTzG1fFKpPNlwM02fpd7uJcfBPlrrBTE0rloCrlLCN2FV+MreAf9IVSVTHGU" + "aNI0ekEoJFWXR0itxLpCPL0D9b5T2C10oJOIieuQaWQumUU+YahV0W9oLWIoDb1EfVB+tIB35Im8NVqCBiEVjeBNAft/56Mh" + "lqSDN3xjn1kDfhsqkY38LcvDyrOS7G+WDFSUXTTzmQ3NoeYnM948aYabF4zZxjJjr+ExrhlrjMZGFcOlNzfyGtkhC/cGSRcy" + "DF3XX+g39WqGYUjmPWORscAoYqwyJhjbjQ+Aek9BpXkCaiMXRH9Zp8ZnvYeeDlXSDn2LKfEcqCiKBT4eo5NkidBa7CEmCYOE" + "CUJZMZdUVfoilhJLCoOpi1yCk4aSebgfeKmfLWBlWS3WkxVgDyDmTjefm9HMyabwhXw7j+V+QNeHcQhpCxIqC1X3JFIeasZH" + "oOupJCdxQUSeDh6ajNvh2agMYmDzSZDVXvO2/ALgjHdmPkZ5V96Mn4PqcxeL5PGQFRag0Wge1K+FoaJ9g29BDLgD9ZJK+pGl" + "pDv47Rt8AE/HM3B9XBG/RVsgOiXye4ATN4D91AWPSmSPGeEvWSrLz/vw8lCZKVCpreU/uZ1f5M/5bIjLR8FXn5G+OD9+hr/R" + "cDFB/CKMoflJFdpPWC01kz4Jg+hkUonE0F1CmnCbRpGf6ADEj1nATUWcG5Xgw1lr9hL2ymCbWV7GjarGF+Oc2Zc1YGvNw0Zl" + "o7MRajrNtuyC6TdqGaVAQwUg0iWZVcwWRub/kSpnjDBaGYn6bEBWrfWaemn9ofZKOwTe30JbrH3VtukrdFnvpaUHPwYfapHG" + "buO23l+bERS1QfpOI8FoYVzRNgUnB4fq1c3b5gTDDk8tgh20WP2AEWkc0ioHjwRqB84ECgdzabX0aVBHm8FhwU3BNvpHcw/4" + "wmIWYdYyv7OLWBDaCXPJSbCNENyZVhIThLx0HqrH/+RV8ESSg0xGvVl1UzZfQ4Um8pHsF7OYEdSnGtPMOnD2juwzVO5fzSfs" + "B98OmX0haohKodVoEG5F/oQa+ig2UDbcEGrwAmQcXgQV8Vq+HuJFgJ/mRfmvLNlMNXuy2+wHm8/c5iPTY66ASroxj+ClOGdN" + "wFIqo2gUwKWon06k+0k0vSdYAH80VprLJQBhF5WvKbvUi8ouaZyYU2wAttxYGiEuojvxLaizk7CJo/FRHsZGm6/MBawo38QO" + "md+N341NRjtTZArbbJrGTyPJKGHOMLeaG8w+ZoaxzmhvdDfyg34GgCY362+1G1qaVhF0lK7N1eppWCukjdUua7u07oCE/9Yu" + "aY+04lB7RulYb6iv1f36Ez1WZxDF8xtljUHGTqODEWF81csY0fB8yzhvtATNn9bP68eMp8ZRw69P1wfoY2BORV3TdmvttSda" + "DtD/St2mH9WG6E0MK1TFPVgFVpltZFd5PDqJd+D7+DTW8ABikmq0CN1EOpM+pAy5jffjXTgP3gY5qAh6D9k0yA6yADvPtrAB" + "rB3ryiaxdNYKUGVR3gAiZHPIyHlxBdwCb8Yy+YMECKI7yQVyk1Sko2lniml7cgnk2BM8OTeJxhPAj1uDd37OnIcW8t58HQ/y" + "pqgGikQPOEJ7kIBDwC/forKQM7dDbGgC8fsFROcA3g94oL+gizHSXvEBDRO4sEQ+qvRRo5RYQFfHxXrKR7WKmiAFhexCTaG/" + "9Ctg+TNCfTIMFyHT6Sc6nwZxKJoBEaQmPoXjkIx+5QIgiWdZ/z9tOrcD6nrKPjAXa80L8sesGgsCpkgzK7LZLJrNM+1GqpHd" + "3GdeNqeapc32Rro+3GgMz83NP4yuoPPFRnmwv1um1exnLDGY8c58b640J5oPjUuGag4yR5uFoAYZZa6A3wwjxGxh7jYlFsZe" + "mH+aE0wCWPU31oodBQ4UvoddAzk35GtAxicgwiWznFAfVASMUZUfYe1ZDXYKeJ3F3piNzApmN/O8mWJeMTuayGxjPgZLvccO" + "sBOsMh8Lc74AbmwNES832Uzy0xi6mt6nNkDN+4UzQpywWTgEGNovHBGWC4uEacIGYYXQWsgvvIEs5qTRQlXhDh0A6GkT/Uwj" + "hDDhHO1LR9A9lIKMswkfICcvAmT1lHrobcjZeagVcFs8OUQWkpLkOF6J/8Br8C84ATDUTPQraomaoCoomZ+BU+3kY/gQPpoP" + "4Pn5a+ZmYZBn4yD6XmYzWQfWh/0JVrcSbG4Q6wTeHcdk7mGxEOcNFs3nQBwewpvwipBHdJ4TneLt+Ax+E3Lpab6cl+aJIL/T" + "7B82mjnN2SCjbmZuwBxTjOZGTfCmTB/abQwxphnfjJVQHeaFODLf3GN2gsxaAmTdgSUCqlzDMmP/FPan2d8caNrYNjaDOSBa" + "5THXmB3YWeBvBLsPntWTPWCD4BTPYN5A0GIhfoyf4934PqaZ7VhuyC4ePoEfg3eH2G98EFqBHMD9L5BNjqJeeBXuiL+gE6g5" + "5KjF5CHIrT5g0t+JQAfR6bQLIJVcgFcH0aX0OX0GuptBp9FdoEFF8NFXUKXsAVzzmJo0lxAuIEDK72gcdVMXzSOUFpLpXnqc" + "vqcBKgspNJ4mgo7O0GP0Mj0H1610Dm1NI6lB/iEXyRrItDlJCkSFvoCCnOgaZNHeKDs6C3KtDNXObfYXG8PysX/MhWZb8zez" + "u1nHDBiPjT+NbXANMweDV3SGqjjaXG5WAinMYb8wysLheoF9Z59YP3bHRCChC2wR42Cru83rUEHbANEkmTpg+UKAbxLN/FDn" + "bGI3IDdeYW1YX9DgHL4L9D6DTQdrqMj/gHqrFlSqMvjqKf6RL+CxLDfkkO6sC8g0lV0xx5onzPqgncfA7XKzgfnSfAkYys2G" + "slxgSRfZYO7ml3l2/gkqqFjI6REoFOLcfrivgOYDTUTd0Ep0ErBlFTwI98R9cCwOJ+1ISzIOsA0nrcAb9tBVdBlIuq1wVYgR" + "GgrFhYrCDuG94BO2CNWFdFpDOCDsgTc24Ss9CXrjtKTwnY6lw0GjW0CTo0GfPWgL2px2h5o9B5UgTn4mxyBG9iZNSSo+D1G4" + "J7ZAvmuOCiGM4gCbNOGP2E6wycxqPYaVY5/MJ6YXrLQAE1kEK8JGwpt1bDf7BtF5KoxvxkuAbxREf6HJyAOy6QxW+BdKRfkQ" + "Bvm9ZHY+BCLgHrbRPGyeZD7+hhfgCeZ4sybrwXsgO7/BcrLGbDHvDRK5xW+x9Swc8Noy9JaH8f3sKqvAu/OZPIT3Y7VZL5bE" + "7oDH5mdW0Fpb8N+hrAlzmcUga5wDPxwPmf4j+MV4sKUVIPvi/A5vC7IuDRX/Rn4B4v8OyP3loHpdwHOh8+g71HgR6AO3gh4a" + "44E4HY0EnRTEx7AbqqKWuDTuhr/g/qQu8eG1gPFU0gFQZyNSk+g4P0S5O+Qc5LPGgPoXkPPQJpI2gP0WgH/NIc2BOoB/7YAZ" + "MaQaaUbGQN5aQlqRPKQErNiF1CGYnMDH8Vf8Cf+N22IRJ0EV2BgXww4UA/KrApzfBn7qgd084gSeqwO37yDuzIOYdgEs9A6c" + "sy54+C98OOS3pTyGV+HR0NOfb+Vn+QNAv1P5Zs4ArRZBtVBhVAxVg6ozFs6dAtcZaCj6A71AOXADQD/zwQZi0D9QzXaAKDoD" + "0FFtFI/64SlYwNXQd94eEdwf94J3ZaFyqYycaDzOh7cgBSE0AOJKdvwTdUZfuJN3hrwbD/VtEcTBBzqDhb8EVDoD6qVBaCfS" + "kIyj8DW0FWT+DZXANjivHR0DPrzoF1wV18YI5JAT+gfgybg3rgnv2wFPeyBLL4GePhDJNuFrED+24EOABg7B3TnQzVl4vxIw" + "xd+AfXeCL+2E380wFmo4sPIL+B6+iY/i61B7fcXpMP4ESP0baPcFfgn19k5A6/vwZbwY/4qbAw4cj3/HkwBDExyGa+HfQEIN" + "sQR6aYy742kQSfNhDjh7CnjuQOBPxSWhuh6AO8HJ7qPHyAZzauMfYGFX4akYrgZzn0DN74c5Q2F9N5xVwiNhz93AcyWwtNX4" + "FQ7CGWbiIVBP3McZ2AOn7I1H47v4LT6Jx+GyIIVecP4FuD2OAC1UwIPh7S+YAo/FYeQ6OPkUsNhieAR+CLXINuCtLm4C1xP4" + "COyVDeuoAIxsB/uXwCnoOHoEVpADZP8CUNAZdAc9QXHIA56bBHyGg9YzUC7cFFaoB3G6GlBFeOoBZy8Ke/qRgq1YQ270APR4" + "Al1Cr9EhqHJmgkedh7sD4Ge7AGUdQgkoACgsDr1D6VmaL4Jz47xYhhq1DkgtJ1h9KPSaIJGnMOYruoXuocuQxcehsWAzM9Bc" + "NAZNh+sk8M3xsGLm10br0Z/oAljwKRj7Cj2E2BMLfFyD5+3ob5h9Aew4HnoWoo5gZ3HAwQPwoxhA6KPA0r6g56g9VHkR8HQQ" + "bHUVaoUk8KwY4Pwi6oWyoVyoDRoIz0MAL3ohducCPFEc+fg/PJVbsr7LskFzAJ7rhPqiquAPAioP/tMcVYZxAYhxGbw8zHXy" + "q4BAbvJX/BvEtDi+B/LzTOi5Dv47iQ/iXSDa9uUT+TTeizeCyDkK3o4E/LUavPYoP86vwHUt5KVrsO9tvgXmDOBzwdO381kw" + "PhQwc33o6Qy45ht7zt6yCMApeXgG5P9tkJdUHgkY4x92GCiOBSGuMvYOMtMz5oPa2M88gPzesIcQo++xF5AHr8P1NvzugAz4" + "AOgji4fK8SWsYGcCz8utXIV6pwjE+/K8NuxUCCJsLdi9HUScXLBvDog+9Xh96E/KmpON5wSk9Ra4OQVR28841Lqn2XZATKks" + "FNZKhVG3YQcJcFQYd7LPEN3DYJ98gJZdgNMMVpiXhCedpQDHCE4j8gCMT8j6gkmHmvYDcPg16ykF8lECy/wXZD9gqcx/S9Zh" + "fjjwLMFqHDCdwA0WAs0LY3U4T6YMMr+I4jDHBOlk7v+NMajJ3bDmOzj9VxhpByl9YjdBMq9h/ZfsFrsE0jnFjgBCPMk2sFWA" + "HLextWw5mwd36yB7zQe0PIdNAyy/AbLRQshQw9kU6N/H/mDLoKoZAW0zzN4I2Ws0GwLzFrAlMHoYIJe+bCqMmQH9fWHWDMjA" + "2wCH7oCxu2DXJ+wV6O4+aOwVcPMJatFPwNFd6HsE7Snc3QVOrwCufQTvnwLPz2HOY/ae/QSJp8GJ3kCzg4R0kIcGJwsyK+gw" + "G2iVQZ+Y9YWZyhFPgLVTs74ZSwRJPIP93rMvgFlT4PoeUFYCzMWcgEw1kLKPabCeAjoUuBfeuOGdBTK2BTSX+RUagvUj4UmC" + "0UF4p4AeEcjfAfIPQnOBTtJhxwSgL6DTz7DHBzhB5lnuw1nuAd1kf4PMTwFie5aF2U6BPG7AGd8D3YOnk5D/n8Cch9B/HGqb" + "83DuNzD7HNh+LEjkJTxfh/7tgFxOgA7Psr2AGdYB0jkNY87CmL9g5EUY9Qxs9Ro7A5b5AlZ4AatfgBkXofch+ETmzifg/Y0s" + "zu5D73XofZxlH09h/AewoR8gtUzJpcPZvf/5WVrWd3SMUZCaAXWuASdnIBkdbA+BNEx4MqE/CM0DErHDDCfc+0G6Bsz8l4ws" + "+8xcReaZI3WwXpYlvUSQpi9rTS9I8SM0b9a85CzNpWRpiAK+/Q7c2WFU5peCOoxxQKOgEQY7uWCcEzTmyfKLn2BdicBFpgc4" + "4ZoEazmybMYH751gHQ6Yk8m9BnNSss6dBL0JWfvHAb2DnTNl8SVrpWSYw4CLf79htIK1RPIoiFyleTGoggtlURmIKqXA54tA" + "1V8BYkwT3hjiSQ2oResDzmzD2/JWvDn8doZ4GcMH8t+zrkP5CIiM0wHrTAGaDL9zAN8tgjYPouVivgqq240QRxfyJXC/EbDR" + "Zoihq/kGiMKxgJNO8YOAy49CXL4FNdRtoJtQDb/g7wD3v4Xfp0AvIYa/4E/+o8fQnkM9/5rH8w8Q239Cre+CPGEHvOOG2O/M" + "ujqA0uDXBe8/8s8w7itP4Mk8Ba6JWTM8PIn/gJYIfZlfun6AFd/Avp8z/44aKB5mpMCoVOj5B3Z9Du/igJeHwN8d4OE1PL3L" + "4vMb7O3nBmA9g5tQqQazyOAUWSFXyUgEnGaDKisfygF1iIwsKArlRjmhT0SZowXokSEneoBnDZ4yv0PWss4QhDU1HgB+0+HZ" + "CyfL/NtqB/xqWd/oemBfjWd+s4wgQ2a+C3IF8imGJy/wYoV9MneKhL0iUQHA4uWBiqKCgDCrZH2pXAdQaUVUKeu75frQakNG" + "rQitMqoAWLMkUGkYWzyLMr91LoTyojyQo3PBunlh5QhYNxKFoXDYQYLz/PvVNAb+vf/x6wPOU7Iknwb3buA+Fe7c8NYP5M3i" + "WoNz/vsHAW4lsIqUJbd/v8KWQH4yXKX/VpeyrlAI//elNs36Jf/d/89vuDMl+b+/7/73G+/MHTL34P9jv/97/ffd/3369/d/" + "AYxHlHJ2PgAA" +) + + +@lru_cache(maxsize=1) +def ready_trigger_pcm() -> bytes: + return gzip.decompress(base64.b64decode(READY_TRIGGER_PCM_16KHZ_MONO_GZIP_B64)) diff --git a/litellm/llms/custom_httpx/llm_http_handler.py b/litellm/llms/custom_httpx/llm_http_handler.py index 9f18b669124..c426714a1bd 100644 --- a/litellm/llms/custom_httpx/llm_http_handler.py +++ b/litellm/llms/custom_httpx/llm_http_handler.py @@ -1300,16 +1300,15 @@ class BaseLLMHTTPHandler: if client is None or not isinstance(client, HTTPHandler): client = _get_httpx_client() + json_data = data if files is None and isinstance(data, dict) else None + try: - # Make the POST request - clean and simple, always use data and files response = client.post( url=complete_url, headers=headers, - data=data, + data=data if json_data is None else None, files=files, - json=( - data if files is None and isinstance(data, dict) else None - ), # Use json param only when no files and data is dict + json=json_data, timeout=timeout, ) except Exception as e: @@ -1373,16 +1372,15 @@ class BaseLLMHTTPHandler: else: async_httpx_client = client + json_data = data if files is None and isinstance(data, dict) else None + try: - # Make the async POST request - clean and simple, always use data and files response = await async_httpx_client.post( url=complete_url, headers=headers, - data=data, + data=data if json_data is None else None, files=files, - json=( - data if files is None and isinstance(data, dict) else None - ), # Use json param only when no files and data is dict + json=json_data, timeout=timeout, ) except Exception as e: @@ -1986,7 +1984,8 @@ class BaseLLMHTTPHandler: api_base=api_base, ) - headers = update_headers_with_filtered_beta(headers=headers, provider=custom_llm_provider) + if anthropic_messages_provider_config.should_filter_anthropic_beta_headers(): + headers = update_headers_with_filtered_beta(headers=headers, provider=custom_llm_provider) logging_obj.update_from_kwargs( kwargs=kwargs, @@ -2083,12 +2082,18 @@ class BaseLLMHTTPHandler: initial_response: Union[AsyncIterator, AnthropicMessagesResponse] if stream: + from litellm.llms.anthropic.experimental_pass_through.messages.streaming_iterator import ( + AnthropicMessagesStreamingResponse, + anthropic_messages_stream_hidden_params, + ) + completion_stream = anthropic_messages_provider_config.get_async_streaming_response_iterator( model=model, httpx_response=response, request_body=request_body, litellm_logging_obj=logging_obj, ) + stream_hidden_params = anthropic_messages_stream_hidden_params(response.headers) if not self._has_agentic_completion_hook(logging_obj): # No callback overrides async_should_run_agentic_loop, so the @@ -2096,7 +2101,10 @@ class BaseLLMHTTPHandler: # and rebuilding the response from SSE at end-of-stream to call # hooks that all return (False, {}). Stream through directly and # skip that per-chunk + end-of-stream overhead. - return completion_stream + return AnthropicMessagesStreamingResponse( + completion_stream=completion_stream, + hidden_params=stream_hidden_params, + ) from litellm.llms.anthropic.experimental_pass_through.messages.agentic_streaming_iterator import ( AgenticAnthropicStreamingIterator, @@ -2111,9 +2119,12 @@ class BaseLLMHTTPHandler: anthropic_messages_optional_request_params=anthropic_messages_optional_request_params, logging_obj=logging_obj, custom_llm_provider=custom_llm_provider, - kwargs=kwargs, + kwargs={**kwargs, "api_key": api_key} if api_key else kwargs, + ) + return AnthropicMessagesStreamingResponse( + completion_stream=initial_response, + hidden_params=stream_hidden_params, ) - return initial_response else: initial_response = anthropic_messages_provider_config.transform_anthropic_messages_response( model=model, @@ -2121,6 +2132,10 @@ class BaseLLMHTTPHandler: logging_obj=logging_obj, ) + # Inject api_key into kwargs so follow-up calls in agentic hooks can + # authenticate. api_key is a named param here (not in kwargs), so + # _prepare_followup_kwargs would miss it otherwise. + kwargs_for_agentic = {**kwargs, "api_key": api_key} if api_key else kwargs # Call agentic completion hooks (non-streaming path only) final_response = await self._call_agentic_completion_hooks( response=initial_response, @@ -2131,7 +2146,7 @@ class BaseLLMHTTPHandler: logging_obj=logging_obj, stream=False, custom_llm_provider=custom_llm_provider, - kwargs=kwargs, + kwargs=kwargs_for_agentic, ) return self._maybe_wrap_in_fake_stream( @@ -2897,6 +2912,7 @@ class BaseLLMHTTPHandler: try: response = sync_httpx_client.get(url=url, headers=headers, params=data) + response.raise_for_status() except Exception as e: raise self._handle_error( e=e, @@ -2968,9 +2984,9 @@ class BaseLLMHTTPHandler: try: response = await async_httpx_client.get(url=url, headers=headers, params=data) - + response.raise_for_status() except Exception as e: - verbose_logger.exception(f"Error retrieving response: {e}") + verbose_logger.debug(f"Error retrieving response: {e}") raise self._handle_error( e=e, provider_config=responses_api_provider_config, @@ -3061,6 +3077,7 @@ class BaseLLMHTTPHandler: try: response = sync_httpx_client.get(url=url, headers=headers, params=params) + response.raise_for_status() except Exception as e: raise self._handle_error(e=e, provider_config=responses_api_provider_config) @@ -3134,6 +3151,7 @@ class BaseLLMHTTPHandler: try: response = await async_httpx_client.get(url=url, headers=headers, params=params) + response.raise_for_status() except Exception as e: raise self._handle_error(e=e, provider_config=responses_api_provider_config) @@ -4720,6 +4738,13 @@ class BaseLLMHTTPHandler: except Exception as e: raise self._handle_error(e=e, provider_config=provider_config) + if response.status_code >= 400: + raise provider_config.get_error_class( + error_message=response.text, + status_code=response.status_code, + headers=response.headers, + ) + return provider_config.transform_file_content_response( raw_response=response, logging_obj=logging_obj, @@ -4776,6 +4801,13 @@ class BaseLLMHTTPHandler: except Exception as e: raise self._handle_error(e=e, provider_config=provider_config) + if response.status_code >= 400: + raise provider_config.get_error_class( + error_message=response.text, + status_code=response.status_code, + headers=response.headers, + ) + return provider_config.transform_file_content_response( raw_response=response, logging_obj=logging_obj, diff --git a/litellm/llms/deepseek/chat/transformation.py b/litellm/llms/deepseek/chat/transformation.py index 7a548136f2a..525de1476e2 100644 --- a/litellm/llms/deepseek/chat/transformation.py +++ b/litellm/llms/deepseek/chat/transformation.py @@ -35,7 +35,9 @@ class DeepSeekChatConfig(OpenAIGPTConfig): Map OpenAI params to DeepSeek params. Handles `thinking` and `reasoning_effort` parameters for DeepSeek reasoner models. - DeepSeek only supports `{"type": "enabled"}` - no budget_tokens like Anthropic. + DeepSeek supports `{"type": "enabled"}` and `{"type": "disabled"}` - no budget_tokens + like Anthropic. `reasoning_effort="none"` is the OpenAI-style way to ask for thinking + off, so it maps to `{"type": "disabled"}`; any other effort keeps thinking on. Reference: https://api-docs.deepseek.com/guides/thinking_mode """ @@ -47,15 +49,13 @@ class DeepSeekChatConfig(OpenAIGPTConfig): thinking_value = optional_params.pop("thinking", None) reasoning_effort = optional_params.pop("reasoning_effort", None) - # Handle thinking parameter - only accept {"type": "enabled"} - if thinking_value is not None: - if isinstance(thinking_value, dict) and thinking_value.get("type") == "enabled": - # DeepSeek only accepts {"type": "enabled"}, ignore budget_tokens - optional_params["thinking"] = {"type": "enabled"} + # Handle thinking parameter - accept both enabled and disabled, ignore budget_tokens + if isinstance(thinking_value, dict) and thinking_value.get("type") in ("enabled", "disabled"): + optional_params["thinking"] = {"type": thinking_value["type"]} - # Handle reasoning_effort - map to thinking enabled - elif reasoning_effort is not None and reasoning_effort != "none": - optional_params["thinking"] = {"type": "enabled"} + # Otherwise fall back to reasoning_effort: "none" disables, anything else enables + elif reasoning_effort is not None: + optional_params["thinking"] = {"type": "disabled" if reasoning_effort == "none" else "enabled"} return optional_params diff --git a/litellm/llms/gdc/__init__.py b/litellm/llms/gdc/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/litellm/llms/gdc/chat/__init__.py b/litellm/llms/gdc/chat/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/litellm/llms/gdc/chat/transformation.py b/litellm/llms/gdc/chat/transformation.py new file mode 100644 index 00000000000..61631920a64 --- /dev/null +++ b/litellm/llms/gdc/chat/transformation.py @@ -0,0 +1,285 @@ +""" +GDC Gemini chat completion transformation +""" + +import json +import os +import re +import threading +from typing import Any, Final +from urllib.parse import urlsplit + +import litellm +from litellm.llms.openai_like.chat.transformation import OpenAILikeChatConfig + + +class GDCGeminiConfig(OpenAILikeChatConfig): + supports_vertex_params: bool = True # Tell LiteLLM utilities not to strip vertex_ params + _GDCH_CREDENTIAL_TYPE: Final[str] = "gdch_service_account" + _PATH_ID_PATTERN: Final[re.Pattern[str]] = re.compile(r"^[a-zA-Z0-9_-]+$") + + def __init__(self, **kwargs: Any) -> None: + super().__init__(**kwargs) + self._creds_lock = threading.Lock() + self._gdch_creds_cache: dict = {} + + def get_supported_openai_params(self, model: str) -> list: + return [ + "vertex_project", + "vertex_location", + ] + super().get_supported_openai_params(model) + + def _resolve_project(self, optional_params: dict, litellm_params: dict) -> str | None: + return ( + litellm_params.get("vertex_project") + or litellm_params.get("vertex_ai_project") + or getattr(litellm, "vertex_project", None) + or optional_params.get("vertex_project") + or optional_params.get("vertex_ai_project") + ) + + def _resolve_location(self, optional_params: dict, litellm_params: dict) -> str | None: + return ( + litellm_params.get("vertex_location") + or litellm_params.get("vertex_ai_location") + or getattr(litellm, "vertex_location", None) + or optional_params.get("vertex_location") + or optional_params.get("vertex_ai_location") + ) + + def _effective_project(self, api_base: str, optional_params: dict, litellm_params: dict) -> str | None: + match = re.search(r"/v1/projects/([^/]+)", api_base) + if match: + return match.group(1) + return self._resolve_project(optional_params, litellm_params) + + def _validate_path_id(self, value: str, field: str, model: str) -> str: + if not self._PATH_ID_PATTERN.match(value): + raise litellm.utils.AuthenticationError( + message=f"{field} must be a plain identifier of letters, digits, hyphens or underscores.", + llm_provider="gdc", + model=model, + ) + return value + + def get_complete_url( + self, + api_base: str | None, + api_key: str | None, + model: str, + optional_params: dict, + litellm_params: dict, + stream: bool | None = None, + ) -> str: + api_base = api_base or litellm.gdc_api_base or litellm.api_base + if not api_base: + raise litellm.utils.AuthenticationError( + message="api_base/host is required for GDC Gemini. Please set it or pass it.", + llm_provider="gdc", + model=model, + ) + + if not api_base.startswith("http"): + api_base = f"https://{api_base}" + + api_base = api_base.rstrip("/") + + if "/v1/projects/" in api_base: + return api_base + + project = self._resolve_project(optional_params, litellm_params) + + if not project: + raise litellm.utils.AuthenticationError( + message="project is required for GDC Gemini. Please pass vertex_project.", + llm_provider="gdc", + model=model, + ) + + location = self._resolve_location(optional_params, litellm_params) + + if not location: + raise litellm.utils.AuthenticationError( + message="location is required for GDC Gemini. Please pass vertex_location.", + llm_provider="gdc", + model=model, + ) + + project = self._validate_path_id(project, "vertex_project", model) + location = self._validate_path_id(location, "vertex_location", model) + + return f"{api_base}/v1/projects/{project}/locations/{location}/chat/completions" + + def _read_env_bool(self, val: Any, env_var: str, default: bool = True) -> bool | str: + def _parse(s: str) -> bool | str: + cleaned = s.strip().lower() + if cleaned in ("false", "0", "no", "off"): + return False + if cleaned in ("true", "1", "yes", "on"): + return True + return s + + if val is not None: + if isinstance(val, str): + return _parse(val) + return val + + _env_val = os.getenv(env_var) + if _env_val is None: + return default + return _parse(_env_val) + + def _fetch_auth(self, gdch_creds: Any, ssl_verify: bool | str) -> None: + import requests + from google.auth.transport import requests as auth_requests + + auth_session = requests.Session() + auth_session.verify = ssl_verify + auth_request = auth_requests.Request(session=auth_session) + gdch_creds.refresh(auth_request) + + def _cached_fetch_token(self, creds: Any, audience: str, ssl_verify: bool | str, api_key: str | None = None) -> str: + # Key cache by both audience and credential identity to prevent cross-caller contamination + cache_key = (audience.rstrip("/"), api_key or str(id(creds))) + + with self._creds_lock: + if cache_key not in self._gdch_creds_cache: + self._gdch_creds_cache[cache_key] = creds.with_gdch_audience(audience.rstrip("/")) + + gdch_creds = self._gdch_creds_cache[cache_key] + + if not getattr(gdch_creds, "valid", False) or not getattr(gdch_creds, "token", None): + self._fetch_auth(gdch_creds, ssl_verify) + + token = gdch_creds.token + + return token + + def _load_creds_from_key(self, api_key: str) -> tuple[Any, bool]: + import google.auth + + try: + json_obj = json.loads(api_key) + except json.JSONDecodeError: + return None, False + if not isinstance(json_obj, dict) or json_obj.get("type") != self._GDCH_CREDENTIAL_TYPE: + raise ValueError( + "GDC only accepts a GDCH service account credential as a JSON api_key " + '(expected "type": "gdch_service_account"). Other Google credential types are ' + "rejected so their token or external-account endpoints cannot drive server-side requests." + ) + creds, _ = google.auth.load_credentials_from_dict(json_obj) + return creds, True + + def validate_environment( + self, + headers: dict, + model: str, + messages: list[Any], + optional_params: dict, + litellm_params: dict, + api_key: str | None = None, + api_base: str | None = None, + ) -> dict: + import google.auth.exceptions + + api_base = api_base or litellm.gdc_api_base or litellm.api_base + if not api_base: + raise litellm.utils.AuthenticationError( + message="api_base/host is required for GDC Gemini. Please set it or pass it.", + llm_provider="gdc", + model=model, + ) + + if not api_key: + raise litellm.utils.AuthenticationError( + message="api_key is required for GDC Gemini. Please pass your service account string or token as the api_key.", + llm_provider="gdc", + model=model, + ) + + project = self._effective_project(api_base, optional_params, litellm_params) + if not project: + raise litellm.utils.AuthenticationError( + message="project is required for GDC Gemini. Please pass vertex_project.", + llm_provider="gdc", + model=model, + ) + project = self._validate_path_id(project, "vertex_project", model) + + _audience_parts = urlsplit(api_base if api_base.startswith("http") else f"https://{api_base}") + audience = f"{_audience_parts.scheme}://{_audience_parts.netloc}" + + try: + creds, is_service_account = self._load_creds_from_key(api_key) + except ( + google.auth.exceptions.GoogleAuthError, + ValueError, + TypeError, + KeyError, + AttributeError, + ) as e: + raise litellm.utils.AuthenticationError( + message=f"Failed to load service account credentials from api_key: {str(e)}", + llm_provider="gdc", + model=model, + ) from e + + if creds is not None: + ssl_verify = self._read_env_bool(litellm_params.get("ssl_verify"), "SSL_VERIFY", default=True) + if self._read_env_bool(litellm_params.get("gdc_token_caching"), "GDC_TOKEN_CACHING", default=False): + token = self._cached_fetch_token(creds, audience, ssl_verify, api_key) + else: + gdch_creds = creds.with_gdch_audience(audience) + self._fetch_auth(gdch_creds, ssl_verify) + token = gdch_creds.token + headers["Authorization"] = f"Bearer {token}" + + if "Authorization" not in headers and not is_service_account: + headers["Authorization"] = f"Bearer {api_key}" + + # Standardize necessary metadata headers + if "content-type" not in headers and "Content-Type" not in headers: + headers["Content-Type"] = "application/json" + + stale_quota_headers = tuple(h for h in headers if h.lower() == "x-goog-user-project") + for stale in stale_quota_headers: + headers.pop(stale, None) + headers["x-goog-user-project"] = f"projects/{project}" + + return headers + + def transform_request( + self, + model: str, + messages: list[Any], + optional_params: dict, + litellm_params: dict, + headers: dict, + ) -> dict: + """ + Transforms the request to the GDC provider + """ + if model.startswith("gdc/"): + model = model.split("/", 1)[1] + + data = super().transform_request( + model=model, + messages=messages, + optional_params=optional_params, + litellm_params=litellm_params, + headers=headers, + ) + + # Remove extra params used for routing/auth + for param in [ + "vertex_project", + "vertex_ai_project", + "vertex_location", + "vertex_ai_location", + "ssl_verify", + "gdc_token_caching", + ]: + data.pop(param, None) + + return data diff --git a/litellm/llms/github_copilot/messages/__init__.py b/litellm/llms/github_copilot/messages/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/litellm/llms/github_copilot/messages/transformation.py b/litellm/llms/github_copilot/messages/transformation.py new file mode 100644 index 00000000000..fb3f0a4e159 --- /dev/null +++ b/litellm/llms/github_copilot/messages/transformation.py @@ -0,0 +1,118 @@ +from typing import Any, Optional + +from litellm.exceptions import AuthenticationError +from litellm.llms.anthropic.experimental_pass_through.messages.transformation import ( + AnthropicMessagesConfig, +) + +from ..authenticator import Authenticator +from ..common_utils import ( + DEFAULT_GITHUB_COPILOT_API_BASE, + GetAPIKeyError, + get_copilot_default_headers, +) + +_MESSAGES_PROXY_API_VERSION = "2026-06-01" + + +class GithubCopilotAnthropicMessagesConfig(AnthropicMessagesConfig): + """ + GitHub Copilot implementation of Anthropic messages API. + Routes requests to Copilot's /v1/messages endpoint with appropriate authentication and headers. + """ + + def __init__(self) -> None: + super().__init__() + self.authenticator = Authenticator() + + def handles_web_search_natively(self) -> bool: + """ + Copilot's /v1/messages endpoint does not execute ``web_search`` tools, so + the interception handler must short-circuit web-search-only requests + instead of routing them here. + """ + return False + + def should_filter_anthropic_beta_headers(self) -> bool: + """ + Copilot's /v1/messages is a native Anthropic Messages passthrough, so + ``anthropic-beta`` values injected by ``_update_headers_with_anthropic_beta`` + (context_management, structured outputs, ...) must reach the upstream + verbatim. The default provider-scoped filter would drop them because + github_copilot has no entry in ``anthropic_beta_headers_config.json``. + """ + return False + + def validate_anthropic_messages_environment( + self, + headers: dict, + model: str, + messages: list[Any], + optional_params: dict, + litellm_params: dict, + api_key: Optional[str] = None, + api_base: Optional[str] = None, + ) -> tuple[dict, Optional[str]]: + """ + Validate environment for GitHub Copilot and add Copilot-specific headers. + + The caller-supplied ``api_base`` is intentionally ignored. Routing this + request anywhere other than the authenticated Copilot endpoint would + leak the Copilot bearer token to a caller-controlled URL. + """ + # Always use the Copilot endpoint resolved from the authenticated + # session, never the caller-supplied api_base. rstrip so a + # tenant-specific base with a trailing slash does not yield a + # double-slash URL once "/v1/messages" is appended downstream. + dynamic_api_base = (self.authenticator.get_api_base() or DEFAULT_GITHUB_COPILOT_API_BASE).rstrip("/") + try: + dynamic_api_key = self.authenticator.get_api_key() + except GetAPIKeyError as e: + raise AuthenticationError( + model=model, + llm_provider="github_copilot", + message=str(e), + ) + + # Merge Copilot headers with provided headers + copilot_headers = get_copilot_default_headers(dynamic_api_key) + for key, value in copilot_headers.items(): + if key not in headers: + headers[key] = value + + headers["openai-intent"] = "messages-proxy" + headers["x-interaction-type"] = "messages-proxy" + headers["x-github-api-version"] = _MESSAGES_PROXY_API_VERSION + + if "anthropic-version" not in headers: + headers["anthropic-version"] = "2023-06-01" + + headers = self._update_headers_with_anthropic_beta( + headers, optional_params, custom_llm_provider="github_copilot" + ) + + return headers, dynamic_api_base + + def get_complete_url( + self, + api_base: Optional[str], + api_key: Optional[str], + model: str, + optional_params: dict, + litellm_params: dict, + stream: Optional[bool] = None, + ) -> str: + """ + Return the complete URL for GitHub Copilot /v1/messages endpoint. + + ``api_base`` here is the value already resolved by + ``validate_anthropic_messages_environment`` (the authenticated Copilot + host), not the raw caller-supplied base — that one is discarded there to + avoid leaking the Copilot bearer token to a caller-controlled URL. We + reuse it to avoid a second authenticator read, falling back to a fresh + resolution only if it was not provided. + """ + resolved = (api_base or self.authenticator.get_api_base() or DEFAULT_GITHUB_COPILOT_API_BASE).rstrip("/") + if not resolved.endswith("/v1/messages"): + resolved = f"{resolved}/v1/messages" + return resolved diff --git a/litellm/llms/oci/chat/cohere.py b/litellm/llms/oci/chat/cohere.py index 3661ac908d2..ca85a6309d7 100644 --- a/litellm/llms/oci/chat/cohere.py +++ b/litellm/llms/oci/chat/cohere.py @@ -110,7 +110,7 @@ def adapt_messages_to_cohere_standard( tool_calls: Optional[List[CohereToolCall]] = None if role == "assistant" and msg.get("tool_calls"): # type: ignore[union-attr,typeddict-item] tool_calls = [] - for tc in msg["tool_calls"]: # type: ignore[union-attr,typeddict-item] + for tc in msg["tool_calls"]: # pyright: ignore[reportOptionalIterable] # truthiness check above rules out None raw_arguments: Any = tc.get("function", {}).get("arguments", {}) if isinstance(raw_arguments, str): try: diff --git a/litellm/llms/ollama/chat/transformation.py b/litellm/llms/ollama/chat/transformation.py index 3152ded2367..694f8cdd6c2 100644 --- a/litellm/llms/ollama/chat/transformation.py +++ b/litellm/llms/ollama/chat/transformation.py @@ -363,7 +363,11 @@ class OllamaChatConfig(BaseConfig): response_json_message["reasoning_content"] = reasoning_content response_json_message["content"] = content - if request_data.get("format", "") == "json" and litellm_params.get("function_name") is not None: + if ( + request_data.get("format", "") == "json" + and litellm_params.get("function_name") is not None + and response_json_message is not None + ): function_call = json.loads(response_json_message["content"]) message = litellm.Message( content=None, diff --git a/litellm/llms/openai/chat/gpt_transformation.py b/litellm/llms/openai/chat/gpt_transformation.py index 396ad5b105e..f2498c0a7e2 100644 --- a/litellm/llms/openai/chat/gpt_transformation.py +++ b/litellm/llms/openai/chat/gpt_transformation.py @@ -2,6 +2,7 @@ Support for gpt model family """ +import json from typing import ( TYPE_CHECKING, Any, @@ -782,8 +783,30 @@ class OpenAIChatCompletionStreamingHandler(BaseModelResponseIterator): delta["reasoning_content"] = delta.pop("reasoning") return choices + @staticmethod + def _extract_error_from_chunk(chunk: dict) -> Optional[tuple[str, int]]: + """OpenAI-compatible backends (vLLM, sglang) can return an HTTP 200 + stream whose body carries an error payload, e.g. + ``data: {"error": {"message": "...", "code": 400}}``.""" + error = chunk.get("error") + if not error: + return None + if not isinstance(error, dict): + return str(error), 500 + message = error.get("message") + code = error.get("code") + status_code = code if isinstance(code, int) and 400 <= code < 600 else 500 + return (message if isinstance(message, str) else json.dumps(error)), status_code + def chunk_parser(self, chunk: dict) -> ModelResponseStream: try: + error_details = self._extract_error_from_chunk(chunk) + if error_details is not None: + error_message, error_status_code = error_details + raise OpenAIError( + status_code=error_status_code, + message=error_message, + ) choices = chunk.get("choices", []) choices = self._map_reasoning_to_reasoning_content(choices) diff --git a/litellm/llms/openai/chat/guardrail_translation/handler.py b/litellm/llms/openai/chat/guardrail_translation/handler.py index c7a49a2e47f..a6b6a6267c3 100644 --- a/litellm/llms/openai/chat/guardrail_translation/handler.py +++ b/litellm/llms/openai/chat/guardrail_translation/handler.py @@ -716,7 +716,7 @@ class OpenAIChatCompletionsHandler(BaseTranslation): elif isinstance(content, list) and content_idx_optional is not None: # Replace specific text item in list content - choice.message.content[content_idx_optional]["text"] = guardrail_response # type: ignore + content[content_idx_optional]["text"] = guardrail_response async def _apply_guardrail_responses_to_output_tool_calls( self, diff --git a/litellm/llms/openai/responses/guardrail_translation/handler.py b/litellm/llms/openai/responses/guardrail_translation/handler.py index 6ac33ffa44a..093dffccac0 100644 --- a/litellm/llms/openai/responses/guardrail_translation/handler.py +++ b/litellm/llms/openai/responses/guardrail_translation/handler.py @@ -45,6 +45,7 @@ from litellm.types.llms.openai import ( AllMessageValues, ChatCompletionToolCallChunk, ChatCompletionToolParam, + ResponsesAPIStreamEvents, ) from litellm.types.responses.main import ( GenericResponseOutputItem, @@ -196,12 +197,13 @@ class OpenAIResponsesHandler(BaseTranslation): return data def extract_request_tool_names(self, data: dict) -> List[str]: - """Extract tool names from Responses API request (tools[].name for function, tools[].server_label for mcp).""" + """Extract tool names from Responses API request (tools[].name for function + and custom, tools[].server_label for mcp).""" names: List[str] = [] for tool in data.get("tools") or []: if not isinstance(tool, dict): continue - if tool.get("type") == "function" and tool.get("name"): + if tool.get("type") in ("function", "custom") and tool.get("name"): names.append(str(tool["name"])) elif tool.get("type") == "mcp" and tool.get("server_label"): names.append(str(tool["server_label"])) @@ -586,7 +588,14 @@ class OpenAIResponsesHandler(BaseTranslation): """ Check if the streaming has ended. """ - return all(response.choices[0].finish_reason is not None for response in responses_so_far) + if not responses_so_far: + return False + terminal_types = { + ResponsesAPIStreamEvents.RESPONSE_COMPLETED.value, + ResponsesAPIStreamEvents.RESPONSE_FAILED.value, + ResponsesAPIStreamEvents.RESPONSE_INCOMPLETE.value, + } + return responses_so_far[-1].get("type") in terminal_types def get_streaming_string_so_far(self, responses_so_far: List[Any]) -> str: """ diff --git a/litellm/llms/openai_like/dynamic_config.py b/litellm/llms/openai_like/dynamic_config.py index 3c763ed9b9b..31c913d5d4e 100644 --- a/litellm/llms/openai_like/dynamic_config.py +++ b/litellm/llms/openai_like/dynamic_config.py @@ -91,7 +91,7 @@ def create_config_class(provider: SimpleProviderConfig): def get_supported_openai_params(self, model: str) -> list: """Get supported OpenAI params, excluding tool-related params for models that don't support function calling.""" - from litellm.utils import supports_function_calling + from litellm.utils import supports_function_calling, supports_reasoning supported_params = super().get_supported_openai_params(model=model) @@ -113,6 +113,10 @@ def create_config_class(provider: SimpleProviderConfig): f"function calling — removed tool-related params from supported params." ) + _supports_reasoning = supports_reasoning(model=model, custom_llm_provider=provider.slug) + if _supports_reasoning and "reasoning_effort" not in supported_params: + supported_params.append("reasoning_effort") + return supported_params def map_openai_params( diff --git a/litellm/llms/openai_like/messages/__init__.py b/litellm/llms/openai_like/messages/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/litellm/llms/openai_like/messages/transformation.py b/litellm/llms/openai_like/messages/transformation.py new file mode 100644 index 00000000000..4963bcca9ac --- /dev/null +++ b/litellm/llms/openai_like/messages/transformation.py @@ -0,0 +1,134 @@ +from typing import Any, Optional + +import litellm +from litellm.llms.anthropic.experimental_pass_through.messages.transformation import ( + AnthropicMessagesConfig, +) +from litellm.llms.openai_like.json_loader import SimpleProviderConfig +from litellm.secret_managers.main import get_secret_str + +DEFAULT_ANTHROPIC_API_VERSION = "2023-06-01" + + +class OpenAILikeAnthropicMessagesConfig(AnthropicMessagesConfig): + """ + Forwards Anthropic /v1/messages requests to an OpenAI-compatible server that + also natively exposes the Anthropic Messages API, with no translation. + + Opted into per deployment via ``model_info.supported_endpoints`` containing + ``"/v1/messages"``. The inbound Anthropic payload (system, cache_control, + thinking, tools, ...) is forwarded essentially unchanged to + ``{api_base}/v1/messages``, so Anthropic-only features that the + Anthropic->OpenAI translation would otherwise drop are preserved. Response + parsing and streaming are inherited from the native Anthropic config. + """ + + def validate_anthropic_messages_environment( + self, + headers: dict[str, str], + model: str, + messages: list[Any], + optional_params: dict, + litellm_params: dict, + api_key: Optional[str] = None, + api_base: Optional[str] = None, + ) -> tuple[dict[str, str], Optional[str]]: + present = {key.lower() for key in headers} + needs_auth = bool(api_key) and "authorization" not in present and "x-api-key" not in present + defaults: dict[str, str] = { + **({"authorization": f"Bearer {api_key}"} if needs_auth else {}), + **({"anthropic-version": DEFAULT_ANTHROPIC_API_VERSION} if "anthropic-version" not in present else {}), + **({"content-type": "application/json"} if "content-type" not in present else {}), + } + combined = {**headers, **defaults} + normalized = { + ("anthropic-beta" if key.lower() == "anthropic-beta" else key): value for key, value in combined.items() + } + merged = self._update_headers_with_anthropic_beta( + headers=normalized, + optional_params=optional_params, + ) + return merged, api_base + + def should_filter_anthropic_beta_headers(self) -> bool: + return False + + def get_complete_url( + self, + api_base: Optional[str], + api_key: Optional[str], + model: str, + optional_params: dict, + litellm_params: dict, + stream: Optional[bool] = None, + ) -> str: + if not api_base: + raise ValueError("api_base is required to forward Anthropic /v1/messages to a native endpoint") + base = api_base.rstrip("/") + if base.endswith("/v1/messages"): + return base + if base.endswith("/v1"): + base = base[: -len("/v1")] + return f"{base}/v1/messages" + + +class JSONProviderAnthropicMessagesConfig(OpenAILikeAnthropicMessagesConfig): + """ + Provider-level native Anthropic Messages passthrough for JSON-configured + OpenAI-compatible providers whose ``supported_endpoints`` in providers.json + includes ``"/v1/messages"``. Resolves the api key and api base from the + provider's configured env vars, then forwards the Anthropic payload + untranslated like ``OpenAILikeAnthropicMessagesConfig``. + """ + + def __init__(self, provider: SimpleProviderConfig): + super().__init__() + self._provider = provider + + def should_strip_billing_metadata(self) -> bool: + return True + + def _resolve_api_key(self, api_key: Optional[str]) -> Optional[str]: + return api_key or get_secret_str(self._provider.api_key_env) or litellm.api_key + + def _resolve_api_base(self, api_base: Optional[str]) -> str: + env_api_base = get_secret_str(self._provider.api_base_env) if self._provider.api_base_env else None + return api_base or env_api_base or self._provider.base_url + + def validate_anthropic_messages_environment( + self, + headers: dict[str, str], + model: str, + messages: list[Any], + optional_params: dict, + litellm_params: dict, + api_key: Optional[str] = None, + api_base: Optional[str] = None, + ) -> tuple[dict[str, str], Optional[str]]: + return super().validate_anthropic_messages_environment( + headers=headers, + model=model, + messages=messages, + optional_params=optional_params, + litellm_params=litellm_params, + api_key=self._resolve_api_key(api_key), + api_base=api_base, + ) + + def get_complete_url( + self, + api_base: Optional[str], + api_key: Optional[str], + model: str, + optional_params: dict, + litellm_params: dict, + stream: Optional[bool] = None, + ) -> str: + return super().get_complete_url( + api_base=self._resolve_api_base(api_base), + api_key=api_key, + model=model, + optional_params=optional_params, + litellm_params=litellm_params, + stream=stream, + ) diff --git a/litellm/llms/openai_like/providers.json b/litellm/llms/openai_like/providers.json index d87346fea70..164100d4194 100644 --- a/litellm/llms/openai_like/providers.json +++ b/litellm/llms/openai_like/providers.json @@ -168,6 +168,13 @@ }, "supported_endpoints": ["/v1/chat/completions", "/v1/responses"] }, + "meta": { + "base_url": "https://api.meta.ai/v1", + "api_key_env": "META_API_KEY", + "api_base_env": "META_API_BASE", + "base_class": "openai_gpt", + "supported_endpoints": ["/v1/chat/completions", "/v1/responses", "/v1/messages"] + }, "pinstripes": { "base_url": "https://pinstripes.io/v1", "api_key_env": "PINSTRIPES_API_KEY", diff --git a/litellm/llms/sap/chat/transformation.py b/litellm/llms/sap/chat/transformation.py index d9d0f9bc236..4bf8272a334 100755 --- a/litellm/llms/sap/chat/transformation.py +++ b/litellm/llms/sap/chat/transformation.py @@ -155,7 +155,7 @@ class GenAIHubOrchestrationConfig(OpenAIGPTConfig): def headers(self) -> Dict[str, str]: if self.token_creator is None: self.run_env_setup() - access_token = self.token_creator() # type: ignore + access_token = self.token_creator() # pyright: ignore[reportOptionalCall] # run_env_setup set it or raised return { "Authorization": access_token, "AI-Resource-Group": self.resource_group, diff --git a/litellm/llms/tencent/__init__.py b/litellm/llms/tencent/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/litellm/llms/tencent/chat/__init__.py b/litellm/llms/tencent/chat/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/litellm/llms/tencent/chat/transformation.py b/litellm/llms/tencent/chat/transformation.py new file mode 100644 index 00000000000..4dea0c4b8c7 --- /dev/null +++ b/litellm/llms/tencent/chat/transformation.py @@ -0,0 +1,68 @@ +""" +Translates from OpenAI's `/v1/chat/completions` to Tencent TokenHub's +OpenAI-compatible endpoint. +""" + +from typing import Optional + +from litellm.secret_managers.main import get_secret_str +from litellm.utils import supports_reasoning + +from ...openai.chat.gpt_transformation import OpenAIGPTConfig + + +class TencentChatConfig(OpenAIGPTConfig): + def get_supported_openai_params(self, model: str) -> list: + params = super().get_supported_openai_params(model) + if supports_reasoning(model, custom_llm_provider="tencent"): + params.extend(["thinking", "reasoning_effort"]) + return params + + def map_openai_params( + self, + non_default_params: dict, + optional_params: dict, + model: str, + drop_params: bool, + ) -> dict: + optional_params = super().map_openai_params(non_default_params, optional_params, model, drop_params) + + thinking_value = optional_params.pop("thinking", None) + reasoning_effort = optional_params.pop("reasoning_effort", None) + + if thinking_value is not None: + if isinstance(thinking_value, dict): + optional_params["thinking"] = thinking_value + elif reasoning_effort is not None and reasoning_effort != "none": + optional_params["thinking"] = {"type": "enabled"} + + return optional_params + + def _get_openai_compatible_provider_info( + self, api_base: Optional[str], api_key: Optional[str] + ) -> tuple[Optional[str], Optional[str]]: + api_base = api_base or get_secret_str("TENCENT_API_BASE") or "https://tokenhub-intl.tencentcloudmaas.com/v1" + dynamic_api_key = api_key or get_secret_str("TENCENT_API_KEY") + return api_base, dynamic_api_key + + def get_complete_url( + self, + api_base: Optional[str], + api_key: Optional[str], + model: str, + optional_params: dict, + litellm_params: dict, + stream: Optional[bool] = None, + ) -> str: + if not api_base: + api_base = "https://tokenhub-intl.tencentcloudmaas.com/v1" + + api_base = api_base.rstrip("/") + + if api_base.endswith("/chat/completions"): + return api_base + + if not api_base.endswith("/v1"): + api_base = f"{api_base}/v1" + + return f"{api_base}/chat/completions" diff --git a/litellm/llms/tencent/cost_calculator.py b/litellm/llms/tencent/cost_calculator.py new file mode 100644 index 00000000000..d9aebdc3284 --- /dev/null +++ b/litellm/llms/tencent/cost_calculator.py @@ -0,0 +1,6 @@ +from litellm.litellm_core_utils.llm_cost_calc.utils import generic_cost_per_token +from litellm.types.utils import Usage + + +def cost_per_token(model: str, usage: Usage) -> tuple[float, float]: + return generic_cost_per_token(model=model, usage=usage, custom_llm_provider="tencent") diff --git a/litellm/llms/tencent/messages/__init__.py b/litellm/llms/tencent/messages/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/litellm/llms/tencent/messages/transformation.py b/litellm/llms/tencent/messages/transformation.py new file mode 100644 index 00000000000..e0f13aa9ca4 --- /dev/null +++ b/litellm/llms/tencent/messages/transformation.py @@ -0,0 +1,85 @@ +""" +Tencent Anthropic-compatible messages transformation config. + +Tencent TokenHub exposes an Anthropic-compatible Messages API endpoint +alongside its standard OpenAI-compatible chat completions endpoint. +""" + +from typing import Any, Optional + +import litellm +from litellm.llms.anthropic.experimental_pass_through.messages.transformation import ( + AnthropicMessagesConfig, +) +from litellm.secret_managers.main import get_secret_str + + +class TencentAnthropicMessagesConfig(AnthropicMessagesConfig): + """ + Tencent TokenHub exposes an Anthropic-compatible Messages API. + + Unlike the chat completions endpoint (which uses /v1), the Anthropic + endpoint may use a different base URL. Configure via + TENCENT_ANTHROPIC_API_BASE or TENCENT_API_BASE. + """ + + @property + def custom_llm_provider(self) -> Optional[str]: + return "tencent" + + def should_strip_billing_metadata(self) -> bool: + return True + + @staticmethod + def get_api_key(api_key: Optional[str] = None) -> Optional[str]: + return api_key or get_secret_str("TENCENT_API_KEY") or litellm.api_key + + @staticmethod + def get_api_base(api_base: Optional[str] = None) -> str: + return ( + api_base + or get_secret_str("TENCENT_ANTHROPIC_API_BASE") + or get_secret_str("TENCENT_API_BASE") + or "https://tokenhub-intl.tencentcloudmaas.com" + ) + + def validate_anthropic_messages_environment( + self, + headers: dict, + model: str, + messages: list[Any], + optional_params: dict, + litellm_params: dict, + api_key: Optional[str] = None, + api_base: Optional[str] = None, + ) -> tuple[dict, Optional[str]]: + return super().validate_anthropic_messages_environment( + headers=headers, + model=model, + messages=messages, + optional_params=optional_params, + litellm_params=litellm_params, + api_key=self.get_api_key(api_key=api_key), + api_base=api_base, + ) + + def get_complete_url( + self, + api_base: Optional[str], + api_key: Optional[str], + model: str, + optional_params: dict, + litellm_params: dict, + stream: Optional[bool] = None, + ) -> str: + base_url = self.get_api_base(api_base=api_base).rstrip("/") + + if base_url.endswith("/v1/messages"): + return base_url + + if base_url.endswith("/v1/chat/completions"): + base_url = base_url[: -len("/v1/chat/completions")] + elif base_url.endswith("/v1"): + base_url = base_url[: -len("/v1")] + + return f"{base_url}/v1/messages" diff --git a/litellm/llms/tinyfish/search/transformation.py b/litellm/llms/tinyfish/search/transformation.py index 4b7d38e3661..cef5f9cd02e 100644 --- a/litellm/llms/tinyfish/search/transformation.py +++ b/litellm/llms/tinyfish/search/transformation.py @@ -6,53 +6,42 @@ Docs: https://docs.tinyfish.ai/search-api from __future__ import annotations -from typing import Literal, TypedDict +import json +from typing import Literal from urllib.parse import urlencode import httpx -from pydantic import BaseModel, TypeAdapter, ValidationError +from pydantic import TypeAdapter, ValidationError +from litellm._logging import verbose_logger from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj +from litellm.llms.base_llm.chat.transformation import BaseLLMException from litellm.llms.base_llm.search.transformation import ( BaseSearchConfig, SearchResponse, - SearchResult, ) from litellm.secret_managers.main import get_secret_str - -class _TinyfishSearchRequestRequired(TypedDict): - query: str - - -class TinyfishSearchRequest(_TinyfishSearchRequestRequired, total=False): - location: str - language: str - page: int - include_thumbnail: bool - max_results: int - - -class _TinyfishResultItem(BaseModel, frozen=True): - title: str = "" - url: str = "" - snippet: str = "" - - -class _TinyfishApiResponse(BaseModel, frozen=True): - results: tuple[_TinyfishResultItem, ...] = () - - _UrlEncodableParams = TypeAdapter(dict[str, str | int | bool]) _StrList = TypeAdapter(list[str]) _StrFrozenSet = TypeAdapter(frozenset[str]) _TINYFISH_PARAMS_KEY = "_tinyfish_params" +_TINYFISH_DOCS_URL = "https://docs.tinyfish.ai/search-api" +_TINYFISH_RESULT_CAP = 10 # TinyFish's natural per-page SERP ceiling class TinyfishSearchConfig(BaseSearchConfig): TINYFISH_API_BASE = "https://api.search.tinyfish.ai" + def __init__(self) -> None: + super().__init__() + # Threaded from transform_search_request → transform_search_response so the + # response slice honors the caller's max_results without re-sending it on + # the wire (TinyFish doesn't honor it server-side). Safe because the + # config is instantiated per-call via ProviderConfigManager. + self._caller_max_results: int | None = None + @staticmethod def ui_friendly_name() -> str: return "TinyFish" @@ -97,36 +86,77 @@ class TinyfishSearchConfig(BaseSearchConfig): optional_params: dict[str, object], **kwargs: object, ) -> dict[str, object]: + """ + Transform a LiteLLM search request to TinyFish's querystring format. + + Maps LiteLLM's unified-spec params (see + ``BaseSearchConfig.get_supported_perplexity_optional_params``) to + TinyFish equivalents: + - ``query`` (str or list[str]) → ``query`` (list joined by spaces) + - ``country`` → ``location`` + - ``search_domain_filter`` (list[str]) → folded into the query as + ``() (site:a OR site:b ...)`` (TinyFish has no first-class + field today; see ML-2084 for the planned ``include_domains``) + - ``max_results`` → not sent on the wire; stashed on + ``self._caller_max_results`` for client-side response truncation + (TinyFish doesn't honor it server-side) + - ``max_tokens_per_page`` → silently dropped (no TinyFish equivalent) + + Any other ``optional_params`` keys are forwarded to TinyFish as-is. + dict/list values are JSON-encoded so they survive ``urlencode``. + + Returns: + ``{_TINYFISH_PARAMS_KEY: }``. + ``get_complete_url`` reads this back to build the final URL. + """ resolved_query = " ".join(query) if isinstance(query, list) else query - request_data: TinyfishSearchRequest = {"query": resolved_query} - - country = optional_params.get("country") - if isinstance(country, str): - request_data["location"] = country - - raw_max = optional_params.get("max_results") - if isinstance(raw_max, (int, float, str)): - request_data["max_results"] = max(1, min(int(raw_max), 20)) - try: domains = _StrList.validate_python(optional_params.get("search_domain_filter")) except (ValidationError, TypeError): domains = [] if domains: - request_data["query"] = _append_domain_filters(request_data["query"], domains) + resolved_query = _append_domain_filters(resolved_query, domains) - result_data: dict[str, object] = dict(request_data) + request_data: dict[str, object] = {"query": resolved_query} + + country = optional_params.get("country") + if isinstance(country, str): + request_data["location"] = country + + # max_results is enforced client-side on the response (TinyFish ignores + # the param and always returns ~10). Clamp to [1, 10] and stash on self + # so transform_search_response can slice without re-reading the URL. + raw_max = optional_params.get("max_results") + if isinstance(raw_max, (int, float, str)): + try: + self._caller_max_results = max(1, min(int(raw_max), _TINYFISH_RESULT_CAP)) + except (ValueError, TypeError, OverflowError): + # OverflowError covers int(float('inf')) and similar non-finite floats. + verbose_logger.warning( + "TinyFish Search: max_results=%r is not a valid integer; ignoring.", + raw_max, + ) raw_supported: object = ( self.get_supported_perplexity_optional_params() # any-ok: base class returns bare set ) supported_perplexity = _StrFrozenSet.validate_python(raw_supported) for param, value in optional_params.items(): - if param not in supported_perplexity and param not in result_data: - result_data[param] = value + if param not in supported_perplexity and param not in request_data: + # `fetch` expects a JSON-encoded object on the wire; accept the + # natural Python dict form and serialize here so callers don't + # have to pre-stringify. + if isinstance(value, dict): + value = json.dumps(value, separators=(",", ":")) + # `urlencode` would render Python bool as "True"/"False" + # (capitalized). ux-labs validators require lowercase + # "true"/"false" (e.g. `include_thumbnail`); normalize here. + elif isinstance(value, bool): + value = "true" if value else "false" + request_data[param] = value - return {_TINYFISH_PARAMS_KEY: result_data} + return {_TINYFISH_PARAMS_KEY: request_data} def transform_search_response( self, @@ -134,24 +164,158 @@ class TinyfishSearchConfig(BaseSearchConfig): logging_obj: LiteLLMLoggingObj | None, **kwargs: object, ) -> SearchResponse: - raw_json: object = raw_response.json() # any-ok: httpx Response.json() -> Any - parsed = _TinyfishApiResponse.model_validate(raw_json) + """ + Transform a TinyFish response to LiteLLM's unified ``SearchResponse``. - max_results_str: str = "20" - if raw_response.request: - raw_param: object = raw_response.request.url.params.get( # any-ok: httpx QueryParams.get() -> Any - "max_results", "20" + Mappings (per-result): + - ``title`` → ``SearchResult.title`` (defaults to ``""`` if missing/null) + - ``url`` → ``SearchResult.url`` (defaults to ``""``) + - ``snippet`` → ``SearchResult.snippet`` (defaults to ``""``) + - all other per-result fields (``position``, ``site_name``, + ``thumbnail_url``, ``fetch``, ``fetch_error``, ...) ride through as + extras on ``SearchResult`` via its ``extra="allow"`` config. + + Top-level ``parameter_warnings`` (see ML-2085) is read when present and + each entry is re-fired via ``verbose_logger.warning``. Absent or + malformed entries are silently skipped — never throws. + + Error paths routed through ``self._wrap_error`` for uniform + ``"TinyFish Search: . See for details."`` wrapping: + - non-2xx HTTP status (caught here because ``AsyncHTTPHandler.get`` + does not call ``raise_for_status``) + - 200 with non-JSON body + - 200 with valid JSON whose shape doesn't satisfy ``SearchResponse`` + + Returns: + ``SearchResponse`` truncated to ``self._caller_max_results`` (or + ``_TINYFISH_RESULT_CAP`` when the caller didn't set ``max_results``). + """ + # AsyncHTTPHandler.get does not call raise_for_status, so non-2xx + # responses arrive here looking successful. Dispatch through + # get_error_class so callers see a uniform attributed error. + if not (200 <= raw_response.status_code < 300): + raise self._wrap_error( + error_message=raw_response.text, + status_code=raw_response.status_code, + headers=dict(raw_response.headers), ) - max_results_str = str(raw_param) - max_results: int = min(int(max_results_str), 20) - results = [ - SearchResult(title=item.title, url=item.url, snippet=item.snippet) for item in parsed.results[:max_results] - ] + try: + raw_json: object = raw_response.json() # any-ok: httpx Response.json() -> Any + except json.JSONDecodeError: + raise self._wrap_error( + error_message=f"Expected JSON response, got: {raw_response.text[:200]}", + status_code=raw_response.status_code, + headers=dict(raw_response.headers), + ) - return SearchResponse(results=results, object="search") + _default_missing_result_fields(raw_json) + + try: + parsed = SearchResponse.model_validate(raw_json) + except ValidationError as e: + raise self._wrap_error( + error_message=(f"Response shape does not match LiteLLM's SearchResponse schema: {e}"), + status_code=raw_response.status_code, + headers=dict(raw_response.headers), + ) + + _emit_parameter_warnings(parsed) + + max_results = self._caller_max_results or _TINYFISH_RESULT_CAP + return SearchResponse(results=list(parsed.results[:max_results])) + + def _wrap_error( + self, + error_message: str, + status_code: int, + headers: dict[str, str], + ) -> Exception: + """ + Build an attributed ``BaseLLMException`` from a TinyFish error body. + + Used only at the call sites we control inside + ``transform_search_response`` (non-2xx, JSONDecodeError, ValidationError). + Not an override of ``BaseSearchConfig.get_error_class``: that path is + left to inherit from the base so it auto-picks-up any future LiteLLM + improvements. Trade-off: network failures (routed through LiteLLM + core's ``_handle_error`` → ``BaseSearchConfig.get_error_class``) won't + carry the ``TinyFish Search:`` prefix — the bare error already names + the host in the URL, so attribution is implicit there. + """ + # ux-labs frontend wraps every error body as {"error": {"code", "message", "details"?}}. + # Best-effort unwrap to surface the inner message; fall back to the raw body + # for non-ux-labs responses (CDN HTML pages, other JSON envelopes, plain text). + inner_message = error_message + try: + body: object = json.loads(error_message) # any-ok: json.loads -> Any + if isinstance(body, dict): + error_obj: object = body.get("error") # any-ok: untyped dict + if isinstance(error_obj, dict): + candidate: object = error_obj.get("message") # any-ok: untyped dict + if isinstance(candidate, str) and candidate: + inner_message = candidate + except (json.JSONDecodeError, TypeError): + pass + + return BaseLLMException( + status_code=status_code, + message=f"TinyFish Search: {inner_message}. See {_TINYFISH_DOCS_URL} for details.", + headers=headers, + ) def _append_domain_filters(query: str, domains: list[str]) -> str: domain_clauses = " OR ".join(f"site:{d}" for d in domains) return f"({query}) ({domain_clauses})" + + +def _default_missing_result_fields(raw_json: object) -> None: + """Default missing/null title/url/snippet to "" on each result item in place. + + SearchResult requires these three fields; a degraded TinyFish result flows + through with empty strings instead of failing the whole call. + """ + if not isinstance(raw_json, dict): + return + results_in = raw_json.get("results") + if not isinstance(results_in, list): + return + for item in results_in: + if not isinstance(item, dict): + continue + for field in ("title", "url", "snippet"): + if not isinstance(item.get(field), str): + item[field] = "" + + +def _emit_parameter_warnings(parsed: SearchResponse) -> None: + """Re-fire TinyFish-side ``parameter_warnings`` (see ML-2085) as warnings. + + Defensive: skip silently on any shape we don't recognize so a malformed + entry (or an early/partial rollout of the field) never throws. + Schema per entry: ``{type, parameter, message, docs_url?}``. + """ + warnings_field: object = ( + getattr(parsed, "parameter_warnings", None) # any-ok: extras=allow field + ) + if not isinstance(warnings_field, list): + return + for entry in warnings_field: + if not isinstance(entry, dict): + continue + warning_type: object = entry.get("type") # any-ok: untyped dict + parameter: object = entry.get("parameter") # any-ok: untyped dict + message: object = entry.get("message") # any-ok: untyped dict + if not isinstance(warning_type, str) or not warning_type: + continue + if not isinstance(parameter, str) or not parameter: + continue + if not isinstance(message, str) or not message: + continue + verbose_logger.warning( + "TinyFish Search parameter_warning (%s) `%s`: %s", + warning_type, + parameter, + message, + ) diff --git a/litellm/llms/vertex_ai/audio_transcription/transformation.py b/litellm/llms/vertex_ai/audio_transcription/transformation.py new file mode 100644 index 00000000000..03769bf2601 --- /dev/null +++ b/litellm/llms/vertex_ai/audio_transcription/transformation.py @@ -0,0 +1,194 @@ +import base64 + +from httpx import Headers, Response + +import litellm +from litellm.exceptions import UnsupportedParamsError +from litellm.litellm_core_utils.audio_utils.utils import ( + normalize_transcription_language_to_bcp47, + process_audio_file, +) +from litellm.llms.base_llm.audio_transcription.transformation import ( + AudioTranscriptionRequestData, + BaseAudioTranscriptionConfig, +) +from litellm.llms.base_llm.chat.transformation import BaseLLMException +from litellm.llms.vertex_ai.common_utils import VertexAIError, validate_vertex_location +from litellm.llms.vertex_ai.vertex_llm_base import VertexBase +from litellm.types.llms.openai import ( + AllMessageValues, + OpenAIAudioTranscriptionOptionalParams, +) +from litellm.types.llms.vertex_ai_speech_to_text import ( + VertexSpeechToTextAutoDecodingConfig, + VertexSpeechToTextRecognitionConfig, + VertexSpeechToTextRecognitionFeatures, + VertexSpeechToTextRecognizeRequest, + VertexSpeechToTextRecognizeResponse, +) +from litellm.types.utils import FileTypes, TranscriptionResponse + +DEFAULT_SPEECH_TO_TEXT_LOCATION = "us" +AUTO_LANGUAGE_CODE = "auto" +SUPPORTED_RESPONSE_FORMATS = ("json", "text") +_URL_UNSAFE_PROJECT_CHARS = ("/", "?", "#", "\\", ":", " ", "\t", "\n", "\r") + + +class VertexAIAudioTranscriptionConfig(BaseAudioTranscriptionConfig, VertexBase): + def __init__(self) -> None: + BaseAudioTranscriptionConfig.__init__(self) + VertexBase.__init__(self) + + def get_supported_openai_params(self, model: str) -> list[OpenAIAudioTranscriptionOptionalParams]: + return ["language", "response_format"] + + def map_openai_params( + self, + non_default_params: dict, + optional_params: dict, + model: str, + drop_params: bool, + ) -> dict: + supported_params = self.get_supported_openai_params(model) + mapped = { + **optional_params, + **{k: v for k, v in non_default_params.items() if k in supported_params}, + } + response_format = mapped.get("response_format") + if response_format is None or response_format in SUPPORTED_RESPONSE_FORMATS: + return mapped + if drop_params or litellm.drop_params: + return {k: v for k, v in mapped.items() if k != "response_format"} + raise UnsupportedParamsError( + status_code=400, + message=( + f"Google Speech-to-Text does not support response_format={response_format!r}. " + f"Supported values: {', '.join(SUPPORTED_RESPONSE_FORMATS)}. " + "To drop unsupported openai params from the call, set `litellm.drop_params = True`" + ), + ) + + def get_error_class(self, error_message: str, status_code: int, headers: dict | Headers) -> BaseLLMException: + return VertexAIError(status_code=status_code, message=error_message, headers=headers) + + def validate_environment( + self, + headers: dict, + model: str, + messages: list[AllMessageValues], + optional_params: dict, + litellm_params: dict, + api_key: str | None = None, + api_base: str | None = None, + ) -> dict: + access_token, project_id = self._ensure_access_token( + credentials=self.safe_get_vertex_ai_credentials(litellm_params), + project_id=self.safe_get_vertex_ai_project(litellm_params), + custom_llm_provider="vertex_ai", + ) + return { + **headers, + "Authorization": f"Bearer {access_token}", + "x-goog-user-project": project_id, + "Content-Type": "application/json", + } + + def get_complete_url( + self, + api_base: str | None, + api_key: str | None, + model: str, + optional_params: dict, + litellm_params: dict, + stream: bool | None = None, + ) -> str: + location = self._validate_location(self.safe_get_vertex_ai_location(litellm_params)) + project_id = self._validate_project_id( + self.safe_get_vertex_ai_project(litellm_params) or self._resolve_project_id_from_credentials(litellm_params) + ) + host = "speech.googleapis.com" if location == "global" else f"{location}-speech.googleapis.com" + base_url = (api_base or f"https://{host}").rstrip("/") + return f"{base_url}/v2/projects/{project_id}/locations/{location}/recognizers/_:recognize" + + @staticmethod + def _validate_location(location: str | None) -> str: + try: + return validate_vertex_location(location or DEFAULT_SPEECH_TO_TEXT_LOCATION) + except ValueError as e: + raise VertexAIError(status_code=400, message=str(e)) from e + + @staticmethod + def _validate_project_id(project_id: str) -> str: + if not project_id or ".." in project_id or any(c in project_id for c in _URL_UNSAFE_PROJECT_CHARS): + raise VertexAIError(status_code=400, message=f"Invalid vertex_project format: {project_id!r}") + return project_id + + def _resolve_project_id_from_credentials(self, litellm_params: dict) -> str: + _, project_id = self._ensure_access_token( + credentials=self.safe_get_vertex_ai_credentials(litellm_params), + project_id=None, + custom_llm_provider="vertex_ai", + ) + return project_id + + def transform_audio_transcription_request( + self, + model: str, + audio_file: FileTypes, + optional_params: dict, + litellm_params: dict, + ) -> AudioTranscriptionRequestData: + processed_audio = process_audio_file(audio_file) + language = optional_params.get("language") + language_codes = ( + [normalize_transcription_language_to_bcp47(language)] + if isinstance(language, str) and language + else [AUTO_LANGUAGE_CODE] + ) + request_body = VertexSpeechToTextRecognizeRequest( + config=VertexSpeechToTextRecognitionConfig( + model=model.removeprefix("vertex_ai/"), + languageCodes=language_codes, + features=VertexSpeechToTextRecognitionFeatures(enableAutomaticPunctuation=True), + autoDecodingConfig=VertexSpeechToTextAutoDecodingConfig(), + ), + content=base64.b64encode(processed_audio.file_content).decode("utf-8"), + ) + return AudioTranscriptionRequestData(data=dict(request_body)) + + def transform_audio_transcription_response( + self, + raw_response: Response, + ) -> TranscriptionResponse: + try: + response_json = raw_response.json() + except ValueError: + raise VertexAIError( + status_code=raw_response.status_code, + message=f"Received non-JSON response from Google Speech-to-Text: {raw_response.text}", + ) + parsed = VertexSpeechToTextRecognizeResponse.model_validate(response_json) + transcripts = tuple( + result.alternatives[0].transcript + for result in parsed.results + if result.alternatives and result.alternatives[0].transcript + ) + response = TranscriptionResponse(text=" ".join(transcripts)) + response["task"] = "transcribe" + detected_language = next((result.languageCode for result in parsed.results if result.languageCode), None) + if detected_language is not None: + response["language"] = detected_language + billed_duration = _parse_duration_seconds(parsed.metadata.totalBilledDuration if parsed.metadata else None) + if billed_duration is not None: + response["duration"] = billed_duration + response._hidden_params = response_json + return response + + +def _parse_duration_seconds(duration: str | None) -> float | None: + if duration is None or not duration.endswith("s"): + return None + try: + return float(duration[:-1]) + except ValueError: + return None diff --git a/litellm/llms/vertex_ai/batches/transformation.py b/litellm/llms/vertex_ai/batches/transformation.py index c75efdb43e8..6bbe8f75701 100644 --- a/litellm/llms/vertex_ai/batches/transformation.py +++ b/litellm/llms/vertex_ai/batches/transformation.py @@ -1,4 +1,4 @@ -from typing import Any, Dict +from typing import Any, Dict, Optional from litellm._uuid import uuid from litellm.llms.vertex_ai.common_utils import ( @@ -47,7 +47,7 @@ class VertexAIBatchTransformation: ) -> LiteLLMBatch: return LiteLLMBatch( id=cls._get_batch_id_from_vertex_ai_batch_response(response), - completion_window="24hrs", + completion_window="24h", created_at=_convert_vertex_datetime_to_openai_datetime(vertex_datetime=response.get("createTime", "")), endpoint="", input_file_id=cls._get_input_file_id_from_vertex_ai_batch_response(response), @@ -207,3 +207,19 @@ class VertexAIBatchTransformation: parts = model_path.split("/") model = f"publishers/{'/'.join(parts[:3])}" return model + + @classmethod + def is_unmanaged_gcs_batch_input_file_id(cls, input_file_id: Optional[str]) -> bool: + """ + Returns True if `input_file_id` is a raw gs:// Vertex batch input file (i.e. not a + LiteLLM-managed unified file id) with a `publishers/` model path that + `_get_model_from_gcs_file` can parse. + """ + return input_file_id is not None and input_file_id.startswith("gs://") and "publishers/" in input_file_id + + @classmethod + def get_bare_model_name_from_gcs_file(cls, gcs_file_uri: str) -> str: + """ + Extracts the bare model name (e.g. "gemini-1.5-flash-001") from a gcs file uri. + """ + return cls._get_model_from_gcs_file(gcs_file_uri).rsplit("/", 1)[-1] diff --git a/litellm/llms/vertex_ai/common_utils.py b/litellm/llms/vertex_ai/common_utils.py index 36522dfe396..7dcb4dcf2e8 100644 --- a/litellm/llms/vertex_ai/common_utils.py +++ b/litellm/llms/vertex_ai/common_utils.py @@ -311,6 +311,28 @@ def get_vertex_base_model_name(model: str) -> str: return model +def validate_vertex_location(vertex_location: Optional[str]) -> str: + """ + Validate a Vertex AI location before interpolating it into a request host or + URL path. + + ``vertex_location`` is client-controllable on the proxy (it flows in from the + request body), so it must never be trusted verbatim in a URL or an attacker + could point the host at their own server and exfiltrate the admin's Google + access token. Allow the special ``global`` control plane and otherwise require + a lowercase alphanumeric-plus-hyphen token (e.g. ``us``, ``us-central1``, + ``eu``), which rejects host injection like ``attacker.example/`` or + ``evil.com#``. + """ + if vertex_location == "global": + return vertex_location + if vertex_location is None: + raise ValueError("vertex_location is required") + if not re.match(r"^[a-z][a-z0-9-]*$", vertex_location): + raise ValueError("Invalid vertex_location format") + return vertex_location + + def get_vertex_base_url( vertex_location: Optional[str], ) -> str: @@ -321,15 +343,12 @@ def get_vertex_base_url( - Multi-region geographies (e.g. ``us``, ``eu``) use ``aiplatform.{geo}.rep.googleapis.com``. - Regional locations (e.g. ``us-central1``) use ``{region}-aiplatform.googleapis.com``. """ - if vertex_location == "global": + validated_location = validate_vertex_location(vertex_location) + if validated_location == "global": return "https://aiplatform.googleapis.com" - if vertex_location is None: - raise ValueError("vertex_location is required") - if not re.match(r"^[a-z][a-z0-9-]*$", vertex_location): - raise ValueError("Invalid vertex_location format") - if "-" not in vertex_location: - return f"https://aiplatform.{vertex_location}.rep.googleapis.com" - return f"https://{vertex_location}-aiplatform.googleapis.com" + if "-" not in validated_location: + return f"https://aiplatform.{validated_location}.rep.googleapis.com" + return f"https://{validated_location}-aiplatform.googleapis.com" def _get_embedding_url( diff --git a/litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py b/litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py index 678877c0721..f9ed8cea9b5 100644 --- a/litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py +++ b/litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py @@ -2315,17 +2315,15 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig): # Store thoughtSignatures in provider_specific_fields if thought_signatures is not None: - if "provider_specific_fields" not in chat_completion_message: - chat_completion_message["provider_specific_fields"] = {} - chat_completion_message["provider_specific_fields"]["thought_signatures"] = thought_signatures # type: ignore + thought_signature_fields = chat_completion_message.get("provider_specific_fields") or {} + thought_signature_fields["thought_signatures"] = thought_signatures + chat_completion_message["provider_specific_fields"] = thought_signature_fields # Store server-side tool invocations in provider_specific_fields if server_side_tool_invocations is not None: - if "provider_specific_fields" not in chat_completion_message: - chat_completion_message["provider_specific_fields"] = {} - chat_completion_message["provider_specific_fields"]["server_side_tool_invocations"] = ( - server_side_tool_invocations # type: ignore - ) + tool_invocation_fields = chat_completion_message.get("provider_specific_fields") or {} + tool_invocation_fields["server_side_tool_invocations"] = server_side_tool_invocations + chat_completion_message["provider_specific_fields"] = tool_invocation_fields if isinstance(model_response, ModelResponseStream): choice = VertexGeminiConfig._create_streaming_choice( diff --git a/litellm/llms/vertex_ai/image_generation/vertex_gemini_transformation.py b/litellm/llms/vertex_ai/image_generation/vertex_gemini_transformation.py index 39503bd78dd..572725ac789 100644 --- a/litellm/llms/vertex_ai/image_generation/vertex_gemini_transformation.py +++ b/litellm/llms/vertex_ai/image_generation/vertex_gemini_transformation.py @@ -1,5 +1,7 @@ import os -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import TYPE_CHECKING, Any, Optional + +from litellm._logging import verbose_logger import httpx @@ -52,6 +54,7 @@ class VertexAIGeminiImageGenerationConfig(BaseImageGenerationConfig, VertexLLM): return [ "n", "size", + "imageConfig", "aspectRatio", "aspect_ratio", "imageSize", @@ -83,7 +86,12 @@ class VertexAIGeminiImageGenerationConfig(BaseImageGenerationConfig, VertexLLM): mapped_params["aspectRatio"] = v elif k in ("imageSize", "image_size"): mapped_params["imageSize"] = v - elif k not in ("tools", "web_search_options"): + elif k == "imageConfig": + if isinstance(v, dict): + mapped_params["imageConfig"] = v + else: + verbose_logger.warning("imageConfig must be a dict, got %s — ignoring.", type(v).__name__) + elif k not in ("tools", "web_search_options", "imageConfig"): mapped_params[k] = v mapped_params = map_gemini_image_tools_params(non_default_params, mapped_params) @@ -167,7 +175,7 @@ class VertexAIGeminiImageGenerationConfig(BaseImageGenerationConfig, VertexLLM): self, headers: dict, model: str, - messages: List[AllMessageValues], + messages: list[AllMessageValues], optional_params: dict, litellm_params: dict, api_key: Optional[str] = None, @@ -209,18 +217,16 @@ class VertexAIGeminiImageGenerationConfig(BaseImageGenerationConfig, VertexLLM): contents = [{"role": "user", "parts": [{"text": prompt}]}] # Prepare generation config - generation_config: Dict[str, Any] = {"responseModalities": ["IMAGE"]} + generation_config: dict[str, Any] = {"responseModalities": ["IMAGE"]} - # Handle image-specific config parameters - image_config: Dict[str, Any] = {} + # Seed from user-supplied imageConfig dict; flat params are overlaid for backward compat. + image_config: dict[str, Any] = dict(optional_params.get("imageConfig") or {}) - # Map aspectRatio if "aspectRatio" in optional_params: image_config["aspectRatio"] = optional_params["aspectRatio"] elif "aspect_ratio" in optional_params: image_config["aspectRatio"] = optional_params["aspect_ratio"] - # Map imageSize (for Gemini 3 Pro) if "imageSize" in optional_params: image_config["imageSize"] = optional_params["imageSize"] elif "image_size" in optional_params: @@ -235,7 +241,7 @@ class VertexAIGeminiImageGenerationConfig(BaseImageGenerationConfig, VertexLLM): elif "n" in optional_params: generation_config["candidateCount"] = optional_params["n"] - request_body: Dict[str, Any] = { + request_body: dict[str, Any] = { "contents": contents, "generationConfig": generation_config, } diff --git a/litellm/llms/vertex_ai/vertex_llm_base.py b/litellm/llms/vertex_ai/vertex_llm_base.py index d57d7bf17df..788261ac1fe 100644 --- a/litellm/llms/vertex_ai/vertex_llm_base.py +++ b/litellm/llms/vertex_ai/vertex_llm_base.py @@ -9,6 +9,7 @@ import json import os import threading from typing import TYPE_CHECKING, Any, Dict, Literal, Optional, Tuple +from urllib.parse import urlparse import litellm from litellm._logging import verbose_logger @@ -315,6 +316,9 @@ class VertexBase: api_base=api_base, ) + if partner == VertexPartnerProvider.llama: + return default_api_base + if len(default_api_base.split(":")) > 1: endpoint = default_api_base.split(":")[-1] else: @@ -615,7 +619,8 @@ class VertexBase: Handles custom api_base for: 1. Gemini (Google AI Studio) - constructs /models/{model}:{endpoint} - 2. Vertex AI with standard proxies - constructs {api_base}:{endpoint} + 2. Vertex AI with standard proxies - constructs {api_base}:{endpoint}; + if api_base has no path (bare host), grafts the default vertex URL path onto it 3. Vertex AI with PSC endpoints - constructs full path structure {api_base}/v1/projects/{project}/locations/{location}/endpoints/{model}:{endpoint} (only when use_psc_endpoint_format=True) @@ -660,8 +665,9 @@ class VertexBase: model_for_url, endpoint, ) + elif urlparse(api_base).path in ("", "/"): + url = api_base.rstrip("/") + urlparse(url).path else: - # Fallback to simple format if we don't have all parameters url = "{}:{}".format(api_base, endpoint) if stream is True: url = url + "?alt=sse" diff --git a/litellm/main.py b/litellm/main.py index 18d2c367f8d..7d457d9cdd1 100644 --- a/litellm/main.py +++ b/litellm/main.py @@ -210,6 +210,7 @@ from .llms.bedrock.embed.embedding import BedrockEmbedding from .llms.bedrock.image_edit.handler import BedrockImageEdit from .llms.bedrock.image_generation.image_handler import BedrockImageGeneration from .llms.bytez.chat.transformation import BytezChatConfig +from .llms.gdc.chat.transformation import GDCGeminiConfig from .llms.clarifai.chat.transformation import ClarifaiConfig from .llms.codestral.completion.handler import CodestralTextCompletion from .llms.cohere.embed import handler as cohere_embed @@ -318,6 +319,7 @@ google_batch_embeddings = GoogleBatchEmbeddings() vertex_partner_models_chat_completion = VertexAIPartnerModels() vertex_gemma_chat_completion = VertexAIGemmaModels() vertex_model_garden_chat_completion = VertexAIModelGardenModels() +gdc_transformation = GDCGeminiConfig() # vertex_text_to_speech is now replaced by VertexAITextToSpeechConfig sagemaker_llm = SagemakerLLM() watsonx_chat_completion = WatsonXChatHandler() @@ -580,6 +582,7 @@ async def acompletion( "api_key": api_key, "model_list": model_list, "reasoning_effort": reasoning_effort, + "verbosity": verbosity, "safety_identifier": safety_identifier, "service_tier": service_tier, "extra_headers": extra_headers, @@ -1079,6 +1082,54 @@ def _build_custom_pricing_entry( return entry +def _get_router_deployment_id(kwargs: dict) -> Optional[str]: + for metadata_key in ("litellm_metadata", "metadata"): + metadata = kwargs.get(metadata_key) or {} + if not isinstance(metadata, dict): + continue + deployment_model_info = metadata.get("model_info") or {} + if not isinstance(deployment_model_info, dict): + continue + deployment_id = deployment_model_info.get("id") + if deployment_id is not None: + return str(deployment_id) + return None + + +def _register_custom_pricing_for_request( + model: str, + custom_llm_provider: str, + kwargs: dict, + model_info: Optional[dict], +) -> None: + """Register per-request custom pricing in litellm.model_cost. + + Router-originated requests (identified by the deployment id the router puts + in metadata) get their full pricing registered under that unique id only; + the shared ``{provider}/{model}`` key receives the entry with pricing fields + stripped, mirroring Router._create_deployment. This keeps one deployment's + pricing overrides (e.g. a zero-cost wildcard) from clobbering built-in + pricing used by sibling deployments of the same backend model. Direct SDK + calls keep the legacy behavior of registering the shared key with pricing. + """ + entry = _build_custom_pricing_entry( + custom_llm_provider=custom_llm_provider, + kwargs=kwargs, + model_info=model_info, + ) + shared_key = f"{custom_llm_provider}/{model}" + deployment_id = _get_router_deployment_id(kwargs) + if deployment_id is None: + litellm.register_model({shared_key: entry}) + return + litellm.register_model( + { + deployment_id: entry, + shared_key: CustomPricingLiteLLMParams.strip_custom_pricing_fields(entry), + } + ) + + def _complete_azure(ctx: _CompletionDispatchContext) -> _CompletionDispatchResult: _azure_detection_model = ctx._azure_detection_model acompletion = ctx.acompletion @@ -4336,6 +4387,45 @@ def _complete_gradient_ai(ctx: _CompletionDispatchContext) -> _CompletionDispatc ) +def _complete_gdc(ctx: _CompletionDispatchContext) -> _CompletionDispatchResult: + acompletion = ctx.acompletion + api_base = ctx.api_base + api_key = ctx.api_key + client = ctx.client + custom_llm_provider = ctx.custom_llm_provider + headers = ctx.headers + litellm_params = ctx.litellm_params + logging = ctx.logging + messages = ctx.messages + model = ctx.model + model_response = ctx.model_response + optional_params = ctx.optional_params + stream = ctx.stream + timeout = ctx.timeout + + api_key = api_key or litellm.gdc_key or get_secret_str("GDC_API_KEY") or litellm.api_key + api_base = api_base or litellm.gdc_api_base or get_secret_str("GDC_API_BASE") or litellm.api_base + + return base_llm_http_handler.completion( + model=model, + messages=messages, + headers=headers, + model_response=model_response, + api_key=api_key, + api_base=api_base, + acompletion=acompletion, + logging_obj=logging, + optional_params=optional_params, + litellm_params=litellm_params, + timeout=timeout, # type: ignore + client=client, + custom_llm_provider=custom_llm_provider, + encoding=_get_encoding(), + stream=stream, + provider_config=gdc_transformation, + ) + + def _complete_bytez(ctx: _CompletionDispatchContext) -> _CompletionDispatchResult: acompletion = ctx.acompletion api_base = ctx.api_base @@ -5066,14 +5156,11 @@ def completion( # type: ignore if ( input_cost_per_token is not None and output_cost_per_token is not None ) or input_cost_per_second is not None: - litellm.register_model( - { - f"{custom_llm_provider}/{model}": _build_custom_pricing_entry( - custom_llm_provider=custom_llm_provider, - kwargs=kwargs, - model_info=model_info, - ) - } + _register_custom_pricing_for_request( + model=model, + custom_llm_provider=custom_llm_provider, + kwargs=kwargs, + model_info=model_info, ) ### BUILD CUSTOM PROMPT TEMPLATE -- IF GIVEN ### custom_prompt_dict = {} # type: ignore @@ -5152,6 +5239,7 @@ def completion( # type: ignore "parallel_tool_calls": parallel_tool_calls, "messages": messages, "reasoning_effort": reasoning_effort, + "verbosity": verbosity, "thinking": thinking, "web_search_options": web_search_options, "include_server_side_tool_invocations": ( @@ -5533,6 +5621,8 @@ def completion( # type: ignore elif custom_llm_provider == "gradient_ai": response = _complete_gradient_ai(_dispatch_ctx) + elif custom_llm_provider == "gdc": + response = _complete_gdc(_dispatch_ctx) elif custom_llm_provider == "bytez": response = _complete_bytez(_dispatch_ctx) elif custom_llm_provider == "lemonade": @@ -5914,14 +6004,11 @@ def embedding( ### REGISTER CUSTOM MODEL PRICING -- IF GIVEN ### if (input_cost_per_token is not None and output_cost_per_token is not None) or input_cost_per_second is not None: - litellm.register_model( - { - f"{custom_llm_provider}/{model}": _build_custom_pricing_entry( - custom_llm_provider=custom_llm_provider, - kwargs=kwargs, - model_info=kwargs.get("model_info"), - ) - } + _register_custom_pricing_for_request( + model=model, + custom_llm_provider=custom_llm_provider, + kwargs=kwargs, + model_info=kwargs.get("model_info"), ) litellm_params_dict = get_litellm_params(**kwargs) @@ -8261,26 +8348,6 @@ def stream_chunk_builder_text_completion(chunks: list, messages: Optional[List] finish_reason = chunks[-1]["choices"][0]["finish_reason"] logprobs = chunks[-1]["choices"][0]["logprobs"] - response = { - "id": id, - "object": object, - "created": created, - "model": model, - "system_fingerprint": system_fingerprint, - "choices": [ - { - "text": None, - "index": 0, - "logprobs": logprobs, - "finish_reason": finish_reason, - } - ], - "usage": { - "prompt_tokens": None, - "completion_tokens": None, - "total_tokens": None, - }, - } content_list = [] for chunk in chunks: choices = chunk["choices"] @@ -8292,25 +8359,37 @@ def stream_chunk_builder_text_completion(chunks: list, messages: Optional[List] # Combine the "content" strings into a single string || combine the 'function' strings into a single string combined_content = "".join(content_list) - # Update the "content" field within the response dictionary - response["choices"][0]["text"] = combined_content - - if len(combined_content) > 0: - pass - else: - pass - # # Update usage information if needed try: - response["usage"]["prompt_tokens"] = token_counter(model=model, messages=messages) + prompt_tokens = token_counter(model=model, messages=messages) except Exception: # don't allow this failing to block a complete streaming response from being returned print_verbose("token_counter failed, assuming prompt tokens is 0") - response["usage"]["prompt_tokens"] = 0 - response["usage"]["completion_tokens"] = token_counter( + prompt_tokens = 0 + completion_tokens = token_counter( model=model, text=combined_content, count_response_tokens=True, # count_response_tokens is a Flag to tell token counter this is a response, No need to add extra tokens we do for input messages ) - response["usage"]["total_tokens"] = response["usage"]["prompt_tokens"] + response["usage"]["completion_tokens"] + + response = { + "id": id, + "object": object, + "created": created, + "model": model, + "system_fingerprint": system_fingerprint, + "choices": [ + { + "text": combined_content, + "index": 0, + "logprobs": logprobs, + "finish_reason": finish_reason, + } + ], + "usage": { + "prompt_tokens": prompt_tokens, + "completion_tokens": completion_tokens, + "total_tokens": prompt_tokens + completion_tokens, + }, + } return TextCompletionResponse(**response) diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 21132db93cb..2a269d693ec 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -744,7 +744,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "anthropic.claude-haiku-4-5@20251001": { "cache_creation_input_token_cost": 1.25e-06, @@ -768,7 +769,8 @@ "supports_tool_choice": true, "supports_vision": true, "supports_native_streaming": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "anthropic.claude-3-5-sonnet-20240620-v1:0": { "input_cost_per_token": 3e-06, @@ -787,8 +789,6 @@ "output_cost_per_token_above_200k_tokens": 3e-05, "cache_creation_input_token_cost_above_200k_tokens": 7.5e-06, "cache_read_input_token_cost_above_200k_tokens": 6e-07, - "cache_creation_input_token_cost_above_1hr": 7.5e-06, - "cache_creation_input_token_cost_above_1hr_above_200k_tokens": 1.5e-05, "cache_creation_input_token_cost": 3.75e-06, "cache_read_input_token_cost": 3e-07 }, @@ -813,9 +813,7 @@ "input_cost_per_token_above_200k_tokens": 6e-06, "output_cost_per_token_above_200k_tokens": 3e-05, "cache_creation_input_token_cost_above_200k_tokens": 7.5e-06, - "cache_read_input_token_cost_above_200k_tokens": 6e-07, - "cache_creation_input_token_cost_above_1hr": 7.5e-06, - "cache_creation_input_token_cost_above_1hr_above_200k_tokens": 1.5e-05 + "cache_read_input_token_cost_above_200k_tokens": 6e-07 }, "anthropic.claude-3-7-sonnet-20240620-v1:0": { "cache_creation_input_token_cost": 4.5e-06, @@ -991,7 +989,8 @@ "supports_vision": true, "supports_native_structured_output": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "high" + "bedrock_output_config_effort_ceiling": "high", + "supports_parallel_tool_use_config": true }, "anthropic.claude-opus-4-6-v1": { "supports_adaptive_thinking": true, @@ -1010,7 +1009,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -1023,7 +1021,8 @@ "supports_native_structured_output": true, "supports_output_config": true, "supports_max_reasoning_effort": true, - "bedrock_output_config_effort_ceiling": "max" + "bedrock_output_config_effort_ceiling": "max", + "supports_parallel_tool_use_config": true }, "global.anthropic.claude-opus-4-6-v1": { "supports_adaptive_thinking": true, @@ -1042,7 +1041,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -1055,7 +1053,8 @@ "supports_native_structured_output": true, "supports_output_config": true, "supports_max_reasoning_effort": true, - "bedrock_output_config_effort_ceiling": "max" + "bedrock_output_config_effort_ceiling": "max", + "supports_parallel_tool_use_config": true }, "us.anthropic.claude-opus-4-6-v1": { "supports_adaptive_thinking": true, @@ -1074,7 +1073,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -1087,7 +1085,8 @@ "supports_native_structured_output": true, "supports_output_config": true, "supports_max_reasoning_effort": true, - "bedrock_output_config_effort_ceiling": "max" + "bedrock_output_config_effort_ceiling": "max", + "supports_parallel_tool_use_config": true }, "eu.anthropic.claude-opus-4-6-v1": { "supports_adaptive_thinking": true, @@ -1106,7 +1105,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -1119,7 +1117,8 @@ "supports_native_structured_output": true, "supports_output_config": true, "supports_max_reasoning_effort": true, - "bedrock_output_config_effort_ceiling": "max" + "bedrock_output_config_effort_ceiling": "max", + "supports_parallel_tool_use_config": true }, "au.anthropic.claude-opus-4-6-v1": { "supports_adaptive_thinking": true, @@ -1138,7 +1137,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -1151,9 +1149,11 @@ "supports_native_structured_output": true, "supports_output_config": true, "supports_max_reasoning_effort": true, - "bedrock_output_config_effort_ceiling": "max" + "bedrock_output_config_effort_ceiling": "max", + "supports_parallel_tool_use_config": true }, "anthropic.claude-opus-4-7": { + "bedrock_converse_supports_strict_tools": false, "supports_adaptive_thinking": true, "cache_creation_input_token_cost": 6.25e-06, "cache_creation_input_token_cost_above_1hr": 1e-05, @@ -1170,7 +1170,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -1185,7 +1184,8 @@ "supports_native_structured_output": true, "supports_max_reasoning_effort": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "xhigh" + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true }, "anthropic.claude-mythos-preview": { "input_cost_per_token": 0, @@ -1203,6 +1203,7 @@ "supports_output_config": true }, "global.anthropic.claude-opus-4-7": { + "bedrock_converse_supports_strict_tools": false, "supports_adaptive_thinking": true, "cache_creation_input_token_cost": 6.25e-06, "cache_creation_input_token_cost_above_1hr": 1e-05, @@ -1219,7 +1220,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -1234,9 +1234,11 @@ "supports_native_structured_output": true, "supports_max_reasoning_effort": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "xhigh" + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true }, "us.anthropic.claude-opus-4-7": { + "bedrock_converse_supports_strict_tools": false, "supports_adaptive_thinking": true, "cache_creation_input_token_cost": 6.875e-06, "cache_creation_input_token_cost_above_1hr": 1.1e-05, @@ -1253,7 +1255,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -1268,9 +1269,11 @@ "supports_native_structured_output": true, "supports_max_reasoning_effort": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "xhigh" + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true }, "eu.anthropic.claude-opus-4-7": { + "bedrock_converse_supports_strict_tools": false, "supports_adaptive_thinking": true, "cache_creation_input_token_cost": 6.875e-06, "cache_creation_input_token_cost_above_1hr": 1.1e-05, @@ -1287,7 +1290,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -1302,9 +1304,11 @@ "supports_native_structured_output": true, "supports_max_reasoning_effort": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "xhigh" + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true }, "au.anthropic.claude-opus-4-7": { + "bedrock_converse_supports_strict_tools": false, "supports_adaptive_thinking": true, "cache_creation_input_token_cost": 6.875e-06, "cache_creation_input_token_cost_above_1hr": 1.1e-05, @@ -1321,7 +1325,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -1336,7 +1339,8 @@ "supports_native_structured_output": true, "supports_max_reasoning_effort": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "xhigh" + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true }, "anthropic.claude-fable-5": { "cache_creation_input_token_cost": 1.25e-05, @@ -1369,7 +1373,8 @@ "supports_native_structured_output": true, "supports_max_reasoning_effort": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "xhigh" + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true }, "global.anthropic.claude-fable-5": { "cache_creation_input_token_cost": 1.25e-05, @@ -1402,7 +1407,8 @@ "supports_native_structured_output": true, "supports_max_reasoning_effort": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "xhigh" + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true }, "us.anthropic.claude-fable-5": { "cache_creation_input_token_cost": 1.375e-05, @@ -1435,7 +1441,8 @@ "supports_native_structured_output": true, "supports_max_reasoning_effort": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "xhigh" + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true }, "eu.anthropic.claude-fable-5": { "cache_creation_input_token_cost": 1.375e-05, @@ -1468,9 +1475,11 @@ "supports_native_structured_output": true, "supports_max_reasoning_effort": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "xhigh" + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true }, "anthropic.claude-opus-4-8": { + "bedrock_converse_supports_strict_tools": false, "supports_adaptive_thinking": true, "cache_creation_input_token_cost": 6.25e-06, "cache_creation_input_token_cost_above_1hr": 1e-05, @@ -1487,7 +1496,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -1502,9 +1510,11 @@ "supports_native_structured_output": true, "supports_max_reasoning_effort": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "xhigh" + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true }, "global.anthropic.claude-opus-4-8": { + "bedrock_converse_supports_strict_tools": false, "supports_adaptive_thinking": true, "cache_creation_input_token_cost": 6.25e-06, "cache_creation_input_token_cost_above_1hr": 1e-05, @@ -1521,7 +1531,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -1536,9 +1545,11 @@ "supports_native_structured_output": true, "supports_max_reasoning_effort": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "xhigh" + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true }, "us.anthropic.claude-opus-4-8": { + "bedrock_converse_supports_strict_tools": false, "supports_adaptive_thinking": true, "cache_creation_input_token_cost": 6.875e-06, "cache_creation_input_token_cost_above_1hr": 1.1e-05, @@ -1555,7 +1566,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -1570,9 +1580,11 @@ "supports_native_structured_output": true, "supports_max_reasoning_effort": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "xhigh" + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true }, "eu.anthropic.claude-opus-4-8": { + "bedrock_converse_supports_strict_tools": false, "supports_adaptive_thinking": true, "cache_creation_input_token_cost": 6.875e-06, "cache_creation_input_token_cost_above_1hr": 1.1e-05, @@ -1589,7 +1601,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -1604,9 +1615,11 @@ "supports_native_structured_output": true, "supports_max_reasoning_effort": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "xhigh" + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true }, "au.anthropic.claude-opus-4-8": { + "bedrock_converse_supports_strict_tools": false, "supports_adaptive_thinking": true, "cache_creation_input_token_cost": 6.875e-06, "cache_creation_input_token_cost_above_1hr": 1.1e-05, @@ -1623,6 +1636,72 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, + "supports_assistant_prefill": false, + "supports_computer_use": true, + "supports_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_sampling_params": false, + "supports_tool_choice": true, + "supports_vision": true, + "supports_xhigh_reasoning_effort": true, + "supports_native_structured_output": true, + "supports_max_reasoning_effort": true, + "supports_output_config": true, + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true + }, + "jp.anthropic.claude-opus-4-7": { + "bedrock_converse_supports_strict_tools": false, + "cache_creation_input_token_cost": 6.875e-06, + "cache_read_input_token_cost": 5.5e-07, + "input_cost_per_token": 5.5e-06, + "litellm_provider": "bedrock_converse", + "max_input_tokens": 1000000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 2.75e-05, + "search_context_cost_per_query": { + "search_context_size_high": 0.01, + "search_context_size_low": 0.01, + "search_context_size_medium": 0.01 + }, + "supports_adaptive_thinking": true, + "supports_assistant_prefill": false, + "supports_computer_use": true, + "supports_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_sampling_params": false, + "supports_tool_choice": true, + "supports_vision": true, + "supports_xhigh_reasoning_effort": true, + "supports_native_structured_output": true, + "supports_max_reasoning_effort": true, + "supports_minimal_reasoning_effort": true, + "supports_parallel_tool_use_config": true + }, + "anthropic.claude-sonnet-5": { + "cache_creation_input_token_cost": 2.5e-06, + "cache_creation_input_token_cost_above_1hr": 4e-06, + "cache_read_input_token_cost": 2e-07, + "input_cost_per_token": 2e-06, + "litellm_provider": "bedrock_converse", + "max_input_tokens": 1000000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 1e-05, + "search_context_cost_per_query": { + "search_context_size_high": 0.01, + "search_context_size_low": 0.01, + "search_context_size_medium": 0.01 + }, "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, @@ -1638,18 +1717,20 @@ "supports_native_structured_output": true, "supports_max_reasoning_effort": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "xhigh" + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true }, - "jp.anthropic.claude-opus-4-7": { - "cache_creation_input_token_cost": 6.875e-06, - "cache_read_input_token_cost": 5.5e-07, - "input_cost_per_token": 5.5e-06, + "global.anthropic.claude-sonnet-5": { + "cache_creation_input_token_cost": 2.5e-06, + "cache_creation_input_token_cost_above_1hr": 4e-06, + "cache_read_input_token_cost": 2e-07, + "input_cost_per_token": 2e-06, "litellm_provider": "bedrock_converse", "max_input_tokens": 1000000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", - "output_cost_per_token": 2.75e-05, + "output_cost_per_token": 1e-05, "search_context_cost_per_query": { "search_context_size_high": 0.01, "search_context_size_low": 0.01, @@ -1669,7 +1750,145 @@ "supports_xhigh_reasoning_effort": true, "supports_native_structured_output": true, "supports_max_reasoning_effort": true, - "supports_minimal_reasoning_effort": true + "supports_output_config": true, + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true + }, + "us.anthropic.claude-sonnet-5": { + "cache_creation_input_token_cost": 2.75e-06, + "cache_creation_input_token_cost_above_1hr": 4.4e-06, + "cache_read_input_token_cost": 2.2e-07, + "input_cost_per_token": 2.2e-06, + "litellm_provider": "bedrock_converse", + "max_input_tokens": 1000000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 1.1e-05, + "search_context_cost_per_query": { + "search_context_size_high": 0.01, + "search_context_size_low": 0.01, + "search_context_size_medium": 0.01 + }, + "supports_adaptive_thinking": true, + "supports_assistant_prefill": false, + "supports_computer_use": true, + "supports_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_sampling_params": false, + "supports_tool_choice": true, + "supports_vision": true, + "supports_xhigh_reasoning_effort": true, + "supports_native_structured_output": true, + "supports_max_reasoning_effort": true, + "supports_output_config": true, + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true + }, + "eu.anthropic.claude-sonnet-5": { + "cache_creation_input_token_cost": 2.75e-06, + "cache_creation_input_token_cost_above_1hr": 4.4e-06, + "cache_read_input_token_cost": 2.2e-07, + "input_cost_per_token": 2.2e-06, + "litellm_provider": "bedrock_converse", + "max_input_tokens": 1000000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 1.1e-05, + "search_context_cost_per_query": { + "search_context_size_high": 0.01, + "search_context_size_low": 0.01, + "search_context_size_medium": 0.01 + }, + "supports_adaptive_thinking": true, + "supports_assistant_prefill": false, + "supports_computer_use": true, + "supports_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_sampling_params": false, + "supports_tool_choice": true, + "supports_vision": true, + "supports_xhigh_reasoning_effort": true, + "supports_native_structured_output": true, + "supports_max_reasoning_effort": true, + "supports_output_config": true, + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true + }, + "au.anthropic.claude-sonnet-5": { + "cache_creation_input_token_cost": 2.75e-06, + "cache_creation_input_token_cost_above_1hr": 4.4e-06, + "cache_read_input_token_cost": 2.2e-07, + "input_cost_per_token": 2.2e-06, + "litellm_provider": "bedrock_converse", + "max_input_tokens": 1000000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 1.1e-05, + "search_context_cost_per_query": { + "search_context_size_high": 0.01, + "search_context_size_low": 0.01, + "search_context_size_medium": 0.01 + }, + "supports_adaptive_thinking": true, + "supports_assistant_prefill": false, + "supports_computer_use": true, + "supports_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_sampling_params": false, + "supports_tool_choice": true, + "supports_vision": true, + "supports_xhigh_reasoning_effort": true, + "supports_native_structured_output": true, + "supports_max_reasoning_effort": true, + "supports_output_config": true, + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true + }, + "jp.anthropic.claude-sonnet-5": { + "cache_creation_input_token_cost": 2.75e-06, + "cache_creation_input_token_cost_above_1hr": 4.4e-06, + "cache_read_input_token_cost": 2.2e-07, + "input_cost_per_token": 2.2e-06, + "litellm_provider": "bedrock_converse", + "max_input_tokens": 1000000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 1.1e-05, + "search_context_cost_per_query": { + "search_context_size_high": 0.01, + "search_context_size_low": 0.01, + "search_context_size_medium": 0.01 + }, + "supports_adaptive_thinking": true, + "supports_assistant_prefill": false, + "supports_computer_use": true, + "supports_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_sampling_params": false, + "supports_tool_choice": true, + "supports_vision": true, + "supports_xhigh_reasoning_effort": true, + "supports_native_structured_output": true, + "supports_max_reasoning_effort": true, + "supports_output_config": true, + "bedrock_output_config_effort_ceiling": "xhigh", + "supports_parallel_tool_use_config": true }, "anthropic.claude-sonnet-4-6": { "supports_adaptive_thinking": true, @@ -1688,7 +1907,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": true, "supports_computer_use": true, "supports_function_calling": true, @@ -1700,7 +1918,8 @@ "supports_tool_choice": true, "supports_vision": true, "supports_native_structured_output": true, - "supports_output_config": true + "supports_output_config": true, + "supports_parallel_tool_use_config": true }, "global.anthropic.claude-sonnet-4-6": { "supports_adaptive_thinking": true, @@ -1719,7 +1938,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": true, "supports_computer_use": true, "supports_function_calling": true, @@ -1731,7 +1949,8 @@ "supports_tool_choice": true, "supports_vision": true, "supports_native_structured_output": true, - "supports_output_config": true + "supports_output_config": true, + "supports_parallel_tool_use_config": true }, "us.anthropic.claude-sonnet-4-6": { "supports_adaptive_thinking": true, @@ -1750,7 +1969,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": true, "supports_computer_use": true, "supports_function_calling": true, @@ -1762,7 +1980,8 @@ "supports_tool_choice": true, "supports_vision": true, "supports_native_structured_output": true, - "supports_output_config": true + "supports_output_config": true, + "supports_parallel_tool_use_config": true }, "eu.anthropic.claude-sonnet-4-6": { "supports_adaptive_thinking": true, @@ -1781,7 +2000,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": true, "supports_computer_use": true, "supports_function_calling": true, @@ -1793,7 +2011,8 @@ "supports_tool_choice": true, "supports_vision": true, "supports_native_structured_output": true, - "supports_output_config": true + "supports_output_config": true, + "supports_parallel_tool_use_config": true }, "au.anthropic.claude-sonnet-4-6": { "supports_adaptive_thinking": true, @@ -1812,7 +2031,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": true, "supports_computer_use": true, "supports_function_calling": true, @@ -1824,7 +2042,8 @@ "supports_tool_choice": true, "supports_vision": true, "supports_native_structured_output": true, - "supports_output_config": true + "supports_output_config": true, + "supports_parallel_tool_use_config": true }, "jp.anthropic.claude-sonnet-4-6": { "supports_adaptive_thinking": true, @@ -1843,7 +2062,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": true, "supports_computer_use": true, "supports_function_calling": true, @@ -1855,7 +2073,8 @@ "supports_tool_choice": true, "supports_vision": true, "supports_native_structured_output": true, - "supports_output_config": true + "supports_output_config": true, + "supports_parallel_tool_use_config": true }, "anthropic.claude-sonnet-4-20250514-v1:0": { "cache_creation_input_token_cost": 3.75e-06, @@ -1884,7 +2103,8 @@ "supports_reasoning": true, "supports_response_schema": true, "supports_tool_choice": true, - "supports_vision": true + "supports_vision": true, + "bedrock_converse_supports_strict_tools": false }, "anthropic.claude-sonnet-4-5-20250929-v1:0": { "cache_creation_input_token_cost": 3.75e-06, @@ -1916,7 +2136,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "anthropic.claude-v1": { "input_cost_per_token": 8e-06, @@ -2166,7 +2387,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "apac.anthropic.claude-3-sonnet-20240229-v1:0": { "input_cost_per_token": 3e-06, @@ -2211,7 +2433,8 @@ "supports_reasoning": true, "supports_response_schema": true, "supports_tool_choice": true, - "supports_vision": true + "supports_vision": true, + "bedrock_converse_supports_strict_tools": false }, "assemblyai/best": { "input_cost_per_second": 3.333e-05, @@ -2255,7 +2478,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "azure/ada": { "input_cost_per_token": 1e-07, @@ -2364,7 +2588,6 @@ "cache_creation_input_token_cost": 6.25e-06, "cache_creation_input_token_cost_above_1hr": 1e-05, "cache_read_input_token_cost": 5e-07, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -2394,7 +2617,6 @@ "cache_creation_input_token_cost": 6.25e-06, "cache_creation_input_token_cost_above_1hr": 1e-05, "cache_read_input_token_cost": 5e-07, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -2455,7 +2677,6 @@ "cache_creation_input_token_cost": 6.25e-06, "cache_creation_input_token_cost_above_1hr": 1e-05, "cache_read_input_token_cost": 5e-07, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -2511,6 +2732,36 @@ "supports_tool_choice": true, "supports_vision": true }, + "azure_ai/claude-sonnet-5": { + "cache_creation_input_token_cost": 2.5e-06, + "cache_creation_input_token_cost_above_1hr": 4e-06, + "cache_read_input_token_cost": 2e-07, + "input_cost_per_token": 2e-06, + "litellm_provider": "azure_ai", + "max_input_tokens": 1000000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 1e-05, + "search_context_cost_per_query": { + "search_context_size_high": 0.01, + "search_context_size_low": 0.01, + "search_context_size_medium": 0.01 + }, + "supports_adaptive_thinking": true, + "supports_assistant_prefill": false, + "supports_computer_use": true, + "supports_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_sampling_params": false, + "supports_tool_choice": true, + "supports_vision": true, + "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true + }, "azure_ai/claude-sonnet-4-6": { "supports_adaptive_thinking": true, "cache_creation_input_token_cost": 3.75e-06, @@ -2523,7 +2774,6 @@ "max_tokens": 64000, "mode": "chat", "output_cost_per_token": 1.5e-05, - "supports_adaptive_thinking": true, "supports_assistant_prefill": true, "supports_computer_use": true, "supports_function_calling": true, @@ -5511,6 +5761,76 @@ "supports_tool_choice": true, "supports_vision": true }, + "azure/us/gpt-5.4": { + "cache_read_input_token_cost": 2.8e-07, + "cache_read_input_token_cost_priority": 5.5e-07, + "input_cost_per_token": 2.75e-06, + "input_cost_per_token_priority": 5.5e-06, + "output_cost_per_token": 1.65e-05, + "output_cost_per_token_priority": 3.3e-05, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "azure/eu/gpt-5.4": { + "cache_read_input_token_cost": 2.8e-07, + "cache_read_input_token_cost_priority": 5.5e-07, + "input_cost_per_token": 2.75e-06, + "input_cost_per_token_priority": 5.5e-06, + "output_cost_per_token": 1.65e-05, + "output_cost_per_token_priority": 3.3e-05, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true + }, "azure/gpt-5.4-2026-03-05": { "cache_read_input_token_cost": 2.5e-07, "cache_read_input_token_cost_above_272k_tokens": 5e-07, @@ -5552,6 +5872,76 @@ "supports_tool_choice": true, "supports_vision": true }, + "azure/us/gpt-5.4-2026-03-05": { + "cache_read_input_token_cost": 2.8e-07, + "cache_read_input_token_cost_priority": 5.5e-07, + "input_cost_per_token": 2.75e-06, + "input_cost_per_token_priority": 5.5e-06, + "output_cost_per_token": 1.65e-05, + "output_cost_per_token_priority": 3.3e-05, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "azure/eu/gpt-5.4-2026-03-05": { + "cache_read_input_token_cost": 2.8e-07, + "cache_read_input_token_cost_priority": 5.5e-07, + "input_cost_per_token": 2.75e-06, + "input_cost_per_token_priority": 5.5e-06, + "output_cost_per_token": 1.65e-05, + "output_cost_per_token_priority": 3.3e-05, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true + }, "azure/gpt-5.4-pro": { "cache_read_input_token_cost": 3e-06, "cache_read_input_token_cost_above_272k_tokens": 6e-06, @@ -5622,6 +6012,522 @@ "supports_vision": true, "supports_web_search": true }, + "azure/gpt-5.6": { + "cache_read_input_token_cost": 5e-07, + "cache_read_input_token_cost_above_272k_tokens": 1e-06, + "cache_read_input_token_cost_priority": 1e-06, + "cache_read_input_token_cost_above_272k_tokens_priority": 2e-06, + "input_cost_per_token": 5e-06, + "input_cost_per_token_above_272k_tokens": 1e-05, + "input_cost_per_token_priority": 1e-05, + "input_cost_per_token_above_272k_tokens_priority": 2e-05, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 3e-05, + "output_cost_per_token_above_272k_tokens": 4.5e-05, + "output_cost_per_token_priority": 6e-05, + "output_cost_per_token_above_272k_tokens_priority": 9e-05, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_none_reasoning_effort": true, + "supports_xhigh_reasoning_effort": true, + "supports_minimal_reasoning_effort": false + }, + "azure/gpt-5.6-sol": { + "cache_read_input_token_cost": 5e-07, + "cache_read_input_token_cost_above_272k_tokens": 1e-06, + "cache_read_input_token_cost_priority": 1e-06, + "cache_read_input_token_cost_above_272k_tokens_priority": 2e-06, + "input_cost_per_token": 5e-06, + "input_cost_per_token_above_272k_tokens": 1e-05, + "input_cost_per_token_priority": 1e-05, + "input_cost_per_token_above_272k_tokens_priority": 2e-05, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 3e-05, + "output_cost_per_token_above_272k_tokens": 4.5e-05, + "output_cost_per_token_priority": 6e-05, + "output_cost_per_token_above_272k_tokens_priority": 9e-05, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_none_reasoning_effort": true, + "supports_xhigh_reasoning_effort": true, + "supports_minimal_reasoning_effort": false + }, + "azure/gpt-5.6-terra": { + "cache_read_input_token_cost": 2.5e-07, + "cache_read_input_token_cost_above_272k_tokens": 5e-07, + "cache_read_input_token_cost_priority": 5e-07, + "cache_read_input_token_cost_above_272k_tokens_priority": 1e-06, + "input_cost_per_token": 2.5e-06, + "input_cost_per_token_above_272k_tokens": 5e-06, + "input_cost_per_token_priority": 5e-06, + "input_cost_per_token_above_272k_tokens_priority": 1e-05, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 1.5e-05, + "output_cost_per_token_above_272k_tokens": 2.25e-05, + "output_cost_per_token_priority": 3e-05, + "output_cost_per_token_above_272k_tokens_priority": 4.5e-05, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_none_reasoning_effort": true, + "supports_xhigh_reasoning_effort": true, + "supports_minimal_reasoning_effort": false + }, + "azure/gpt-5.6-luna": { + "cache_read_input_token_cost": 1e-07, + "cache_read_input_token_cost_above_272k_tokens": 2e-07, + "cache_read_input_token_cost_priority": 2e-07, + "cache_read_input_token_cost_above_272k_tokens_priority": 4e-07, + "input_cost_per_token": 1e-06, + "input_cost_per_token_above_272k_tokens": 2e-06, + "input_cost_per_token_priority": 2e-06, + "input_cost_per_token_above_272k_tokens_priority": 4e-06, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 6e-06, + "output_cost_per_token_above_272k_tokens": 9e-06, + "output_cost_per_token_priority": 1.2e-05, + "output_cost_per_token_above_272k_tokens_priority": 1.8e-05, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_none_reasoning_effort": true, + "supports_xhigh_reasoning_effort": true, + "supports_minimal_reasoning_effort": false + }, + "azure/us/gpt-5.6": { + "cache_read_input_token_cost": 5.5e-07, + "cache_read_input_token_cost_above_272k_tokens": 1.1e-06, + "cache_read_input_token_cost_priority": 1.375e-06, + "input_cost_per_token": 5.5e-06, + "input_cost_per_token_above_272k_tokens": 1.1e-05, + "input_cost_per_token_priority": 1.375e-05, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 3.3e-05, + "output_cost_per_token_above_272k_tokens": 4.95e-05, + "output_cost_per_token_priority": 8.25e-05, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_none_reasoning_effort": true, + "supports_xhigh_reasoning_effort": true, + "supports_minimal_reasoning_effort": false + }, + "azure/us/gpt-5.6-sol": { + "cache_read_input_token_cost": 5.5e-07, + "cache_read_input_token_cost_above_272k_tokens": 1.1e-06, + "cache_read_input_token_cost_priority": 1.375e-06, + "input_cost_per_token": 5.5e-06, + "input_cost_per_token_above_272k_tokens": 1.1e-05, + "input_cost_per_token_priority": 1.375e-05, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 3.3e-05, + "output_cost_per_token_above_272k_tokens": 4.95e-05, + "output_cost_per_token_priority": 8.25e-05, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_none_reasoning_effort": true, + "supports_xhigh_reasoning_effort": true, + "supports_minimal_reasoning_effort": false + }, + "azure/us/gpt-5.6-terra": { + "cache_read_input_token_cost": 2.75e-07, + "cache_read_input_token_cost_above_272k_tokens": 5.5e-07, + "cache_read_input_token_cost_priority": 6.875e-07, + "input_cost_per_token": 2.75e-06, + "input_cost_per_token_above_272k_tokens": 5.5e-06, + "input_cost_per_token_priority": 6.875e-06, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 1.65e-05, + "output_cost_per_token_above_272k_tokens": 2.475e-05, + "output_cost_per_token_priority": 4.125e-05, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_none_reasoning_effort": true, + "supports_xhigh_reasoning_effort": true, + "supports_minimal_reasoning_effort": false + }, + "azure/us/gpt-5.6-luna": { + "cache_read_input_token_cost": 1.1e-07, + "cache_read_input_token_cost_above_272k_tokens": 2.2e-07, + "cache_read_input_token_cost_priority": 2.75e-07, + "input_cost_per_token": 1.1e-06, + "input_cost_per_token_above_272k_tokens": 2.2e-06, + "input_cost_per_token_priority": 2.75e-06, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 6.6e-06, + "output_cost_per_token_above_272k_tokens": 9.9e-06, + "output_cost_per_token_priority": 1.65e-05, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_none_reasoning_effort": true, + "supports_xhigh_reasoning_effort": true, + "supports_minimal_reasoning_effort": false + }, + "azure/eu/gpt-5.6": { + "cache_read_input_token_cost": 5.5e-07, + "cache_read_input_token_cost_above_272k_tokens": 1.1e-06, + "cache_read_input_token_cost_priority": 1.375e-06, + "input_cost_per_token": 5.5e-06, + "input_cost_per_token_above_272k_tokens": 1.1e-05, + "input_cost_per_token_priority": 1.375e-05, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 3.3e-05, + "output_cost_per_token_above_272k_tokens": 4.95e-05, + "output_cost_per_token_priority": 8.25e-05, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_none_reasoning_effort": true, + "supports_xhigh_reasoning_effort": true, + "supports_minimal_reasoning_effort": false + }, + "azure/eu/gpt-5.6-sol": { + "cache_read_input_token_cost": 5.5e-07, + "cache_read_input_token_cost_above_272k_tokens": 1.1e-06, + "cache_read_input_token_cost_priority": 1.375e-06, + "input_cost_per_token": 5.5e-06, + "input_cost_per_token_above_272k_tokens": 1.1e-05, + "input_cost_per_token_priority": 1.375e-05, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 3.3e-05, + "output_cost_per_token_above_272k_tokens": 4.95e-05, + "output_cost_per_token_priority": 8.25e-05, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_none_reasoning_effort": true, + "supports_xhigh_reasoning_effort": true, + "supports_minimal_reasoning_effort": false + }, + "azure/eu/gpt-5.6-terra": { + "cache_read_input_token_cost": 2.75e-07, + "cache_read_input_token_cost_above_272k_tokens": 5.5e-07, + "cache_read_input_token_cost_priority": 6.875e-07, + "input_cost_per_token": 2.75e-06, + "input_cost_per_token_above_272k_tokens": 5.5e-06, + "input_cost_per_token_priority": 6.875e-06, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 1.65e-05, + "output_cost_per_token_above_272k_tokens": 2.475e-05, + "output_cost_per_token_priority": 4.125e-05, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_none_reasoning_effort": true, + "supports_xhigh_reasoning_effort": true, + "supports_minimal_reasoning_effort": false + }, + "azure/eu/gpt-5.6-luna": { + "cache_read_input_token_cost": 1.1e-07, + "cache_read_input_token_cost_above_272k_tokens": 2.2e-07, + "cache_read_input_token_cost_priority": 2.75e-07, + "input_cost_per_token": 1.1e-06, + "input_cost_per_token_above_272k_tokens": 2.2e-06, + "input_cost_per_token_priority": 2.75e-06, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 6.6e-06, + "output_cost_per_token_above_272k_tokens": 9.9e-06, + "output_cost_per_token_priority": 1.65e-05, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_none_reasoning_effort": true, + "supports_xhigh_reasoning_effort": true, + "supports_minimal_reasoning_effort": false + }, "azure/gpt-5.5": { "cache_read_input_token_cost": 5e-07, "cache_read_input_token_cost_above_272k_tokens": 1e-06, @@ -5667,6 +6573,90 @@ "supports_xhigh_reasoning_effort": true, "supports_minimal_reasoning_effort": false }, + "azure/us/gpt-5.5": { + "cache_read_input_token_cost": 5.5e-07, + "cache_read_input_token_cost_above_272k_tokens": 1.1e-06, + "cache_read_input_token_cost_priority": 1.38e-06, + "input_cost_per_token": 5.5e-06, + "input_cost_per_token_above_272k_tokens": 1.1e-05, + "input_cost_per_token_priority": 1.375e-05, + "output_cost_per_token": 3.3e-05, + "output_cost_per_token_above_272k_tokens": 4.95e-05, + "output_cost_per_token_priority": 8.25e-05, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_none_reasoning_effort": true, + "supports_xhigh_reasoning_effort": true, + "supports_minimal_reasoning_effort": false + }, + "azure/eu/gpt-5.5": { + "cache_read_input_token_cost": 5.5e-07, + "cache_read_input_token_cost_above_272k_tokens": 1.1e-06, + "cache_read_input_token_cost_priority": 1.38e-06, + "input_cost_per_token": 5.5e-06, + "input_cost_per_token_above_272k_tokens": 1.1e-05, + "input_cost_per_token_priority": 1.375e-05, + "output_cost_per_token": 3.3e-05, + "output_cost_per_token_above_272k_tokens": 4.95e-05, + "output_cost_per_token_priority": 8.25e-05, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_none_reasoning_effort": true, + "supports_xhigh_reasoning_effort": true, + "supports_minimal_reasoning_effort": false + }, "azure/gpt-5.5-2026-04-23": { "cache_read_input_token_cost": 5e-07, "cache_read_input_token_cost_above_272k_tokens": 1e-06, @@ -5709,6 +6699,84 @@ "supports_vision": true, "supports_web_search": true }, + "azure/us/gpt-5.5-2026-04-23": { + "cache_read_input_token_cost": 5.5e-07, + "cache_read_input_token_cost_above_272k_tokens": 1.1e-06, + "cache_read_input_token_cost_priority": 1.38e-06, + "input_cost_per_token": 5.5e-06, + "input_cost_per_token_above_272k_tokens": 1.1e-05, + "input_cost_per_token_priority": 1.375e-05, + "output_cost_per_token": 3.3e-05, + "output_cost_per_token_above_272k_tokens": 4.95e-05, + "output_cost_per_token_priority": 8.25e-05, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true + }, + "azure/eu/gpt-5.5-2026-04-23": { + "cache_read_input_token_cost": 5.5e-07, + "cache_read_input_token_cost_above_272k_tokens": 1.1e-06, + "cache_read_input_token_cost_priority": 1.38e-06, + "input_cost_per_token": 5.5e-06, + "input_cost_per_token_above_272k_tokens": 1.1e-05, + "input_cost_per_token_priority": 1.375e-05, + "output_cost_per_token": 3.3e-05, + "output_cost_per_token_above_272k_tokens": 4.95e-05, + "output_cost_per_token_priority": 8.25e-05, + "litellm_provider": "azure", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true + }, "azure/gpt-5.5-pro": { "cache_read_input_token_cost": 3e-06, "cache_read_input_token_cost_above_272k_tokens": 6e-06, @@ -9132,17 +10200,16 @@ }, "bedrock/us-east-1/minimax.minimax-m2.5": { "input_cost_per_token": 3e-07, + "output_cost_per_token": 1.2e-06, "litellm_provider": "bedrock", "max_input_tokens": 1000000, "max_output_tokens": 8192, "max_tokens": 8192, "mode": "chat", - "source": "https://aws.amazon.com/bedrock/pricing/", "supports_function_calling": true, - "supports_reasoning": true, "supports_system_messages": true, "supports_tool_choice": true, - "output_cost_per_token": 1.2e-06 + "source": "https://aws.amazon.com/bedrock/pricing/" }, "bedrock/us-east-1/moonshotai.kimi-k2-thinking": { "input_cost_per_token": 6e-07, @@ -9371,7 +10438,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "bedrock/us-gov-east-1/claude-sonnet-4-5-20250929-v1:0": { "cache_creation_input_token_cost": 4.5e-06, @@ -9393,7 +10461,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "bedrock/us-gov-east-1/meta.llama3-70b-instruct-v1:0": { "input_cost_per_token": 2.65e-06, @@ -9546,7 +10615,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "bedrock/us-gov-west-1/claude-sonnet-4-5-20250929-v1:0": { "cache_creation_input_token_cost": 4.5e-06, @@ -9568,7 +10638,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "bedrock/us-gov-west-1/meta.llama3-70b-instruct-v1:0": { "input_cost_per_token": 2.65e-06, @@ -9754,17 +10825,16 @@ }, "bedrock/us-west-2/minimax.minimax-m2.5": { "input_cost_per_token": 3e-07, + "output_cost_per_token": 1.2e-06, "litellm_provider": "bedrock", "max_input_tokens": 1000000, "max_output_tokens": 8192, "max_tokens": 8192, "mode": "chat", - "source": "https://aws.amazon.com/bedrock/pricing/", "supports_function_calling": true, - "supports_reasoning": true, "supports_system_messages": true, "supports_tool_choice": true, - "output_cost_per_token": 1.2e-06 + "source": "https://aws.amazon.com/bedrock/pricing/" }, "bedrock/us-west-2/moonshotai.kimi-k2-thinking": { "input_cost_per_token": 6e-07, @@ -10245,6 +11315,40 @@ "supports_vision": true, "supports_web_search": true }, + "claude-sonnet-5": { + "cache_creation_input_token_cost": 2.5e-06, + "cache_creation_input_token_cost_above_1hr": 4e-06, + "cache_read_input_token_cost": 2e-07, + "input_cost_per_token": 2e-06, + "litellm_provider": "anthropic", + "max_input_tokens": 1000000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 1e-05, + "search_context_cost_per_query": { + "search_context_size_high": 0.01, + "search_context_size_low": 0.01, + "search_context_size_medium": 0.01 + }, + "supports_adaptive_thinking": true, + "supports_assistant_prefill": false, + "supports_computer_use": true, + "supports_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_sampling_params": false, + "supports_tool_choice": true, + "supports_vision": true, + "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true, + "provider_specific_entry": { + "us": 1.1 + }, + "supports_output_config": true + }, "claude-sonnet-4-6": { "cache_creation_input_token_cost": 3.75e-06, "cache_creation_input_token_cost_above_1hr": 6e-06, @@ -10298,7 +11402,8 @@ "supports_reasoning": true, "supports_response_schema": true, "supports_tool_choice": true, - "supports_vision": true + "supports_vision": true, + "supports_parallel_tool_use_config": true }, "claude-opus-4-1": { "cache_creation_input_token_cost": 1.875e-05, @@ -14370,7 +15475,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "eu.anthropic.claude-3-5-sonnet-20240620-v1:0": { "input_cost_per_token": 3e-06, @@ -14551,7 +15657,8 @@ "supports_reasoning": true, "supports_response_schema": true, "supports_tool_choice": true, - "supports_vision": true + "supports_vision": true, + "bedrock_converse_supports_strict_tools": false }, "eu.anthropic.claude-sonnet-4-5-20250929-v1:0": { "cache_creation_input_token_cost": 4.125e-06, @@ -14583,7 +15690,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "eu.meta.llama3-2-1b-instruct-v1:0": { "input_cost_per_token": 1.3e-07, @@ -18914,7 +20022,8 @@ "max_tokens": 16000, "mode": "chat", "supported_endpoints": [ - "/v1/chat/completions" + "/v1/chat/completions", + "/v1/messages" ], "supports_function_calling": true, "supports_parallel_function_calling": true, @@ -18927,7 +20036,8 @@ "max_tokens": 16000, "mode": "chat", "supported_endpoints": [ - "/v1/chat/completions" + "/v1/chat/completions", + "/v1/messages" ], "supports_function_calling": true, "supports_parallel_function_calling": true, @@ -18944,7 +20054,6 @@ "supported_endpoints": [ "/v1/chat/completions" ], - "supports_adaptive_thinking": true, "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_vision": true @@ -18980,7 +20089,8 @@ "max_tokens": 16000, "mode": "chat", "supported_endpoints": [ - "/v1/chat/completions" + "/v1/chat/completions", + "/v1/messages" ], "supports_function_calling": true, "supports_parallel_function_calling": true, @@ -19780,7 +20890,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "global.anthropic.claude-sonnet-4-20250514-v1:0": { "cache_creation_input_token_cost": 3.75e-06, @@ -19809,7 +20920,8 @@ "supports_reasoning": true, "supports_response_schema": true, "supports_tool_choice": true, - "supports_vision": true + "supports_vision": true, + "bedrock_converse_supports_strict_tools": false }, "global.anthropic.claude-haiku-4-5-20251001-v1:0": { "cache_creation_input_token_cost": 1.25e-06, @@ -19832,7 +20944,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "global.amazon.nova-2-lite-v1:0": { "cache_read_input_token_cost": 7.5e-08, @@ -21676,6 +22789,218 @@ "supports_xhigh_reasoning_effort": true, "supports_minimal_reasoning_effort": true }, + "gpt-5.6": { + "cache_creation_input_token_cost": 6.25e-06, + "cache_creation_input_token_cost_above_272k_tokens": 1.25e-05, + "cache_creation_input_token_cost_flex": 3.125e-06, + "cache_creation_input_token_cost_priority": 1.25e-05, + "cache_read_input_token_cost": 5e-07, + "cache_read_input_token_cost_above_272k_tokens": 1e-06, + "cache_read_input_token_cost_flex": 2.5e-07, + "cache_read_input_token_cost_priority": 1e-06, + "input_cost_per_token": 5e-06, + "input_cost_per_token_above_272k_tokens": 1e-05, + "input_cost_per_token_batches": 2.5e-06, + "input_cost_per_token_flex": 2.5e-06, + "input_cost_per_token_priority": 1e-05, + "litellm_provider": "openai", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 3e-05, + "output_cost_per_token_above_272k_tokens": 4.5e-05, + "output_cost_per_token_batches": 1.5e-05, + "output_cost_per_token_flex": 1.5e-05, + "output_cost_per_token_priority": 6e-05, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_minimal_reasoning_effort": false, + "supports_native_streaming": true, + "supports_none_reasoning_effort": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_xhigh_reasoning_effort": true + }, + "gpt-5.6-sol": { + "cache_creation_input_token_cost": 6.25e-06, + "cache_creation_input_token_cost_above_272k_tokens": 1.25e-05, + "cache_creation_input_token_cost_flex": 3.125e-06, + "cache_creation_input_token_cost_priority": 1.25e-05, + "cache_read_input_token_cost": 5e-07, + "cache_read_input_token_cost_above_272k_tokens": 1e-06, + "cache_read_input_token_cost_flex": 2.5e-07, + "cache_read_input_token_cost_priority": 1e-06, + "input_cost_per_token": 5e-06, + "input_cost_per_token_above_272k_tokens": 1e-05, + "input_cost_per_token_batches": 2.5e-06, + "input_cost_per_token_flex": 2.5e-06, + "input_cost_per_token_priority": 1e-05, + "litellm_provider": "openai", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 3e-05, + "output_cost_per_token_above_272k_tokens": 4.5e-05, + "output_cost_per_token_batches": 1.5e-05, + "output_cost_per_token_flex": 1.5e-05, + "output_cost_per_token_priority": 6e-05, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_minimal_reasoning_effort": false, + "supports_native_streaming": true, + "supports_none_reasoning_effort": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_xhigh_reasoning_effort": true + }, + "gpt-5.6-terra": { + "cache_creation_input_token_cost": 3.125e-06, + "cache_creation_input_token_cost_above_272k_tokens": 6.25e-06, + "cache_creation_input_token_cost_flex": 1.5625e-06, + "cache_creation_input_token_cost_priority": 6.25e-06, + "cache_read_input_token_cost": 2.5e-07, + "cache_read_input_token_cost_above_272k_tokens": 5e-07, + "cache_read_input_token_cost_flex": 1.25e-07, + "cache_read_input_token_cost_priority": 5e-07, + "input_cost_per_token": 2.5e-06, + "input_cost_per_token_above_272k_tokens": 5e-06, + "input_cost_per_token_batches": 1.25e-06, + "input_cost_per_token_flex": 1.25e-06, + "input_cost_per_token_priority": 5e-06, + "litellm_provider": "openai", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 1.5e-05, + "output_cost_per_token_above_272k_tokens": 2.25e-05, + "output_cost_per_token_batches": 7.5e-06, + "output_cost_per_token_flex": 7.5e-06, + "output_cost_per_token_priority": 3e-05, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_minimal_reasoning_effort": false, + "supports_native_streaming": true, + "supports_none_reasoning_effort": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_xhigh_reasoning_effort": true + }, + "gpt-5.6-luna": { + "cache_creation_input_token_cost": 1.25e-06, + "cache_creation_input_token_cost_above_272k_tokens": 2.5e-06, + "cache_creation_input_token_cost_flex": 6.25e-07, + "cache_creation_input_token_cost_priority": 2.5e-06, + "cache_read_input_token_cost": 1e-07, + "cache_read_input_token_cost_above_272k_tokens": 2e-07, + "cache_read_input_token_cost_flex": 5e-08, + "cache_read_input_token_cost_priority": 2e-07, + "input_cost_per_token": 1e-06, + "input_cost_per_token_above_272k_tokens": 2e-06, + "input_cost_per_token_batches": 5e-07, + "input_cost_per_token_flex": 5e-07, + "input_cost_per_token_priority": 2e-06, + "litellm_provider": "openai", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 6e-06, + "output_cost_per_token_above_272k_tokens": 9e-06, + "output_cost_per_token_batches": 3e-06, + "output_cost_per_token_flex": 3e-06, + "output_cost_per_token_priority": 1.2e-05, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/batch", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_minimal_reasoning_effort": false, + "supports_native_streaming": true, + "supports_none_reasoning_effort": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_xhigh_reasoning_effort": true + }, "gpt-5.5": { "cache_read_input_token_cost": 5e-07, "cache_read_input_token_cost_above_272k_tokens": 1e-06, @@ -21696,8 +23021,8 @@ "output_cost_per_token_flex": 1.5e-05, "output_cost_per_token_batches": 1.5e-05, "output_cost_per_token_priority": 6e-05, - "regional_processing_uplift_multiplier_eu": 1.10, - "regional_processing_uplift_multiplier_us": 1.10, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, "supported_endpoints": [ "/v1/chat/completions", "/v1/batch", @@ -21745,8 +23070,8 @@ "output_cost_per_token_flex": 1.5e-05, "output_cost_per_token_batches": 1.5e-05, "output_cost_per_token_priority": 6e-05, - "regional_processing_uplift_multiplier_eu": 1.10, - "regional_processing_uplift_multiplier_us": 1.10, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, "supported_endpoints": [ "/v1/chat/completions", "/v1/batch", @@ -21790,8 +23115,8 @@ "output_cost_per_token_above_272k_tokens": 0.00027, "output_cost_per_token_flex": 9e-05, "output_cost_per_token_batches": 9e-05, - "regional_processing_uplift_multiplier_eu": 1.10, - "regional_processing_uplift_multiplier_us": 1.10, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, "supported_endpoints": [ "/v1/responses", "/v1/batch" @@ -21835,8 +23160,8 @@ "output_cost_per_token_above_272k_tokens": 0.00027, "output_cost_per_token_flex": 9e-05, "output_cost_per_token_batches": 9e-05, - "regional_processing_uplift_multiplier_eu": 1.10, - "regional_processing_uplift_multiplier_us": 1.10, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, "supported_endpoints": [ "/v1/responses", "/v1/batch" @@ -21884,8 +23209,8 @@ "output_cost_per_token_flex": 7.5e-06, "output_cost_per_token_batches": 7.5e-06, "output_cost_per_token_priority": 3e-05, - "regional_processing_uplift_multiplier_eu": 1.10, - "regional_processing_uplift_multiplier_us": 1.10, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, "supported_endpoints": [ "/v1/chat/completions", "/v1/batch", @@ -21932,8 +23257,8 @@ "output_cost_per_token_flex": 7.5e-06, "output_cost_per_token_batches": 7.5e-06, "output_cost_per_token_priority": 3e-05, - "regional_processing_uplift_multiplier_eu": 1.10, - "regional_processing_uplift_multiplier_us": 1.10, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, "supported_endpoints": [ "/v1/chat/completions", "/v1/batch", @@ -21973,8 +23298,8 @@ "output_cost_per_token_above_272k_tokens": 0.00027, "output_cost_per_token_flex": 9e-05, "output_cost_per_token_batches": 9e-05, - "regional_processing_uplift_multiplier_eu": 1.10, - "regional_processing_uplift_multiplier_us": 1.10, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, "supported_endpoints": [ "/v1/responses", "/v1/batch" @@ -22017,8 +23342,8 @@ "output_cost_per_token_above_272k_tokens": 0.00027, "output_cost_per_token_flex": 9e-05, "output_cost_per_token_batches": 9e-05, - "regional_processing_uplift_multiplier_eu": 1.10, - "regional_processing_uplift_multiplier_us": 1.10, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, "supported_endpoints": [ "/v1/responses", "/v1/batch" @@ -22062,8 +23387,8 @@ "output_cost_per_token_flex": 2.25e-06, "output_cost_per_token_batches": 2.25e-06, "output_cost_per_token_priority": 9e-06, - "regional_processing_uplift_multiplier_eu": 1.10, - "regional_processing_uplift_multiplier_us": 1.10, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, "supported_endpoints": [ "/v1/chat/completions", "/v1/batch", @@ -22108,8 +23433,8 @@ "output_cost_per_token_flex": 2.25e-06, "output_cost_per_token_batches": 2.25e-06, "output_cost_per_token_priority": 9e-06, - "regional_processing_uplift_multiplier_eu": 1.10, - "regional_processing_uplift_multiplier_us": 1.10, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, "supported_endpoints": [ "/v1/chat/completions", "/v1/batch", @@ -22151,8 +23476,8 @@ "output_cost_per_token": 1.25e-06, "output_cost_per_token_flex": 6.25e-07, "output_cost_per_token_batches": 6.25e-07, - "regional_processing_uplift_multiplier_eu": 1.10, - "regional_processing_uplift_multiplier_us": 1.10, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, "supported_endpoints": [ "/v1/chat/completions", "/v1/batch", @@ -22194,8 +23519,8 @@ "output_cost_per_token": 1.25e-06, "output_cost_per_token_flex": 6.25e-07, "output_cost_per_token_batches": 6.25e-07, - "regional_processing_uplift_multiplier_eu": 1.10, - "regional_processing_uplift_multiplier_us": 1.10, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, "supported_endpoints": [ "/v1/chat/completions", "/v1/batch", @@ -22906,6 +24231,76 @@ "supports_system_messages": true, "supports_tool_choice": true }, + "gpt-realtime-2.1": { + "cache_creation_input_audio_token_cost": 4e-07, + "cache_read_input_audio_token_cost": 4e-07, + "cache_read_input_token_cost": 4e-07, + "input_cost_per_audio_token": 3.2e-05, + "input_cost_per_image": 5e-06, + "input_cost_per_token": 4e-06, + "litellm_provider": "openai", + "max_input_tokens": 128000, + "max_output_tokens": 32000, + "max_tokens": 32000, + "mode": "chat", + "output_cost_per_audio_token": 6.4e-05, + "output_cost_per_token": 2.4e-05, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, + "supported_endpoints": [ + "/v1/realtime" + ], + "supported_modalities": [ + "text", + "image", + "audio" + ], + "supported_output_modalities": [ + "text", + "audio" + ], + "supports_audio_input": true, + "supports_audio_output": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_system_messages": true, + "supports_tool_choice": true + }, + "gpt-realtime-2.1-mini": { + "cache_creation_input_audio_token_cost": 3e-07, + "cache_read_input_audio_token_cost": 3e-07, + "cache_read_input_token_cost": 6e-08, + "input_cost_per_audio_token": 1e-05, + "input_cost_per_image": 8e-07, + "input_cost_per_token": 6e-07, + "litellm_provider": "openai", + "max_input_tokens": 128000, + "max_output_tokens": 4096, + "max_tokens": 4096, + "mode": "chat", + "output_cost_per_audio_token": 2e-05, + "output_cost_per_token": 2.4e-06, + "regional_processing_uplift_multiplier_eu": 1.1, + "regional_processing_uplift_multiplier_us": 1.1, + "supported_endpoints": [ + "/v1/realtime" + ], + "supported_modalities": [ + "text", + "image", + "audio" + ], + "supported_output_modalities": [ + "text", + "audio" + ], + "supports_audio_input": true, + "supports_audio_output": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_system_messages": true, + "supports_tool_choice": true + }, "gpt-realtime-mini": { "cache_creation_input_audio_token_cost": 3e-07, "cache_read_input_audio_token_cost": 3e-07, @@ -23901,7 +25296,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "jp.anthropic.claude-haiku-4-5-20251001-v1:0": { "cache_creation_input_token_cost": 1.375e-06, @@ -23924,7 +25320,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "crusoe/deepseek-ai/DeepSeek-R1-0528": { "input_cost_per_token": 3e-06, @@ -24620,6 +26017,42 @@ "supports_function_calling": true, "supports_tool_choice": false }, + "meta/muse-spark-1.1": { + "cache_read_input_token_cost": 1.5e-07, + "input_cost_per_token": 1.25e-06, + "litellm_provider": "meta", + "max_input_tokens": 1048576, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 4.25e-06, + "source": "https://dev.meta.ai/docs/getting-started/pricing-rate-limits", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/responses", + "/v1/messages" + ], + "supported_modalities": [ + "text", + "image", + "video" + ], + "supported_output_modalities": [ + "text" + ], + "supports_function_calling": true, + "supports_minimal_reasoning_effort": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true, + "supports_xhigh_reasoning_effort": true + }, "meta_llama/Llama-3.3-70B-Instruct": { "litellm_provider": "meta_llama", "max_input_tokens": 128000, @@ -24712,14 +26145,13 @@ }, "minimax.minimax-m2.5": { "input_cost_per_token": 3e-07, + "output_cost_per_token": 1.2e-06, "litellm_provider": "bedrock_converse", "max_input_tokens": 1000000, "max_output_tokens": 8192, "max_tokens": 8192, "mode": "chat", - "output_cost_per_token": 1.2e-06, "supports_function_calling": true, - "supports_reasoning": true, "supports_system_messages": true, "supports_tool_choice": true, "source": "https://aws.amazon.com/bedrock/pricing/" @@ -28175,7 +29607,6 @@ "output_cost_per_token": 1.5e-05, "output_cost_per_token_above_200k_tokens": 2.25e-05, "source": "https://openrouter.ai/anthropic/claude-sonnet-4.6", - "supports_adaptive_thinking": true, "supports_assistant_prefill": true, "supports_computer_use": true, "supports_function_calling": true, @@ -28215,7 +29646,6 @@ "max_tokens": 128000, "mode": "chat", "output_cost_per_token": 2.5e-05, - "supports_adaptive_thinking": true, "supports_assistant_prefill": true, "supports_computer_use": true, "supports_function_calling": true, @@ -28277,7 +29707,6 @@ "max_tokens": 128000, "mode": "chat", "output_cost_per_token": 2.5e-05, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -30200,7 +31629,6 @@ "supports_adaptive_thinking": true, "litellm_provider": "perplexity", "mode": "responses", - "supports_adaptive_thinking": true, "supports_web_search": true, "supports_reasoning": false, "supports_function_calling": true, @@ -30210,7 +31638,6 @@ "supports_adaptive_thinking": true, "litellm_provider": "perplexity", "mode": "responses", - "supports_adaptive_thinking": true, "supports_web_search": true, "supports_reasoning": false, "supports_function_calling": true, @@ -31126,7 +32553,7 @@ "supports_tool_choice": true }, "sambanova/Meta-Llama-3.2-1B-Instruct": { - "deprecation_date": "2025-06-25", + "deprecation_date": "2025-06-25", "input_cost_per_token": 4e-08, "litellm_provider": "sambanova", "max_input_tokens": 16384, @@ -31257,15 +32684,15 @@ "supports_vision": true, "source": "https://cloud.sambanova.ai/plans/pricing" }, - "snowflake/claude-3-5-sonnet": { + "snowflake/claude-3-5-sonnet": { "litellm_provider": "snowflake", "max_input_tokens": 200000, "max_output_tokens": 16384, "max_tokens": 16384, "mode": "chat", - "input_cost_per_token": 0.000003, - "output_cost_per_token": 0.000015, - "cache_read_input_token_cost": 0.0000003, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "cache_read_input_token_cost": 3e-07, "supports_computer_use": true, "supports_function_calling": true, "supports_vision": true, @@ -31273,14 +32700,14 @@ "supports_system_messages": true, "supports_response_schema": true }, - "snowflake/deepseek-r1": { + "snowflake/deepseek-r1": { "litellm_provider": "snowflake", "max_input_tokens": 128000, "max_output_tokens": 16384, "max_tokens": 16384, "mode": "chat", - "input_cost_per_token": 0.00000135, - "output_cost_per_token": 0.0000054, + "input_cost_per_token": 1.35e-06, + "output_cost_per_token": 5.4e-06, "supports_reasoning": true, "supports_system_messages": true }, @@ -31339,8 +32766,8 @@ "max_output_tokens": 16384, "max_tokens": 16384, "mode": "chat", - "input_cost_per_token": 0.0000012, - "output_cost_per_token": 0.0000012, + "input_cost_per_token": 1.2e-06, + "output_cost_per_token": 1.2e-06, "supports_function_calling": true, "supports_system_messages": true }, @@ -31350,8 +32777,8 @@ "max_output_tokens": 16384, "max_tokens": 16384, "mode": "chat", - "input_cost_per_token": 0.00000072, - "output_cost_per_token": 0.00000072, + "input_cost_per_token": 7.2e-07, + "output_cost_per_token": 7.2e-07, "supports_function_calling": true, "supports_system_messages": true }, @@ -31361,8 +32788,8 @@ "max_output_tokens": 16384, "max_tokens": 16384, "mode": "chat", - "input_cost_per_token": 0.00000024, - "output_cost_per_token": 0.00000024, + "input_cost_per_token": 2.4e-07, + "output_cost_per_token": 2.4e-07, "supports_system_messages": true }, "snowflake/llama3.2-1b": { @@ -31379,17 +32806,17 @@ "max_tokens": 8192, "mode": "chat" }, - "snowflake/llama3.3-70b": { + "snowflake/llama3.3-70b": { "max_tokens": 16384, "max_input_tokens": 128000, "max_output_tokens": 16384, - "input_cost_per_token": 0.00000072, - "output_cost_per_token": 0.00000072, + "input_cost_per_token": 7.2e-07, + "output_cost_per_token": 7.2e-07, "litellm_provider": "snowflake", "mode": "chat", "supports_function_calling": true, "supports_system_messages": true - }, + }, "snowflake/mistral-7b": { "litellm_provider": "snowflake", "max_input_tokens": 32000, @@ -31404,14 +32831,14 @@ "max_tokens": 8192, "mode": "chat" }, - "snowflake/mistral-large2": { + "snowflake/mistral-large2": { "litellm_provider": "snowflake", "max_input_tokens": 128000, "max_output_tokens": 16384, "max_tokens": 16384, "mode": "chat", - "input_cost_per_token": 0.000002, - "output_cost_per_token": 0.000006, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 6e-06, "supports_function_calling": true, "supports_system_messages": true, "supports_response_schema": true @@ -31451,17 +32878,17 @@ "max_tokens": 8192, "mode": "chat" }, - "snowflake/snowflake-llama-3.3-70b": { + "snowflake/snowflake-llama-3.3-70b": { "max_tokens": 16384, "max_input_tokens": 128000, "max_output_tokens": 16384, - "input_cost_per_token": 0.00000072, - "output_cost_per_token": 0.00000072, + "input_cost_per_token": 7.2e-07, + "output_cost_per_token": 7.2e-07, "litellm_provider": "snowflake", "mode": "chat", "supports_function_calling": true, "supports_system_messages": true - }, + }, "stability/sd3": { "litellm_provider": "stability", "mode": "image_generation", @@ -32545,7 +33972,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "us.anthropic.claude-3-5-sonnet-20240620-v1:0": { "input_cost_per_token": 3e-06, @@ -32704,7 +34132,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "us-gov.anthropic.claude-sonnet-4-5-20250929-v1:0": { "cache_creation_input_token_cost": 4.5e-06, @@ -32713,7 +34142,7 @@ "input_cost_per_token": 3.6e-06, "input_cost_per_token_above_200k_tokens": 7.2e-06, "output_cost_per_token_above_200k_tokens": 2.7e-05, - "cache_creation_input_token_cost_above_200k_tokens": 9.0e-06, + "cache_creation_input_token_cost_above_200k_tokens": 9e-06, "cache_creation_input_token_cost_above_1hr_above_200k_tokens": 1.44e-05, "cache_read_input_token_cost_above_200k_tokens": 7.2e-07, "litellm_provider": "bedrock_converse", @@ -32731,7 +34160,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "au.anthropic.claude-haiku-4-5-20251001-v1:0": { "cache_creation_input_token_cost": 1.375e-06, @@ -32753,7 +34183,8 @@ "supports_response_schema": true, "supports_tool_choice": true, "supports_vision": true, - "supports_native_structured_output": true + "supports_native_structured_output": true, + "supports_parallel_tool_use_config": true }, "us.anthropic.claude-opus-4-20250514-v1:0": { "cache_creation_input_token_cost": 1.875e-05, @@ -32807,7 +34238,8 @@ "supports_vision": true, "supports_native_structured_output": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "high" + "bedrock_output_config_effort_ceiling": "high", + "supports_parallel_tool_use_config": true }, "global.anthropic.claude-opus-4-5-20251101-v1:0": { "cache_creation_input_token_cost": 6.25e-06, @@ -32836,7 +34268,8 @@ "supports_vision": true, "supports_native_structured_output": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "high" + "bedrock_output_config_effort_ceiling": "high", + "supports_parallel_tool_use_config": true }, "eu.anthropic.claude-opus-4-5-20251101-v1:0": { "cache_creation_input_token_cost": 6.25e-06, @@ -32864,7 +34297,8 @@ "supports_vision": true, "supports_native_structured_output": true, "supports_output_config": true, - "bedrock_output_config_effort_ceiling": "high" + "bedrock_output_config_effort_ceiling": "high", + "supports_parallel_tool_use_config": true }, "us.anthropic.claude-sonnet-4-20250514-v1:0": { "cache_creation_input_token_cost": 3.75e-06, @@ -32893,7 +34327,8 @@ "supports_reasoning": true, "supports_response_schema": true, "supports_tool_choice": true, - "supports_vision": true + "supports_vision": true, + "bedrock_converse_supports_strict_tools": false }, "us.deepseek.r1-v1:0": { "input_cost_per_token": 1.35e-06, @@ -33455,7 +34890,6 @@ "max_tokens": 64000, "mode": "chat", "output_cost_per_token": 2.5e-05, - "supports_adaptive_thinking": true, "supports_assistant_prefill": true, "supports_computer_use": true, "supports_function_calling": true, @@ -34357,6 +35791,19 @@ "/v1/audio/speech" ] }, + "vertex_ai/chirp_3": { + "input_cost_per_second": 0.00026667, + "litellm_provider": "vertex_ai", + "metadata": { + "calculation": "$0.016/60 seconds = $0.00026667 per second", + "original_pricing_per_minute": 0.016 + }, + "mode": "audio_transcription", + "source": "https://cloud.google.com/speech-to-text/pricing", + "supported_endpoints": [ + "/v1/audio/transcriptions" + ] + }, "vertex_ai/claude-3-5-haiku": { "input_cost_per_token": 1e-06, "litellm_provider": "vertex_ai-anthropic_models", @@ -34690,7 +36137,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -34720,7 +36166,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -34750,7 +36195,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -34781,7 +36225,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -34872,7 +36315,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -34903,7 +36345,6 @@ "search_context_size_low": 0.01, "search_context_size_medium": 0.01 }, - "supports_adaptive_thinking": true, "supports_assistant_prefill": false, "supports_computer_use": true, "supports_function_calling": true, @@ -34944,6 +36385,36 @@ "supports_tool_choice": true, "supports_vision": true }, + "vertex_ai/claude-sonnet-5": { + "cache_creation_input_token_cost": 2.5e-06, + "cache_creation_input_token_cost_above_1hr": 4e-06, + "cache_read_input_token_cost": 2e-07, + "input_cost_per_token": 2e-06, + "litellm_provider": "vertex_ai-anthropic_models", + "max_input_tokens": 1000000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 1e-05, + "search_context_cost_per_query": { + "search_context_size_high": 0.01, + "search_context_size_low": 0.01, + "search_context_size_medium": 0.01 + }, + "supports_adaptive_thinking": true, + "supports_assistant_prefill": false, + "supports_computer_use": true, + "supports_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_sampling_params": false, + "supports_tool_choice": true, + "supports_vision": true, + "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true + }, "vertex_ai/claude-sonnet-4-6": { "supports_adaptive_thinking": true, "cache_creation_input_token_cost": 3.75e-06, @@ -34956,7 +36427,6 @@ "max_tokens": 64000, "mode": "chat", "output_cost_per_token": 1.5e-05, - "supports_adaptive_thinking": true, "supports_assistant_prefill": true, "supports_computer_use": true, "supports_function_calling": true, @@ -37395,6 +38865,48 @@ "supports_vision": true, "supports_web_search": true }, + "xai/grok-4.5": { + "cache_read_input_token_cost": 5e-07, + "cache_read_input_token_cost_above_200k_tokens": 1e-06, + "input_cost_per_token": 2e-06, + "input_cost_per_token_above_200k_tokens": 4e-06, + "litellm_provider": "xai", + "max_input_tokens": 500000, + "max_output_tokens": 500000, + "max_tokens": 500000, + "mode": "chat", + "output_cost_per_token": 6e-06, + "output_cost_per_token_above_200k_tokens": 1.2e-05, + "source": "https://docs.x.ai/docs/models", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true + }, + "xai/grok-4.5-latest": { + "cache_read_input_token_cost": 5e-07, + "cache_read_input_token_cost_above_200k_tokens": 1e-06, + "input_cost_per_token": 2e-06, + "input_cost_per_token_above_200k_tokens": 4e-06, + "litellm_provider": "xai", + "max_input_tokens": 500000, + "max_output_tokens": 500000, + "max_tokens": 500000, + "mode": "chat", + "output_cost_per_token": 6e-06, + "output_cost_per_token_above_200k_tokens": 1.2e-05, + "source": "https://docs.x.ai/docs/models", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_web_search": true + }, "xai/grok-beta": { "input_cost_per_token": 5e-06, "litellm_provider": "xai", @@ -37485,12 +38997,12 @@ }, "zai.glm-5": { "input_cost_per_token": 1e-06, + "output_cost_per_token": 3.2e-06, "litellm_provider": "bedrock_converse", "max_input_tokens": 200000, "max_output_tokens": 128000, "max_tokens": 128000, "mode": "chat", - "output_cost_per_token": 3.2e-06, "supports_function_calling": true, "supports_reasoning": true, "supports_system_messages": true, @@ -37511,20 +39023,6 @@ "supports_tool_choice": true, "source": "https://aws.amazon.com/bedrock/pricing/" }, - "zai.glm-5": { - "input_cost_per_token": 1e-06, - "litellm_provider": "bedrock_converse", - "max_input_tokens": 200000, - "max_output_tokens": 128000, - "max_tokens": 128000, - "mode": "chat", - "output_cost_per_token": 3.2e-06, - "source": "https://aws.amazon.com/bedrock/pricing/", - "supports_function_calling": true, - "supports_reasoning": true, - "supports_system_messages": true, - "supports_tool_choice": true - }, "zai/glm-5": { "cache_creation_input_token_cost": 0, "cache_read_input_token_cost": 2e-07, @@ -42381,6 +43879,36 @@ "search_context_size_high": 0.035 } }, + "vertex_ai/claude-sonnet-5@default": { + "cache_creation_input_token_cost": 2.5e-06, + "cache_creation_input_token_cost_above_1hr": 4e-06, + "cache_read_input_token_cost": 2e-07, + "input_cost_per_token": 2e-06, + "litellm_provider": "vertex_ai-anthropic_models", + "max_input_tokens": 1000000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 1e-05, + "search_context_cost_per_query": { + "search_context_size_high": 0.01, + "search_context_size_low": 0.01, + "search_context_size_medium": 0.01 + }, + "supports_adaptive_thinking": true, + "supports_assistant_prefill": false, + "supports_computer_use": true, + "supports_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_sampling_params": false, + "supports_tool_choice": true, + "supports_vision": true, + "supports_xhigh_reasoning_effort": true, + "supports_max_reasoning_effort": true + }, "vertex_ai/claude-sonnet-4-6@default": { "supports_adaptive_thinking": true, "cache_creation_input_token_cost": 3.75e-06, @@ -42393,7 +43921,6 @@ "max_tokens": 64000, "mode": "chat", "output_cost_per_token": 1.5e-05, - "supports_adaptive_thinking": true, "supports_assistant_prefill": true, "supports_computer_use": true, "supports_function_calling": true, @@ -42427,7 +43954,10 @@ "max_output_tokens": 32768, "max_tokens": 32768, "mode": "chat", - "supported_endpoints": ["/v1/chat/completions", "/v1/responses"], + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/responses" + ], "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_reasoning": true, @@ -42442,7 +43972,10 @@ "max_output_tokens": 32768, "max_tokens": 32768, "mode": "chat", - "supported_endpoints": ["/v1/chat/completions", "/v1/responses"], + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/responses" + ], "supports_function_calling": true, "supports_parallel_function_calling": true, "supports_reasoning": true, @@ -42457,7 +43990,9 @@ "max_output_tokens": 65536, "max_tokens": 65536, "mode": "chat", - "supported_endpoints": ["/v1/chat/completions"], + "supported_endpoints": [ + "/v1/chat/completions" + ], "supports_function_calling": true, "supports_reasoning": true, "supports_response_schema": true, @@ -42471,7 +44006,9 @@ "max_output_tokens": 65536, "max_tokens": 65536, "mode": "chat", - "supported_endpoints": ["/v1/chat/completions"], + "supported_endpoints": [ + "/v1/chat/completions" + ], "supports_function_calling": true, "supports_reasoning": true, "supports_response_schema": true, @@ -42487,9 +44024,16 @@ "max_tokens": 128000, "mode": "responses", "use_openai_responses_path": true, - "supported_endpoints": ["/v1/responses"], - "supported_modalities": ["text", "image"], - "supported_output_modalities": ["text"], + "supported_endpoints": [ + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], "supports_function_calling": true, "supports_prompt_caching": true, "supports_reasoning": true, @@ -42507,9 +44051,16 @@ "max_tokens": 128000, "mode": "responses", "use_openai_responses_path": true, - "supported_endpoints": ["/v1/responses"], - "supported_modalities": ["text", "image"], - "supported_output_modalities": ["text"], + "supported_endpoints": [ + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text" + ], "supports_function_calling": true, "supports_prompt_caching": true, "supports_reasoning": true, @@ -42526,7 +44077,10 @@ "max_tokens": 256000, "mode": "chat", "use_openai_responses_path": true, - "supported_endpoints": ["/v1/chat/completions", "/v1/responses"], + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/responses" + ], "supports_function_calling": true, "supports_parallel_function_calling": false, "supports_reasoning": true, @@ -42542,7 +44096,10 @@ "max_tokens": 256000, "mode": "chat", "use_openai_responses_path": true, - "supported_endpoints": ["/v1/chat/completions", "/v1/responses"], + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/responses" + ], "supports_function_calling": true, "supports_parallel_function_calling": false, "supports_reasoning": true, @@ -42558,13 +44115,36 @@ "max_tokens": 128000, "mode": "chat", "use_openai_responses_path": true, - "supported_endpoints": ["/v1/chat/completions", "/v1/responses"], + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/responses" + ], "supports_function_calling": true, "supports_parallel_function_calling": false, "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, + "bedrock_mantle/xai.grok-4.3": { + "input_cost_per_token": 1.25e-06, + "output_cost_per_token": 2.5e-06, + "cache_read_input_token_cost": 2e-07, + "litellm_provider": "bedrock_mantle", + "max_input_tokens": 131072, + "max_output_tokens": 16384, + "max_tokens": 16384, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/responses" + ], + "supports_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true, + "source": "https://aws.amazon.com/bedrock/pricing/" + }, "volcengine/doubao-seed-2-0-pro-260215": { "litellm_provider": "volcengine", "max_input_tokens": 256000, @@ -42717,20 +44297,6 @@ } ] }, - "zai.glm-5": { - "input_cost_per_token": 1e-06, - "output_cost_per_token": 3.2e-06, - "litellm_provider": "bedrock_converse", - "max_input_tokens": 200000, - "max_output_tokens": 128000, - "max_tokens": 128000, - "mode": "chat", - "supports_function_calling": true, - "supports_reasoning": true, - "supports_system_messages": true, - "supports_tool_choice": true, - "source": "https://aws.amazon.com/bedrock/pricing/" - }, "bedrock/us-east-1/zai.glm-5": { "input_cost_per_token": 1e-06, "output_cost_per_token": 3.2e-06, @@ -42759,45 +44325,6 @@ "supports_tool_choice": true, "source": "https://aws.amazon.com/bedrock/pricing/" }, - "minimax.minimax-m2.5": { - "input_cost_per_token": 3e-07, - "output_cost_per_token": 1.2e-06, - "litellm_provider": "bedrock_converse", - "max_input_tokens": 1000000, - "max_output_tokens": 8192, - "max_tokens": 8192, - "mode": "chat", - "supports_function_calling": true, - "supports_system_messages": true, - "supports_tool_choice": true, - "source": "https://aws.amazon.com/bedrock/pricing/" - }, - "bedrock/us-east-1/minimax.minimax-m2.5": { - "input_cost_per_token": 3e-07, - "output_cost_per_token": 1.2e-06, - "litellm_provider": "bedrock", - "max_input_tokens": 1000000, - "max_output_tokens": 8192, - "max_tokens": 8192, - "mode": "chat", - "supports_function_calling": true, - "supports_system_messages": true, - "supports_tool_choice": true, - "source": "https://aws.amazon.com/bedrock/pricing/" - }, - "bedrock/us-west-2/minimax.minimax-m2.5": { - "input_cost_per_token": 3e-07, - "output_cost_per_token": 1.2e-06, - "litellm_provider": "bedrock", - "max_input_tokens": 1000000, - "max_output_tokens": 8192, - "max_tokens": 8192, - "mode": "chat", - "supports_function_calling": true, - "supports_system_messages": true, - "supports_tool_choice": true, - "source": "https://aws.amazon.com/bedrock/pricing/" - }, "bedrock/us-gov-east-1/anthropic.claude-haiku-4-5-20251001-v1:0": { "cache_creation_input_token_cost": 1.5e-06, "cache_creation_input_token_cost_above_1hr": 2.4e-06, @@ -42819,7 +44346,8 @@ "supports_tool_choice": true, "supports_vision": true, "supports_native_structured_output": true, - "supports_pdf_input": true + "supports_pdf_input": true, + "supports_parallel_tool_use_config": true }, "bedrock/us-gov-west-1/anthropic.claude-haiku-4-5-20251001-v1:0": { "cache_creation_input_token_cost": 1.5e-06, @@ -42842,364 +44370,368 @@ "supports_tool_choice": true, "supports_vision": true, "supports_native_structured_output": true, - "supports_pdf_input": true + "supports_pdf_input": true, + "supports_parallel_tool_use_config": true + }, + "snowflake/claude-sonnet-4-5": { + "max_tokens": 16384, + "max_input_tokens": 200000, + "max_output_tokens": 16384, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "cache_read_input_token_cost": 3e-07, + "litellm_provider": "snowflake", + "mode": "chat", + "supports_function_calling": true, + "supports_vision": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_response_schema": true + }, + "snowflake/claude-sonnet-4-6": { + "max_tokens": 16384, + "max_input_tokens": 200000, + "max_output_tokens": 16384, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "cache_read_input_token_cost": 3e-07, + "litellm_provider": "snowflake", + "mode": "chat", + "supports_function_calling": true, + "supports_vision": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_response_schema": true + }, + "snowflake/claude-4-sonnet": { + "max_tokens": 16384, + "max_input_tokens": 200000, + "max_output_tokens": 16384, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "cache_read_input_token_cost": 3e-07, + "litellm_provider": "snowflake", + "mode": "chat", + "supports_function_calling": true, + "supports_vision": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_response_schema": true + }, + "snowflake/claude-4-opus": { + "max_tokens": 16384, + "max_input_tokens": 200000, + "max_output_tokens": 16384, + "input_cost_per_token": 5e-06, + "output_cost_per_token": 2.5e-05, + "cache_read_input_token_cost": 5e-07, + "litellm_provider": "snowflake", + "mode": "chat", + "supports_function_calling": true, + "supports_vision": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_reasoning": true, + "supports_response_schema": true + }, + "snowflake/claude-haiku-4-5": { + "max_tokens": 16384, + "max_input_tokens": 200000, + "max_output_tokens": 16384, + "input_cost_per_token": 1e-06, + "output_cost_per_token": 5e-06, + "cache_read_input_token_cost": 1e-07, + "litellm_provider": "snowflake", + "mode": "chat", + "supports_function_calling": true, + "supports_vision": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_response_schema": true + }, + "snowflake/claude-3-7-sonnet": { + "max_tokens": 16384, + "max_input_tokens": 200000, + "max_output_tokens": 16384, + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "cache_read_input_token_cost": 3e-07, + "litellm_provider": "snowflake", + "mode": "chat", + "supports_function_calling": true, + "supports_vision": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_reasoning": true, + "supports_response_schema": true + }, + "snowflake/openai-gpt-4.1": { + "max_tokens": 16384, + "max_input_tokens": 300000, + "max_output_tokens": 16384, + "input_cost_per_token": 2e-06, + "output_cost_per_token": 8e-06, + "cache_read_input_token_cost": 5e-07, + "litellm_provider": "snowflake", + "mode": "chat", + "supports_function_calling": true, + "supports_vision": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_response_schema": true + }, + "snowflake/openai-gpt-5": { + "max_tokens": 16384, + "max_input_tokens": 300000, + "max_output_tokens": 16384, + "input_cost_per_token": 1.25e-06, + "output_cost_per_token": 1e-05, + "cache_read_input_token_cost": 1.25e-07, + "litellm_provider": "snowflake", + "mode": "chat", + "supports_function_calling": true, + "supports_vision": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_reasoning": true, + "supports_response_schema": true + }, + "snowflake/openai-gpt-5-mini": { + "max_tokens": 16384, + "max_input_tokens": 1000000, + "max_output_tokens": 16384, + "input_cost_per_token": 3e-07, + "output_cost_per_token": 1.2e-06, + "litellm_provider": "snowflake", + "mode": "chat", + "supports_function_calling": true, + "supports_system_messages": true, + "supports_response_schema": true + }, + "snowflake/openai-gpt-5-nano": { + "max_tokens": 16384, + "max_input_tokens": 5000000, + "max_output_tokens": 16384, + "input_cost_per_token": 1.5e-07, + "output_cost_per_token": 6e-07, + "litellm_provider": "snowflake", + "mode": "chat", + "supports_function_calling": true, + "supports_system_messages": true, + "supports_response_schema": true + }, + "snowflake/llama4-maverick": { + "max_tokens": 16384, + "max_input_tokens": 128000, + "max_output_tokens": 16384, + "input_cost_per_token": 2.4e-07, + "output_cost_per_token": 9.7e-07, + "litellm_provider": "snowflake", + "mode": "chat", + "supports_function_calling": true, + "supports_system_messages": true + }, + "snowflake/snowflake-arctic-embed-l-v2.0": { + "max_tokens": 8192, + "max_input_tokens": 8192, + "input_cost_per_token": 7e-08, + "output_cost_per_token": 0.0, + "litellm_provider": "snowflake", + "mode": "embedding" + }, + "snowflake/snowflake-arctic-embed-m-v2.0": { + "max_tokens": 8192, + "max_input_tokens": 8192, + "input_cost_per_token": 7e-08, + "output_cost_per_token": 0.0, + "litellm_provider": "snowflake", + "mode": "embedding" + }, + "soniox/stt-async-v4": { + "litellm_provider": "soniox", + "max_output_tokens": 8000, + "max_tokens": 8000, + "input_cost_per_second": 0.0, + "output_cost_per_second": 2.77778e-05, + "mode": "audio_transcription", + "source": "https://soniox.com/pricing", + "supported_endpoints": [ + "/v1/audio/transcriptions" + ], + "supports_audio_input": true + }, + "soniox/stt-async-v5": { + "litellm_provider": "soniox", + "max_output_tokens": 8000, + "max_tokens": 8000, + "input_cost_per_second": 0.0, + "output_cost_per_second": 2.77778e-05, + "mode": "audio_transcription", + "source": "https://soniox.com/pricing", + "supported_endpoints": [ + "/v1/audio/transcriptions" + ], + "supports_audio_input": true + }, + "tensormesh/Qwen/Qwen3.5-397B-A17B-FP8": { + "litellm_provider": "tensormesh", + "mode": "chat", + "input_cost_per_token": 6e-07, + "output_cost_per_token": 3.6e-06, + "cache_read_input_token_cost": 0, + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_response_schema": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_reasoning": true, + "source": "https://serverless.tensormesh.ai/v1/models/openrouter" + }, + "tensormesh/Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8": { + "litellm_provider": "tensormesh", + "mode": "chat", + "input_cost_per_token": 4.5e-07, + "output_cost_per_token": 1.8e-06, + "cache_read_input_token_cost": 0, + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_response_schema": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "source": "https://serverless.tensormesh.ai/v1/models/openrouter" + }, + "tensormesh/Qwen/Qwen3.6-27B-FP8": { + "litellm_provider": "tensormesh", + "mode": "chat", + "input_cost_per_token": 3.2e-07, + "output_cost_per_token": 3.2e-06, + "cache_read_input_token_cost": 0, + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_response_schema": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_reasoning": true, + "source": "https://serverless.tensormesh.ai/v1/models/openrouter" + }, + "tensormesh/lukealonso/GLM-5.1-NVFP4-MTP": { + "litellm_provider": "tensormesh", + "mode": "chat", + "input_cost_per_token": 1.4e-06, + "output_cost_per_token": 4.4e-06, + "cache_read_input_token_cost": 0, + "max_input_tokens": 202752, + "max_output_tokens": 202752, + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_response_schema": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_reasoning": true, + "source": "https://serverless.tensormesh.ai/v1/models/openrouter" + }, + "tensormesh/deepseek-ai/DeepSeek-V4-Flash": { + "litellm_provider": "tensormesh", + "mode": "chat", + "input_cost_per_token": 1.4e-07, + "output_cost_per_token": 2.8e-07, + "cache_read_input_token_cost": 0, + "max_input_tokens": 32768, + "max_output_tokens": 32768, + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_response_schema": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_reasoning": true, + "source": "https://serverless.tensormesh.ai/v1/models/openrouter" + }, + "tensormesh/moonshotai/Kimi-K2.6": { + "litellm_provider": "tensormesh", + "mode": "chat", + "input_cost_per_token": 9.6e-07, + "output_cost_per_token": 4e-06, + "cache_read_input_token_cost": 0, + "max_input_tokens": 32768, + "max_output_tokens": 32768, + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_response_schema": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_reasoning": true, + "source": "https://serverless.tensormesh.ai/v1/models/openrouter" + }, + "tensormesh/MiniMaxAI/MiniMax-M2.5": { + "litellm_provider": "tensormesh", + "mode": "chat", + "input_cost_per_token": 3e-07, + "output_cost_per_token": 1.2e-06, + "cache_read_input_token_cost": 0, + "max_input_tokens": 196608, + "max_output_tokens": 196608, + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_response_schema": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_reasoning": true, + "source": "https://serverless.tensormesh.ai/v1/models/openrouter" + }, + "tensormesh/google/gemma-4-31B-it": { + "litellm_provider": "tensormesh", + "mode": "chat", + "input_cost_per_token": 1.4e-07, + "output_cost_per_token": 5.6e-07, + "cache_read_input_token_cost": 0, + "max_input_tokens": 32768, + "max_output_tokens": 32768, + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_response_schema": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_reasoning": true, + "source": "https://serverless.tensormesh.ai/v1/models/openrouter" + }, + "tensormesh/openai/gpt-oss-120b": { + "litellm_provider": "tensormesh", + "mode": "chat", + "input_cost_per_token": 1.5e-07, + "output_cost_per_token": 6e-07, + "cache_read_input_token_cost": 0, + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_response_schema": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_reasoning": true, + "source": "https://serverless.tensormesh.ai/v1/models/openrouter" + }, + "tensormesh/openai/gpt-oss-20b": { + "litellm_provider": "tensormesh", + "mode": "chat", + "input_cost_per_token": 7e-08, + "output_cost_per_token": 2.8e-07, + "cache_read_input_token_cost": 0, + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_response_schema": true, + "supports_prompt_caching": true, + "supports_system_messages": true, + "supports_reasoning": true, + "source": "https://serverless.tensormesh.ai/v1/models/openrouter" }, - "snowflake/claude-sonnet-4-5": { - "max_tokens": 16384, - "max_input_tokens": 200000, - "max_output_tokens": 16384, - "input_cost_per_token": 0.000003, - "output_cost_per_token": 0.000015, - "cache_read_input_token_cost": 0.0000003, - "litellm_provider": "snowflake", - "mode": "chat", - "supports_function_calling": true, - "supports_vision": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_response_schema": true - }, - "snowflake/claude-sonnet-4-6": { - "max_tokens": 16384, - "max_input_tokens": 200000, - "max_output_tokens": 16384, - "input_cost_per_token": 0.000003, - "output_cost_per_token": 0.000015, - "cache_read_input_token_cost": 0.0000003, - "litellm_provider": "snowflake", - "mode": "chat", - "supports_function_calling": true, - "supports_vision": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_response_schema": true - }, - "snowflake/claude-4-sonnet": { - "max_tokens": 16384, - "max_input_tokens": 200000, - "max_output_tokens": 16384, - "input_cost_per_token": 0.000003, - "output_cost_per_token": 0.000015, - "cache_read_input_token_cost": 0.0000003, - "litellm_provider": "snowflake", - "mode": "chat", - "supports_function_calling": true, - "supports_vision": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_response_schema": true - }, - "snowflake/claude-4-opus": { - "max_tokens": 16384, - "max_input_tokens": 200000, - "max_output_tokens": 16384, - "input_cost_per_token": 0.000005, - "output_cost_per_token": 0.000025, - "cache_read_input_token_cost": 0.0000005, - "litellm_provider": "snowflake", - "mode": "chat", - "supports_function_calling": true, - "supports_vision": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_reasoning": true, - "supports_response_schema": true - }, - "snowflake/claude-haiku-4-5": { - "max_tokens": 16384, - "max_input_tokens": 200000, - "max_output_tokens": 16384, - "input_cost_per_token": 0.000001, - "output_cost_per_token": 0.000005, - "cache_read_input_token_cost": 0.0000001, - "litellm_provider": "snowflake", - "mode": "chat", - "supports_function_calling": true, - "supports_vision": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_response_schema": true - }, - "snowflake/claude-3-7-sonnet": { - "max_tokens": 16384, - "max_input_tokens": 200000, - "max_output_tokens": 16384, - "input_cost_per_token": 0.000003, - "output_cost_per_token": 0.000015, - "cache_read_input_token_cost": 0.0000003, - "litellm_provider": "snowflake", - "mode": "chat", - "supports_function_calling": true, - "supports_vision": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_reasoning": true, - "supports_response_schema": true - }, - "snowflake/openai-gpt-4.1": { - "max_tokens": 16384, - "max_input_tokens": 300000, - "max_output_tokens": 16384, - "input_cost_per_token": 0.000002, - "output_cost_per_token": 0.000008, - "cache_read_input_token_cost": 0.0000005, - "litellm_provider": "snowflake", - "mode": "chat", - "supports_function_calling": true, - "supports_vision": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_response_schema": true - }, - "snowflake/openai-gpt-5": { - "max_tokens": 16384, - "max_input_tokens": 300000, - "max_output_tokens": 16384, - "input_cost_per_token": 0.00000125, - "output_cost_per_token": 0.00001, - "cache_read_input_token_cost": 0.000000125, - "litellm_provider": "snowflake", - "mode": "chat", - "supports_function_calling": true, - "supports_vision": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_reasoning": true, - "supports_response_schema": true - }, - "snowflake/openai-gpt-5-mini": { - "max_tokens": 16384, - "max_input_tokens": 1000000, - "max_output_tokens": 16384, - "input_cost_per_token": 0.0000003, - "output_cost_per_token": 0.0000012, - "litellm_provider": "snowflake", - "mode": "chat", - "supports_function_calling": true, - "supports_system_messages": true, - "supports_response_schema": true - }, - "snowflake/openai-gpt-5-nano": { - "max_tokens": 16384, - "max_input_tokens": 5000000, - "max_output_tokens": 16384, - "input_cost_per_token": 0.00000015, - "output_cost_per_token": 0.0000006, - "litellm_provider": "snowflake", - "mode": "chat", - "supports_function_calling": true, - "supports_system_messages": true, - "supports_response_schema": true - }, - "snowflake/llama4-maverick": { - "max_tokens": 16384, - "max_input_tokens": 128000, - "max_output_tokens": 16384, - "input_cost_per_token": 0.00000024, - "output_cost_per_token": 0.00000097, - "litellm_provider": "snowflake", - "mode": "chat", - "supports_function_calling": true, - "supports_system_messages": true - }, - "snowflake/snowflake-arctic-embed-l-v2.0": { - "max_tokens": 8192, - "max_input_tokens": 8192, - "input_cost_per_token": 0.00000007, - "output_cost_per_token": 0.0, - "litellm_provider": "snowflake", - "mode": "embedding" - }, - "snowflake/snowflake-arctic-embed-m-v2.0": { - "max_tokens": 8192, - "max_input_tokens": 8192, - "input_cost_per_token": 0.00000007, - "output_cost_per_token": 0.0, - "litellm_provider": "snowflake", - "mode": "embedding" - }, - "soniox/stt-async-v4": { - "litellm_provider": "soniox", - "max_output_tokens": 8000, - "max_tokens": 8000, - "input_cost_per_second": 0.0, - "output_cost_per_second": 0.0000277778, - "mode": "audio_transcription", - "source": "https://soniox.com/pricing", - "supported_endpoints": ["/v1/audio/transcriptions"], - "supports_audio_input": true - }, - "soniox/stt-async-v5": { - "litellm_provider": "soniox", - "max_output_tokens": 8000, - "max_tokens": 8000, - "input_cost_per_second": 0.0, - "output_cost_per_second": 0.0000277778, - "mode": "audio_transcription", - "source": "https://soniox.com/pricing", - "supported_endpoints": ["/v1/audio/transcriptions"], - "supports_audio_input": true - }, - "tensormesh/Qwen/Qwen3.5-397B-A17B-FP8": { - "litellm_provider": "tensormesh", - "mode": "chat", - "input_cost_per_token": 6e-07, - "output_cost_per_token": 3.6e-06, - "cache_read_input_token_cost": 0, - "max_input_tokens": 262144, - "max_output_tokens": 262144, - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_response_schema": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_reasoning": true, - "source": "https://serverless.tensormesh.ai/v1/models/openrouter" - }, - "tensormesh/Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8": { - "litellm_provider": "tensormesh", - "mode": "chat", - "input_cost_per_token": 4.5e-07, - "output_cost_per_token": 1.8e-06, - "cache_read_input_token_cost": 0, - "max_input_tokens": 262144, - "max_output_tokens": 262144, - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_response_schema": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "source": "https://serverless.tensormesh.ai/v1/models/openrouter" - }, - "tensormesh/Qwen/Qwen3.6-27B-FP8": { - "litellm_provider": "tensormesh", - "mode": "chat", - "input_cost_per_token": 3.2e-07, - "output_cost_per_token": 3.2e-06, - "cache_read_input_token_cost": 0, - "max_input_tokens": 262144, - "max_output_tokens": 262144, - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_response_schema": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_reasoning": true, - "source": "https://serverless.tensormesh.ai/v1/models/openrouter" - }, - "tensormesh/lukealonso/GLM-5.1-NVFP4-MTP": { - "litellm_provider": "tensormesh", - "mode": "chat", - "input_cost_per_token": 1.4e-06, - "output_cost_per_token": 4.4e-06, - "cache_read_input_token_cost": 0, - "max_input_tokens": 202752, - "max_output_tokens": 202752, - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_response_schema": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_reasoning": true, - "source": "https://serverless.tensormesh.ai/v1/models/openrouter" - }, - "tensormesh/deepseek-ai/DeepSeek-V4-Flash": { - "litellm_provider": "tensormesh", - "mode": "chat", - "input_cost_per_token": 1.4e-07, - "output_cost_per_token": 2.8e-07, - "cache_read_input_token_cost": 0, - "max_input_tokens": 32768, - "max_output_tokens": 32768, - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_response_schema": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_reasoning": true, - "source": "https://serverless.tensormesh.ai/v1/models/openrouter" - }, - "tensormesh/moonshotai/Kimi-K2.6": { - "litellm_provider": "tensormesh", - "mode": "chat", - "input_cost_per_token": 9.6e-07, - "output_cost_per_token": 4e-06, - "cache_read_input_token_cost": 0, - "max_input_tokens": 32768, - "max_output_tokens": 32768, - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_response_schema": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_reasoning": true, - "source": "https://serverless.tensormesh.ai/v1/models/openrouter" - }, - "tensormesh/MiniMaxAI/MiniMax-M2.5": { - "litellm_provider": "tensormesh", - "mode": "chat", - "input_cost_per_token": 3e-07, - "output_cost_per_token": 1.2e-06, - "cache_read_input_token_cost": 0, - "max_input_tokens": 196608, - "max_output_tokens": 196608, - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_response_schema": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_reasoning": true, - "source": "https://serverless.tensormesh.ai/v1/models/openrouter" - }, - "tensormesh/google/gemma-4-31B-it": { - "litellm_provider": "tensormesh", - "mode": "chat", - "input_cost_per_token": 1.4e-07, - "output_cost_per_token": 5.6e-07, - "cache_read_input_token_cost": 0, - "max_input_tokens": 32768, - "max_output_tokens": 32768, - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_response_schema": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_reasoning": true, - "source": "https://serverless.tensormesh.ai/v1/models/openrouter" - }, - "tensormesh/openai/gpt-oss-120b": { - "litellm_provider": "tensormesh", - "mode": "chat", - "input_cost_per_token": 1.5e-07, - "output_cost_per_token": 6e-07, - "cache_read_input_token_cost": 0, - "max_input_tokens": 131072, - "max_output_tokens": 131072, - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_response_schema": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_reasoning": true, - "source": "https://serverless.tensormesh.ai/v1/models/openrouter" - }, - "tensormesh/openai/gpt-oss-20b": { - "litellm_provider": "tensormesh", - "mode": "chat", - "input_cost_per_token": 7e-08, - "output_cost_per_token": 2.8e-07, - "cache_read_input_token_cost": 0, - "max_input_tokens": 131072, - "max_output_tokens": 131072, - "supports_function_calling": true, - "supports_tool_choice": true, - "supports_response_schema": true, - "supports_prompt_caching": true, - "supports_system_messages": true, - "supports_reasoning": true, - "source": "https://serverless.tensormesh.ai/v1/models/openrouter" - } - , "deepseek-v4-flash": { "cache_creation_input_token_cost": 0.0, "cache_read_input_token_cost": 2.8e-09, @@ -43334,12 +44866,64 @@ "supports_tool_choice": true, "supports_vision": false }, + "tencent/deepseek-v4-pro": { + "cache_creation_input_token_cost": 0.0, + "cache_read_input_token_cost": 3.625e-09, + "input_cost_per_token": 4.35e-07, + "input_cost_per_token_cache_hit": 3.625e-09, + "litellm_provider": "tencent", + "max_input_tokens": 1000000, + "max_output_tokens": 384000, + "max_tokens": 384000, + "mode": "chat", + "output_cost_per_token": 8.7e-07, + "source": "https://www.tencentcloud.com/products/tokenhub", + "supported_endpoints": [ + "/v1/chat/completions" + ], + "supports_assistant_prefill": true, + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_prompt_caching": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_reasoning": true, + "supports_vision": false + }, + "tencent/deepseek-v4-flash": { + "cache_creation_input_token_cost": 0.0, + "cache_read_input_token_cost": 2.8e-09, + "input_cost_per_token": 1.4e-07, + "input_cost_per_token_cache_hit": 2.8e-09, + "litellm_provider": "tencent", + "max_input_tokens": 1000000, + "max_output_tokens": 384000, + "max_tokens": 384000, + "mode": "chat", + "output_cost_per_token": 2.8e-07, + "source": "https://www.tencentcloud.com/products/tokenhub", + "supported_endpoints": [ + "/v1/chat/completions" + ], + "supports_assistant_prefill": true, + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_prompt_caching": true, + "supports_response_schema": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_reasoning": true, + "supports_vision": false + }, "pinstripes/ps/glm-4.5-air": { "max_tokens": 128000, "max_input_tokens": 128000, "max_output_tokens": 128000, - "input_cost_per_token": 0.000000125, - "output_cost_per_token": 0.00000045, + "input_cost_per_token": 1.25e-07, + "output_cost_per_token": 4.5e-07, "litellm_provider": "pinstripes", "mode": "chat", "supports_function_calling": true, @@ -43351,8 +44935,8 @@ "max_tokens": 131072, "max_input_tokens": 131072, "max_output_tokens": 131072, - "input_cost_per_token": 0.00000014, - "output_cost_per_token": 0.00000045, + "input_cost_per_token": 1.4e-07, + "output_cost_per_token": 4.5e-07, "litellm_provider": "pinstripes", "mode": "chat", "supports_function_calling": true, @@ -43364,8 +44948,8 @@ "max_tokens": 131072, "max_input_tokens": 131072, "max_output_tokens": 131072, - "input_cost_per_token": 0.00000009, - "output_cost_per_token": 0.0000002, + "input_cost_per_token": 9e-08, + "output_cost_per_token": 2e-07, "litellm_provider": "pinstripes", "mode": "chat", "supports_function_calling": true, @@ -43377,8 +44961,8 @@ "max_tokens": 131072, "max_input_tokens": 131072, "max_output_tokens": 131072, - "input_cost_per_token": 0.0000003, - "output_cost_per_token": 0.0000006, + "input_cost_per_token": 3e-07, + "output_cost_per_token": 6e-07, "litellm_provider": "pinstripes", "mode": "chat", "supports_function_calling": true, @@ -43390,8 +44974,8 @@ "max_tokens": 163840, "max_input_tokens": 163840, "max_output_tokens": 163840, - "input_cost_per_token": 0.0000001, - "output_cost_per_token": 0.0000002, + "input_cost_per_token": 1e-07, + "output_cost_per_token": 2e-07, "litellm_provider": "pinstripes", "mode": "chat", "supports_function_calling": true, @@ -43403,8 +44987,8 @@ "max_tokens": 1000192, "max_input_tokens": 1000192, "max_output_tokens": 1000192, - "input_cost_per_token": 0.000000255, - "output_cost_per_token": 0.00000055, + "input_cost_per_token": 2.55e-07, + "output_cost_per_token": 5.5e-07, "litellm_provider": "pinstripes", "mode": "chat", "supports_function_calling": true, @@ -43412,39 +44996,39 @@ "supports_reasoning": false, "source": "https://pinstripes.io/pricing" }, - "fallback_generalizations": { - "rules": [ - { - "name": "anthropic-claude-adaptive-thinking", - "pattern": "(?:opus|sonnet|haiku)[-._](?:4[-._](?:[6-9]|[1-9]\\d)(?!\\d)|(?:[5-9]|[1-9]\\d{1,})[-._]\\d{1,2}(?!\\d))", - "description": "Claude opus/sonnet/haiku at version 4.6 or higher: 4.6 through 4.99, then any 5.x, 6.x or later major. The minor is capped at two digits so an 8-digit date suffix such as claude-opus-4-20250514 is never read as a >= 4.6 minor. Turns on adaptive thinking for new families with no code change.", - "extends": "anthropic-claude", - "model_info": { - "supports_adaptive_thinking": true - } - }, - { - "name": "anthropic-claude", - "pattern": "^claude-[a-z]+-\\d+[-.]\\d+(?:-\\d{8})?$", - "description": "Any Claude family-major-minor id, optionally with an 8-digit date suffix, anchored to the whole name. Version-neutral fallback that gives an unmapped Claude provider routing and baseline capabilities; it carries no pricing, so cost stays on the standard unpriced behavior rather than a guessed number.", - "model_info": { - "litellm_provider": "anthropic", - "mode": "chat", - "max_input_tokens": 200000, - "max_output_tokens": 64000, - "max_tokens": 64000, - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_vision": true, - "supports_tool_choice": true, - "supports_assistant_prefill": true, - "supports_prompt_caching": true, - "supports_response_schema": true, - "supports_reasoning": true, - "supports_pdf_input": true, - "supports_system_messages": true - } - } - ] - } + "fallback_generalizations": { + "rules": [ + { + "name": "anthropic-claude-adaptive-thinking", + "pattern": "(?:opus|sonnet|haiku)[-._](?:4[-._](?:[6-9]|[1-9]\\d)(?!\\d)|(?:[5-9]|[1-9]\\d{1,})[-._]\\d{1,2}(?!\\d))", + "description": "Claude opus/sonnet/haiku at version 4.6 or higher: 4.6 through 4.99, then any 5.x, 6.x or later major. The minor is capped at two digits so an 8-digit date suffix such as claude-opus-4-20250514 is never read as a >= 4.6 minor. Turns on adaptive thinking for new families with no code change.", + "extends": "anthropic-claude", + "model_info": { + "supports_adaptive_thinking": true + } + }, + { + "name": "anthropic-claude", + "pattern": "^claude-[a-z]+-\\d+[-.]\\d+(?:-\\d{8})?$", + "description": "Any Claude family-major-minor id, optionally with an 8-digit date suffix, anchored to the whole name. Version-neutral fallback that gives an unmapped Claude provider routing and baseline capabilities; it carries no pricing, so cost stays on the standard unpriced behavior rather than a guessed number.", + "model_info": { + "litellm_provider": "anthropic", + "mode": "chat", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_vision": true, + "supports_tool_choice": true, + "supports_assistant_prefill": true, + "supports_prompt_caching": true, + "supports_response_schema": true, + "supports_reasoning": true, + "supports_pdf_input": true, + "supports_system_messages": true + } + } + ] + } } diff --git a/litellm/models/end_user.py b/litellm/models/end_user.py index 15fd03ec2ca..9bf895b9447 100644 --- a/litellm/models/end_user.py +++ b/litellm/models/end_user.py @@ -21,6 +21,7 @@ class LiteLLM_EndUserTable(LiteLLMPydanticObjectBase): spend: float = 0.0 allowed_model_region: Optional[Literal["eu", "us"]] = None default_model: Optional[str] = None + budget_id: Optional[str] = None litellm_budget_table: Optional[LiteLLM_BudgetTable] = None object_permission_id: Optional[str] = None object_permission: Optional[LiteLLM_ObjectPermissionTable] = None diff --git a/litellm/models/managed_files.py b/litellm/models/managed_files.py index 24154768860..99ba764dd98 100644 --- a/litellm/models/managed_files.py +++ b/litellm/models/managed_files.py @@ -51,12 +51,12 @@ class LiteLLM_ManagedVectorStoreTable(LiteLLMPydanticObjectBase): class LiteLLM_ManagedVectorStoresTable(LiteLLMPydanticObjectBase): vector_store_id: str custom_llm_provider: str - vector_store_name: Optional[str] - vector_store_description: Optional[str] - vector_store_metadata: Optional[Dict[str, Any]] - created_at: Optional[datetime] - updated_at: Optional[datetime] - litellm_credential_name: Optional[str] - litellm_params: Optional[Dict[str, Any]] - team_id: Optional[str] - user_id: Optional[str] + vector_store_name: Optional[str] = None + vector_store_description: Optional[str] = None + vector_store_metadata: Optional[Dict[str, Any]] = None + created_at: Optional[datetime] = None + updated_at: Optional[datetime] = None + litellm_credential_name: Optional[str] = None + litellm_params: Optional[Dict[str, Any]] = None + team_id: Optional[str] = None + user_id: Optional[str] = None diff --git a/litellm/models/mcp_server.py b/litellm/models/mcp_server.py index 3d03eff6df8..af2efa822b0 100644 --- a/litellm/models/mcp_server.py +++ b/litellm/models/mcp_server.py @@ -83,16 +83,27 @@ class LiteLLM_MCPServerTable(LiteLLMPydanticObjectBase): token_url: Optional[str] = None registration_url: Optional[str] = None oauth2_flow: Optional[Literal["client_credentials", "authorization_code"]] = None + # Token Exchange (OBO) fields — RFC 8693. ``audience`` is named for the RFC's + # request parameter (token-exchange only); RFC 8707 resource indicators are a + # separate concept named ``resource`` in the v2 egress types. A null + # ``subject_token_type`` means DEFAULT_SUBJECT_TOKEN_TYPE (litellm.types.mcp), + # applied at the egress build sites. + token_exchange_endpoint: Optional[str] = None + audience: Optional[str] = None + subject_token_type: Optional[str] = None + token_exchange_profile: Optional[str] = None allow_all_keys: bool = False available_on_public_internet: bool = True delegate_auth_to_upstream: bool = False oauth_passthrough: bool = False + dcr_bridge: Optional[bool] = None is_byok: bool = False byok_description: List[str] = Field(default_factory=list) byok_api_key_help_url: Optional[str] = None has_user_credential: Optional[bool] = None source_url: Optional[str] = None timeout: Optional[float] = None + max_concurrent_requests: Optional[int] = None approval_status: Optional[str] = Field( default="active", description="Approval status: 'pending_review', 'active', 'rejected'", diff --git a/litellm/models/object_permission.py b/litellm/models/object_permission.py index 6c0d100046c..3052a2af459 100644 --- a/litellm/models/object_permission.py +++ b/litellm/models/object_permission.py @@ -24,3 +24,4 @@ class LiteLLM_ObjectPermissionTable(LiteLLMPydanticObjectBase): mcp_toolsets: Optional[List[str]] = None blocked_tools: Optional[List[str]] = [] search_tools: Optional[List[str]] = [] + mcp_tool_search_enabled: Optional[bool] = None diff --git a/litellm/models/verification_token.py b/litellm/models/verification_token.py index 8bddd1c1619..d67726be584 100644 --- a/litellm/models/verification_token.py +++ b/litellm/models/verification_token.py @@ -39,6 +39,7 @@ class LiteLLM_VerificationToken(LiteLLMPydanticObjectBase): permissions: Dict = {} model_spend: Dict = {} model_max_budget: Dict = {} + budget_fallbacks: dict[str, list[str]] = {} soft_budget_cooldown: bool = False blocked: Optional[bool] = None litellm_budget_table: Optional[dict] = None diff --git a/litellm/ocr/main.py b/litellm/ocr/main.py index 5716155361d..38f3f804e10 100644 --- a/litellm/ocr/main.py +++ b/litellm/ocr/main.py @@ -17,6 +17,9 @@ import litellm from litellm._logging import verbose_logger from litellm.constants import request_timeout from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj +from litellm.llms.azure_ai.ocr.common_utils import ( + is_azure_document_intelligence_model, +) from litellm.llms.base_llm.ocr.transformation import BaseOCRConfig, OCRResponse from litellm.llms.custom_httpx.llm_http_handler import BaseLLMHTTPHandler from litellm.rust_bridge import ocr as rust_ocr_bridge @@ -83,6 +86,8 @@ def _prepare_ocr_request( if doc_type not in ["document_url", "image_url"]: raise ValueError(f"Invalid document type: {doc_type}. Must be 'document_url', 'image_url', or 'file'") + caller_supplied_api_base = api_base is not None + ( model, custom_llm_provider, @@ -95,9 +100,14 @@ def _prepare_ocr_request( api_key=api_key, ) + suppress_dynamic_api_base = ( + not caller_supplied_api_base + and custom_llm_provider == "azure_ai" + and is_azure_document_intelligence_model(model) + ) if dynamic_api_key: api_key = dynamic_api_key - if dynamic_api_base: + if dynamic_api_base and not suppress_dynamic_api_base: api_base = dynamic_api_base ocr_provider_config = ProviderConfigManager.get_provider_ocr_config( @@ -191,8 +201,7 @@ def _rust_bridge_api_base( if prepared_request.api_base is not None: return prepared_request.api_base if prepared_request.custom_llm_provider == "azure_ai": - model = prepared_request.model.lower() - if "doc-intelligence" in model or "documentintelligence" in model: + if is_azure_document_intelligence_model(prepared_request.model): return resolve_secret("AZURE_DOCUMENT_INTELLIGENCE_ENDPOINT") return resolve_secret("AZURE_AI_API_BASE") return None diff --git a/litellm/passthrough/main.py b/litellm/passthrough/main.py index 66367513062..cdeedd7b522 100644 --- a/litellm/passthrough/main.py +++ b/litellm/passthrough/main.py @@ -171,7 +171,6 @@ def llm_passthrough_route( api_key: Optional[str] = None, request_query_params: Optional[dict] = None, request_headers: Optional[dict] = None, - allm_passthrough_route: bool = False, content: Optional[Any] = None, data: Optional[dict] = None, files: Optional[RequestFiles] = None, @@ -198,7 +197,7 @@ def llm_passthrough_route( from litellm.types.utils import LlmProviders from litellm.utils import ProviderConfigManager - _is_async = allm_passthrough_route + _is_async = bool(kwargs.get("allm_passthrough_route", False)) litellm_logging_obj = cast("LiteLLMLoggingObj", kwargs.get("litellm_logging_obj")) diff --git a/litellm/proxy/_experimental/mcp_server/AGENTS.md b/litellm/proxy/_experimental/mcp_server/AGENTS.md index 8eebc3ea3b3..6e1d121c3be 100644 --- a/litellm/proxy/_experimental/mcp_server/AGENTS.md +++ b/litellm/proxy/_experimental/mcp_server/AGENTS.md @@ -41,6 +41,7 @@ litellm/proxy/_experimental/mcp_server/ sampling_handler.py # MCP sampling to LiteLLM completion flow elicitation_handler.py # MCP elicitation relay flow semantic_tool_filter.py # semantic filtering of available MCP tools + tool_search.py # opt-in virtual tools (mcp_tool_search + mcp_tool_call) for large catalogs guardrail_translation/ handler.py # MCP guardrail result translation sse_transport.py # SSE transport implementation @@ -79,6 +80,11 @@ module materially harder to understand. encryption need focused tests for both allowed and rejected paths. - Avoid adding comments to new code unless they explain non-obvious security or protocol behavior. Prefer clear names and small functions. +- The virtual tool path (`tool_search.py`, gated by `mcp_tool_search_enabled`) + must mirror the normal tool flow: IP filtering, server allowlist, per-key tool + permissions, no-accessible-server rejection, per-request auth headers, server + scope, error to `isError` conversion, and spend logging. Reuse `_list_mcp_tools` + and `execute_mcp_tool` rather than reimplementing any of these checks. ## Tests diff --git a/litellm/proxy/_experimental/mcp_server/auth/token_exchange.py b/litellm/proxy/_experimental/mcp_server/auth/token_exchange.py index 80e72fa2bf2..cd41dd648ee 100644 --- a/litellm/proxy/_experimental/mcp_server/auth/token_exchange.py +++ b/litellm/proxy/_experimental/mcp_server/auth/token_exchange.py @@ -28,6 +28,7 @@ from litellm.proxy._experimental.mcp_server.auth.token_endpoint_auth import ( build_token_endpoint_client_auth, ) from litellm.types.llms.custom_http import httpxSpecialProvider +from litellm.types.mcp import DEFAULT_SUBJECT_TOKEN_TYPE if TYPE_CHECKING: from litellm.types.mcp_server.mcp_server_manager import MCPServer @@ -35,8 +36,6 @@ if TYPE_CHECKING: # RFC 8693 grant type constant TOKEN_EXCHANGE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:token-exchange" -DEFAULT_SUBJECT_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:access_token" - class TokenExchangeHandler: """Handles OAuth 2.0 Token Exchange (RFC 8693) for MCP servers. diff --git a/litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py b/litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py index 2520c7e82a1..e7ffef0e4e3 100644 --- a/litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py +++ b/litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py @@ -8,9 +8,11 @@ from starlette.types import Scope from litellm._logging import verbose_logger from litellm.proxy._types import ( + UI_TEAM_ID, LiteLLM_TeamTable, ProxyException, SpecialHeaders, + SpecialMCPServerName, SpecialMCPServerNames, UserAPIKeyAuth, ) @@ -218,6 +220,12 @@ class MCPRequestHandler: # when EVERY target is auth_type=oauth2 with delegate_auth_to_upstream # set; fails closed otherwise. validated_user_api_key_auth = UserAPIKeyAuth() + elif MCPRequestHandler._target_servers_are_true_passthrough( + path=request_route, + mcp_servers=mcp_servers, + client_ip=IPAddressUtils.get_mcp_client_ip(request), + ): + validated_user_api_key_auth = UserAPIKeyAuth() elif oauth2_headers: # Authorization on a non-delegated server: the bearer must be a real # LiteLLM credential, so a failed validation is a genuine 401/403 and @@ -356,6 +364,7 @@ class MCPRequestHandler: # Inline imports avoid a circular dependency: mcp_server_manager imports # from this module. from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( + MCPServerManager, global_mcp_server_manager, ) from litellm.types.mcp import MCPAuth @@ -381,7 +390,45 @@ class MCPRequestHandler: # fetches the upstream token automatically using stored credentials, # so allowing anonymous bypass would let any external caller invoke # tools authenticated as LiteLLM's service account. - if server.has_client_credentials: + # + # Resolve the flow rather than reading has_client_credentials directly: + # this is a security gate, and a legacy row whose oauth2_flow was never + # stamped still carries the M2M credential shape (client_id/secret + + # token_url, no authorization_url). Treating an unstamped-but-M2M-shaped + # row as non-M2M here would reopen the anonymous bypass the explicit + # column no longer closes on its own. Shares the one resolution helper + # with the egress backstop and the anonymous-delegate allowlist; all fail + # closed on the ambiguous shape and are removed together once no null rows + # remain. A pure-PKCE delegate server (no stored credentials) resolves to a + # non-M2M flow and keeps its bypass. + if MCPServerManager.effective_oauth2_flow(server) == "client_credentials": + return False + return True + + @staticmethod + def _target_servers_are_true_passthrough( + path: str, mcp_servers: Optional[list[str]], client_ip: Optional[str] + ) -> bool: + """ + True only when EVERY MCP server the request targets is ``auth_type == true_passthrough``. + Fails closed when any target does not opt in or cannot be resolved. + + Used by :meth:`process_mcp_request` to skip LiteLLM admission auth entirely: the gateway is a + transparent proxy and the caller's ``Authorization`` is an upstream token, never a LiteLLM key. + Mirrors :meth:`_target_servers_delegate_auth_to_upstream`; a mixed-target request keeps normal auth. + """ + from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( + global_mcp_server_manager, + ) + from litellm.types.mcp import MCPAuth + + target_names = MCPRequestHandler._resolve_target_server_names(path=path, mcp_servers_header=mcp_servers) + if not target_names: + return False + + for name in target_names: + server = global_mcp_server_manager.get_mcp_server_by_name(name, client_ip=client_ip) + if server is None or server.auth_type != MCPAuth.true_passthrough: return False return True @@ -544,10 +591,19 @@ class MCPRequestHandler: ASGI headers are in format: List[List[bytes, bytes]] We need to convert them to the format Headers expects. + + Collapsing the ASGI list into a dict keeps the last value for a duplicated + header name, so a request carrying more than one ``Authorization`` is + rejected first: for the client-forwarded token modes the gateway relays the + caller's ``Authorization`` upstream, so a duplicate would make which token is + forwarded ambiguous (and diverge from what admission inspected). Multiple + ``Authorization`` headers is malformed for bearer auth anyway (RFC 9110: not + a comma-combinable field), so fail closed with a 400. """ + raw_headers = scope.get("headers", []) + MCPRequestHandler._reject_duplicate_authorization(raw_headers) try: # ASGI headers are list of [name: bytes, value: bytes] pairs - raw_headers = scope.get("headers", []) # Convert bytes to strings and create dict for Headers constructor headers_dict = {name.decode("latin-1"): value.decode("latin-1") for name, value in raw_headers} return Headers(headers_dict) @@ -556,6 +612,26 @@ class MCPRequestHandler: # Return empty Headers object with empty dict return Headers({}) + @staticmethod + def _reject_duplicate_authorization(raw_headers: object) -> None: + """Raise 400 when the raw ASGI headers carry more than one ``Authorization`` header.""" + if not isinstance(raw_headers, (list, tuple)): + return + count = 0 + for entry in raw_headers: + if not isinstance(entry, (list, tuple)) or len(entry) < 1: + continue + name = entry[0] + if isinstance(name, (bytes, bytearray)) and bytes(name).lower() == b"authorization": + count += 1 + elif isinstance(name, str) and name.lower() == "authorization": + count += 1 + if count > 1: + raise HTTPException( + status_code=400, + detail="Multiple Authorization headers are not allowed", + ) + @staticmethod async def get_allowed_mcp_servers( user_api_key_auth: Optional[UserAPIKeyAuth] = None, @@ -725,6 +801,9 @@ class MCPRequestHandler: if not user_api_key_auth or not user_api_key_auth.team_id or not prisma_client: return None + if user_api_key_auth.team_id == UI_TEAM_ID: + return None + # Get the team object (which has object_permission already loaded) team_obj: Optional[LiteLLM_TeamTable] = await get_team_object( team_id=user_api_key_auth.team_id, @@ -1020,6 +1099,9 @@ class MCPRequestHandler: if user_api_key_auth is None or not user_api_key_auth.team_id or prisma_client is None: return [] + if user_api_key_auth.team_id == UI_TEAM_ID: + return [] + team_obj: Optional[LiteLLM_TeamTable] = await get_team_object( team_id=user_api_key_auth.team_id, prisma_client=prisma_client, @@ -1041,6 +1123,9 @@ class MCPRequestHandler: if object_permissions is None: return list(set(team_access_group_servers)) + if SpecialMCPServerName.all_proxy_servers.value in (object_permissions.mcp_servers or []): + return list(global_mcp_server_manager.get_registry().keys()) + direct_mcp_servers = global_mcp_server_manager.expand_permission_list(object_permissions.mcp_servers or []) legacy_access_group_servers = await MCPRequestHandler._get_mcp_servers_from_access_groups( @@ -1499,6 +1584,9 @@ class MCPRequestHandler: verbose_logger.debug("prisma_client is None") return [] + if user_api_key_auth.team_id == UI_TEAM_ID: + return [] + try: team_obj: Optional[LiteLLM_TeamTable] = await get_team_object( team_id=user_api_key_auth.team_id, diff --git a/litellm/proxy/_experimental/mcp_server/db.py b/litellm/proxy/_experimental/mcp_server/db.py index a2ce3307061..97cefb3f2cb 100644 --- a/litellm/proxy/_experimental/mcp_server/db.py +++ b/litellm/proxy/_experimental/mcp_server/db.py @@ -3,7 +3,7 @@ import binascii import hashlib import json from datetime import datetime, timedelta, timezone -from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Set, Union, cast +from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict, Iterable, List, Optional, Set, Union, cast from litellm._logging import verbose_proxy_logger from litellm._uuid import uuid @@ -46,6 +46,64 @@ from litellm.types.mcp import MCPCredentials if TYPE_CHECKING: from litellm.types.mcp_server.mcp_server_manager import MCPServer +_AUTH_FLOW_SCOPED_FIELDS: frozenset = frozenset( + { + "authorization_url", + "token_url", + "registration_url", + "oauth2_flow", + "dcr_bridge", + "token_exchange_endpoint", + "audience", + "subject_token_type", + "token_exchange_profile", + } +) + +# Token-exchange settings with dedicated columns that also exist on +# ``MCPCredentials`` as a legacy shape (rows and REST callers that predate the +# columns). Every write lifts blob values into the columns and strips them from +# the stored blob, so the read-time ``column or blob`` fallback only serves rows +# the current code has never written — a cleared column can then never be +# silently resurrected by a stale blob copy. These keys are stored plaintext +# (endpoints/identifiers, not secrets), so values lift as-is. +_TOKEN_EXCHANGE_COLUMN_FIELDS: frozenset = frozenset( + { + "token_exchange_endpoint", + "audience", + "subject_token_type", + "token_exchange_profile", + } +) + +# The client-forwarded token modes share one stored-credential shape: the admin-declared upstream +# OAuth app (client_id/client_secret) plus the same authorize relay, and neither mints anything the +# gateway keeps. So a switch WITHIN this class must preserve the stored app, unlike a cross-class +# switch (e.g. an oauth2 row whose client may be DCR-minted and is not reusable elsewhere). +_CLIENT_FORWARDED_AUTH_TYPES: frozenset = frozenset({"true_passthrough", "oauth_delegate"}) + +# Minted token material that must never survive a client rotation on a persisted row. +_MINTED_TOKEN_CREDENTIAL_FIELDS: frozenset = frozenset({"access_token", "refresh_token", "expires_in"}) + + +def _credential_auth_class(auth_type: Optional[str]) -> Optional[str]: + """Collapse the client-forwarded modes to one credential class; every other auth_type is its own + class. Used so credential handling keys off whether the stored-credential shape actually changed, + not off a raw auth_type inequality that treats true_passthrough<->oauth_delegate as a full reset.""" + if auth_type in _CLIENT_FORWARDED_AUTH_TYPES: + return "client_forwarded" + return auth_type + + +def _drop_stale_minted_on_client_rotation(merged: Dict[str, Any], new_creds: Dict[str, Any]) -> Dict[str, Any]: + """When the update rotates the client, drop stale minted token keys it did not itself set, so an old + app's access/refresh token never rides forward under the new client. A no-op when no client key changed.""" + if "client_id" not in new_creds and "client_secret" not in new_creds: + return merged + return { + key: value for key, value in merged.items() if key not in _MINTED_TOKEN_CREDENTIAL_FIELDS or key in new_creds + } + def _is_global_env_var_scope(scope: Any) -> bool: """``scope="user"`` entries are placeholders the user fills in; everything @@ -241,6 +299,14 @@ def _prepare_mcp_server_data( # Handle credentials serialization credentials = data_dict.get("credentials") if credentials is not None: + # Lift legacy blob-shaped token-exchange settings into their dedicated + # columns (an explicit top-level value wins, including an explicit + # null) and strip them from the blob so it never seeds the read-time + # fallback for rows written by current code. + for te_field in _TOKEN_EXCHANGE_COLUMN_FIELDS: + blob_value = credentials.pop(te_field, None) + if blob_value is not None and te_field not in data_dict: + data_dict[te_field] = blob_value data_dict["credentials"] = encrypt_credentials(credentials=credentials, encryption_key=_get_salt_key()) data_dict["credentials"] = safe_dumps(data_dict["credentials"]) @@ -521,7 +587,11 @@ async def delete_mcp_server_from_virtualkey(): pass -async def delete_mcp_server(prisma_client: PrismaClient, server_id: str) -> Optional[LiteLLM_MCPServerTable]: +async def delete_mcp_server( + prisma_client: PrismaClient, + server_id: str, + invalidate_token_cache: Optional[Callable[[str, str], Awaitable[None]]] = None, +) -> Optional[LiteLLM_MCPServerTable]: """ Delete the mcp server from the db by server_id @@ -532,6 +602,12 @@ async def delete_mcp_server(prisma_client: PrismaClient, server_id: str) -> Opti caller-visible error. Each table is cleaned independently so a failure on one still attempts the other. + Each enumerated credential row's user also gets their cached per-user token + invalidated (legacy cache + v2 store, via invalidate_token_cache, defaulting + to the manager's shared invalidation): the caches are keyed by + (user_id, server_id), so without this a re-created server reusing the same + server_id would serve tokens minted for the deleted server until TTL. + Returns the deleted mcp server record if it exists, otherwise None """ deleted_server = await MCPServerRepository(prisma_client).table.delete( @@ -540,6 +616,18 @@ async def delete_mcp_server(prisma_client: PrismaClient, server_id: str) -> Opti }, ) if deleted_server is not None: + credential_user_ids: List[str] = [] + try: + credential_rows = await prisma_client.db.litellm_mcpusercredentials.find_many( + where={"server_id": server_id} + ) + credential_user_ids = [row.user_id for row in credential_rows] + except Exception as e: # noqa: BLE001 - enumeration is best-effort; cached tokens expire by TTL + verbose_proxy_logger.warning( + "MCP server %s deleted but per-user credential enumeration failed; cached tokens expire by TTL: %s", + server_id, + e, + ) for model, label in ( (prisma_client.db.litellm_mcpusercredentials, "credential"), (prisma_client.db.litellm_mcpuserenvvars, "env var"), @@ -554,6 +642,15 @@ async def delete_mcp_server(prisma_client: PrismaClient, server_id: str) -> Opti label, e, ) + if credential_user_ids: + if invalidate_token_cache is None: + from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( + global_mcp_server_manager, + ) + + invalidate_token_cache = global_mcp_server_manager.invalidate_user_oauth_token_cache + for user_id in credential_user_ids: + await invalidate_token_cache(user_id, server_id) return deleted_server @@ -603,29 +700,54 @@ async def update_mcp_server( # Pre-fetch existing record once if we need it for auth_type or credential logic existing = None has_credentials = "credentials" in data_dict and data_dict["credentials"] is not None - if data.auth_type or has_credentials: + # An explicit token-exchange column write (set or clear) also migrates the + # legacy blob copies below, so the existing row is needed for those updates. + explicit_te_write = bool(_TOKEN_EXCHANGE_COLUMN_FIELDS & data_dict.keys()) + if data.auth_type or has_credentials or explicit_te_write: existing = await MCPServerRepository(prisma_client).table.find_unique(where={"server_id": data.server_id}) - # Clear stale credentials when auth_type changes but no new credentials provided - if ( + auth_type_changed = bool( data.auth_type - and "credentials" not in data_dict and existing - and existing.auth_type is not None - and existing.auth_type != data.auth_type - ): + and _credential_auth_class(existing.auth_type) != _credential_auth_class(data.auth_type) + ) + + # Clear stale credentials when auth_type changes but no new credentials provided + if auth_type_changed and "credentials" not in data_dict: data_dict["credentials"] = None + if auth_type_changed: + data_dict.update({field: None for field in _AUTH_FLOW_SCOPED_FIELDS if field not in data_dict}) + + # An explicit column write that does not touch credentials must still migrate + # the row's legacy blob copies: lift values for columns the caller left + # untouched, strip every copy from the blob. Without this, clearing a column + # (e.g. to re-enable RFC 9728/8414 discovery) would leave the blob copy in + # place, and the next credentials update's migrate-on-write would silently + # repopulate the column the admin just cleared. (When credentials ARE in the + # update, the merge below performs the same migration.) + if explicit_te_write and "credentials" not in data_dict and existing is not None and existing.credentials: + existing_creds = ( + json.loads(existing.credentials) if isinstance(existing.credentials, str) else dict(existing.credentials) + ) + if _TOKEN_EXCHANGE_COLUMN_FIELDS & existing_creds.keys(): + for te_field in _TOKEN_EXCHANGE_COLUMN_FIELDS: + legacy_value = existing_creds.pop(te_field, None) + if legacy_value is not None and te_field not in data_dict and getattr(existing, te_field, None) is None: + data_dict[te_field] = legacy_value + data_dict["credentials"] = safe_dumps(existing_creds) + # Merge credentials: preserve existing fields not present in the update. # Without this, a partial credential update (e.g. changing only region) # would wipe encrypted secrets that the UI cannot display back. if "credentials" in data_dict and data_dict["credentials"] is not None: if existing and existing.credentials: - # Only merge when auth_type is unchanged. Switching auth types - # (e.g. oauth2 → api_key) should replace credentials entirely - # to avoid stale secrets from the previous auth type lingering. - auth_type_unchanged = data.auth_type is None or data.auth_type == existing.auth_type - if auth_type_unchanged: + # Only merge when the credential CLASS is unchanged. A cross-class switch + # (e.g. oauth2 → api_key, or oauth2 → true_passthrough) replaces credentials + # entirely to avoid stale secrets from the previous class lingering; a switch + # within the client-forwarded class (true_passthrough ↔ oauth_delegate) keeps + # the same declared app and so must merge, not replace. + if not auth_type_changed: existing_creds = ( json.loads(existing.credentials) if isinstance(existing.credentials, str) @@ -636,13 +758,35 @@ async def update_mcp_server( if isinstance(data_dict["credentials"], str) else dict(data_dict["credentials"]) ) - # New values override existing; existing keys not in update are preserved - merged = {**existing_creds, **new_creds} + # New values override existing; existing keys not in update are preserved. A client + # rotation additionally drops the previous app's stale minted token keys. + merged = _drop_stale_minted_on_client_rotation({**existing_creds, **new_creds}, new_creds) + # Migrate-on-write for legacy rows: token-exchange settings the + # old blob shape carried move to their dedicated columns (unless + # the caller set the column this update, or the row already has + # one) and are never re-persisted in the blob. Stored plaintext, + # so the merged value lifts as-is. + for te_field in _TOKEN_EXCHANGE_COLUMN_FIELDS: + legacy_value = merged.pop(te_field, None) + if ( + legacy_value is not None + and te_field not in data_dict + and getattr(existing, te_field, None) is None + ): + data_dict[te_field] = legacy_value data_dict["credentials"] = safe_dumps(merged) # Add audit fields data_dict["updated_by"] = touched_by + # prisma-python rejects a raw ``None`` for a ``Json?`` field ("value is required but not set"); the + # clear paths above use ``None`` as the merge-skip sentinel, so translate it here to ``Json(None)``, + # which writes SQL null and reads back as ``None``. Done at the edge so the merge guards stay simple. + if "credentials" in data_dict and data_dict["credentials"] is None: + from prisma import Json # noqa: PLC0415 # local import: prisma may be ungenerated at module load in some tools + + data_dict["credentials"] = Json(None) + updated_mcp_server = await MCPServerRepository(prisma_client).table.update( where={"server_id": data.server_id}, data=data_dict, # type: ignore @@ -998,6 +1142,103 @@ async def list_user_oauth_credentials( return results +def _decrypted_credential_field(creds: Dict[str, object], field: str) -> object: + """Return one credential field decrypted with the global salt key; non-string and legacy + plaintext values come back unchanged (decrypt_value_helper returns the original on failure).""" + value = creds.get(field) + if not isinstance(value, str): + return value + return decrypt_value_helper( + value=value, + key=field, + exception_type="debug", + return_original_value=True, + ) + + +def mcp_oauth_token_identity(server: object) -> tuple[object, ...]: + """The upstream-OAuth-token-determining fields of an MCP server: the resource/audience (url, or + spec_path for OpenAPI servers), the OAuth mode/grant (auth_type, oauth2_flow), the + authorization-server endpoints, and the OAuth client + scopes. Mirrors the dashboard's + getOAuthAuthorizationIdentity. When any of these change on a server update, previously stored + per-user tokens were minted for the old identity and are stale. Excludes transport and + delegate_auth_to_upstream, which do not affect what token is minted (RFC 8707/8693). + + client_id/client_secret are compared decrypted: stored values are NaCl-encrypted with a fresh + nonce on every write, so comparing ciphertext would flag every routine save as an identity + change and purge tokens that are still valid.""" + creds = getattr(server, "credentials", None) + if isinstance(creds, str): + try: + parsed: object = json.loads(creds) + except ValueError: + parsed = None + else: + parsed = creds + creds_dict: Dict[str, object] = parsed if isinstance(parsed, dict) else {} + return ( + getattr(server, "url", None), + getattr(server, "spec_path", None), + getattr(server, "auth_type", None), + getattr(server, "oauth2_flow", None), + getattr(server, "authorization_url", None), + getattr(server, "token_url", None), + getattr(server, "registration_url", None), + _decrypted_credential_field(creds_dict, "client_id"), + _decrypted_credential_field(creds_dict, "client_secret"), + creds_dict.get("scopes"), + ) + + +async def purge_user_oauth_credentials_for_server( + prisma_client: PrismaClient, + server_id: str, + invalidate_token_cache: Optional[Callable[[str, str], Awaitable[None]]] = None, +) -> int: + """Delete every stored per-user OAuth token for a server and invalidate each user's cached + token everywhere it can be served from (the legacy per-user token cache and the v2 per-user OAuth + token store), so no user keeps a token minted for a superseded configuration. Called when a server + update changes a mint-relevant field (see mcp_oauth_token_identity). Returns the number of rows + removed. + + LiteLLM_MCPUserCredentials also stores BYOK API keys in the same column; only rows whose payload + decodes as an OAuth2 credential (see _decode_oauth_payload) are deleted, because a config change + only invalidates minted tokens, never a user's own stored key. Rows are therefore deleted per + (user_id, server_id) pair rather than by a blanket server_id filter. An OAuth row inserted while + the purge runs for a user not yet enumerated survives; a re-auth completing in the window for an + already-enumerated user is deleted along with the stale row (the pair delete cannot tell them + apart), which costs that user one extra re-auth and nothing else. + + invalidate_token_cache is injectable for tests; it defaults to the manager's shared + invalidate_user_oauth_token_cache, the single invalidation point for per-user tokens.""" + repo = MCPUserCredentialsRepository(prisma_client) + rows = await repo.table.find_many(where={"server_id": server_id}) + oauth_rows = [row for row in rows if _decode_oauth_payload(row.credential_b64) is not None] + if not oauth_rows: + return 0 + deleted_count = await repo.table.delete_many( + where={"server_id": server_id, "user_id": {"in": [row.user_id for row in oauth_rows]}} + ) + if invalidate_token_cache is None: + from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( + global_mcp_server_manager, + ) + + invalidate_token_cache = global_mcp_server_manager.invalidate_user_oauth_token_cache + + for row in oauth_rows: + await invalidate_token_cache(row.user_id, server_id) + if deleted_count != len(oauth_rows): + verbose_proxy_logger.warning( + "MCP server %s: purge removed %d OAuth credential row(s) but %d were enumerated; " + "row(s) were deleted concurrently during the purge", + server_id, + deleted_count, + len(oauth_rows), + ) + return deleted_count + + async def refresh_user_oauth_token( prisma_client: PrismaClient, user_id: str, @@ -1228,6 +1469,23 @@ def _remaining_token_seconds(expires_at: str | None) -> int | None: return remaining if remaining > 0 else None +async def get_active_submitted_mcp_server_ids_for_user( + prisma_client: PrismaClient, + user_id: str, +) -> list[str]: + """Return active BYOM servers submitted by this user (creator visibility).""" + if not user_id: + return [] + + rows = await MCPServerRepository(prisma_client).table.find_many( + where={ + "submitted_by": user_id, + "approval_status": MCPApprovalStatus.active, + }, + ) + return [row.server_id for row in rows] + + async def approve_mcp_server( prisma_client: PrismaClient, server_id: str, diff --git a/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py b/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py index 6933aa06b2d..9689a7cb047 100644 --- a/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py +++ b/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py @@ -1,14 +1,16 @@ import asyncio import html as _html import json +import secrets import time from datetime import datetime, timezone -from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple +from typing import TYPE_CHECKING, Any, Dict, Literal, Optional, Tuple from urllib.parse import parse_qsl, urlencode, urlparse, urlunparse import httpx from fastapi import APIRouter, Form, HTTPException, Request -from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse +from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse, Response +from pydantic import BaseModel, ValidationError from litellm._logging import verbose_logger from litellm.llms.custom_httpx.http_handler import ( @@ -31,11 +33,11 @@ from litellm.proxy.common_utils.encrypt_decrypt_utils import ( ) from litellm.proxy.common_utils.http_parsing_utils import _read_request_body from litellm.proxy.utils import get_server_root_path -from litellm.types.mcp import MCPAuth +from litellm.types.mcp import MCPAuth, MCPCredentials from litellm.types.mcp_server.mcp_server_manager import MCPServer if TYPE_CHECKING: - from litellm.proxy._types import UserAPIKeyAuth + from litellm.proxy._types import LiteLLM_MCPServerTable, UserAPIKeyAuth # TTL cache for upstream OAuth metadata fetched from pass-through MCP servers. # Keeps us from hammering the upstream IdP on each discovery request. @@ -136,6 +138,72 @@ def decode_state_hash(encrypted_state: str) -> dict: return state_data +# LIT-4197: some upstream authorization servers reject an over-long ``state`` +# (the encrypted OAuth session blob routinely exceeds their limit). The upstream +# only needs an opaque value it echoes back on ``/callback``, so we forward a +# short random handle and keep the encrypted session in a per-flow HttpOnly +# cookie bound to that handle. The browser carries the cookie across the +# upstream round trip, so the flow stays correct with no server-side session +# store (works across proxy replicas, unlike an in-process map). +_OAUTH_STATE_COOKIE_PREFIX = "mcp_oauth_state_" +_OAUTH_STATE_COOKIE_TTL_SECONDS = 600 +_OAUTH_STATE_HANDLE_BYTES = 32 + + +def _oauth_state_cookie_name(relay_state: str) -> str: + return f"{_OAUTH_STATE_COOKIE_PREFIX}{relay_state}" + + +def _oauth_state_cookie_path_and_secure(request: Request) -> tuple[str, bool]: + parsed = urlparse(get_request_base_url(request)) + return parsed.path or "/", parsed.scheme == "https" + + +def _set_oauth_state_cookie( + response: Response, + request: Request, + relay_state: str, + encoded_state: str, +) -> None: + path, secure = _oauth_state_cookie_path_and_secure(request) + response.set_cookie( + key=_oauth_state_cookie_name(relay_state), + value=encoded_state, + max_age=_OAUTH_STATE_COOKIE_TTL_SECONDS, + path=path, + secure=secure, + httponly=True, + samesite="lax", + ) + + +def _resolve_encoded_oauth_state(request: Request, state: str) -> str: + """Return the encrypted OAuth session for a ``/callback`` request. + + New flows carry it in a per-flow cookie keyed by the short handle we + forwarded upstream (the IdP echoes that handle back as ``state``). Flows + started before this change - or in flight across a deploy - carry the + encrypted blob directly in ``state``, so fall back to it when the cookie + is absent. + """ + cookie_value = request.cookies.get(_oauth_state_cookie_name(state)) + return cookie_value if cookie_value else state + + +def _clear_oauth_state_cookie(response: Response, request: Request, state: str) -> None: + cookie_name = _oauth_state_cookie_name(state) + if cookie_name not in request.cookies: + return + path, secure = _oauth_state_cookie_path_and_secure(request) + response.delete_cookie( + key=cookie_name, + path=path, + secure=secure, + httponly=True, + samesite="lax", + ) + + def _get_validated_client_redirect_uri(request: Request, state_data: Dict[str, Any]) -> str: """Return a trusted (same-origin, loopback, or ops-allowlisted) client redirect URI from OAuth state. @@ -380,6 +448,12 @@ async def _store_per_user_token_server_side( ) return # Don't warm Redis if DB write failed + from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( # noqa: PLC0415 + global_mcp_server_manager, + ) + + await global_mcp_server_manager.invalidate_user_oauth_token_cache(user_id, server.server_id) + # Warm the Redis cache so the first subsequent MCP call is a cache hit ttl = _compute_per_user_token_ttl(server, expires_in) await mcp_per_user_token_cache.set( @@ -390,6 +464,121 @@ async def _store_per_user_token_server_side( ) +def _raise_if_not_oauth2(mcp_server: MCPServer) -> None: + """Reject a server without upstream OAuth from the gateway's authorize/token/register flow. + + The client-forwarded token modes (``true_passthrough`` / ``oauth_delegate``) are allowed + through: the caller owns the upstream token, and this relayed flow is how a browser obtains + one against the upstream IdP (the admin UI's browser-only Authorize uses it). The minted + token is upstream-audienced and held by the caller; the gateway persists nothing for these + modes (``_persist_dcr_client_registration`` skips them unconditionally, so even the admin + Authorize path with ``persist_credentials`` enabled writes nothing to the server row). + """ + from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( # noqa: PLC0415 # circular import with mcp_server_manager at module load + _UPSTREAM_OAUTH_DISCOVERY_AUTH_TYPES, + ) + + if mcp_server.auth_type in _UPSTREAM_OAUTH_DISCOVERY_AUTH_TYPES: + return + raise HTTPException( + status_code=400, + detail={ + "error": "server_not_oauth2", + "message": ( + f"MCP server '{mcp_server.server_name or mcp_server.name}' does not use OAuth " + f"(auth_type={mcp_server.auth_type}). This server does not support the authorization-code " + "flow; it has no client_id, authorize, token, or registration endpoint. " + "Access is controlled by the server's configured auth_type and access groups" + ), + }, + ) + + +def _raise_unless_oauth2_discovery_server( + mcp_server: Optional[MCPServer], + mcp_server_name: Optional[str], + description: str, +) -> None: + """404 a NAMED discovery request unless it resolves to an oauth2 or DCR-bridge server. + + A named server that is unknown (or hidden from the caller) and one that exists + but is non-oauth2 both return the same 404, so the well-known discovery paths + cannot be used to enumerate non-OAuth server names. Root discovery (no name) is + unaffected, and pass-through servers are resolved by the caller before this runs. + DCR-bridge servers are admitted because they serve the gateway's own authorization + server metadata (the register, authorize, and token relays). + """ + if mcp_server_name is None: + return + if mcp_server is not None and mcp_server.auth_type == MCPAuth.oauth2: + return + if mcp_server is not None and mcp_server.is_dcr_bridge: + return + raise HTTPException( + status_code=404, + detail=f"MCP server '{mcp_server_name}' is {description}", + ) + + +def _dcr_bridge_relays_client_registration(mcp_server: MCPServer) -> bool: + """True when a DCR-bridge server relays client registration to the upstream authorization + server instead of short-circuiting to an admin-configured OAuth client. In the relay arm the + upstream holds each client's own registration, so the authorize and token relays pass the + client's ``client_id`` and ``redirect_uri`` through verbatim and the authorization code + returns directly to the client's redirect URI without transiting the gateway. Gateway-side + redirect trust and the ``/callback`` state relay therefore only apply to the short-circuit + arm, where the upstream only knows the gateway's own callback.""" + return mcp_server.is_dcr_bridge and bool(mcp_server.registration_url) and not mcp_server.client_id + + +def _require_s256_pkce( + code_challenge: Optional[str], + code_challenge_method: Optional[str], +) -> Tuple[str, str]: + """DCR-bridge servers serve unauthenticated public OAuth clients, so the PKCE downgrade + paths (no challenge, or a non-S256 method; RFC 7636 defaults a missing method to ``plain``) + are rejected at the gateway instead of relying on upstream enforcement. Returns the + validated pair so callers get non-optional values.""" + if code_challenge and code_challenge_method == "S256": + return code_challenge, code_challenge_method + raise HTTPException( + status_code=400, + detail=( + "This server requires PKCE: send code_challenge with " + "code_challenge_method=S256 on the authorization request" + ), + ) + + +def _redirect_to_upstream_authorize( + *, + mcp_server: MCPServer, + client_id: str, + redirect_uri: str, + state: str, + code_challenge: str, + code_challenge_method: str, + response_type: Optional[str], + scope: Optional[str], +) -> RedirectResponse: + """The bridge relay arm's authorize redirect: every client-supplied parameter passes through + to the upstream authorize endpoint verbatim, no relay state cookie is set, and the upstream + enforces its own registered redirect binding for the client.""" + scope_value = scope or (" ".join(mcp_server.scopes) if mcp_server.scopes else None) + passthrough_params = { + "client_id": client_id, + "redirect_uri": redirect_uri, + "state": state, + "response_type": response_type or "code", + "code_challenge": code_challenge, + "code_challenge_method": code_challenge_method, + **({"scope": scope_value} if scope_value else {}), + } + parsed_auth_url = urlparse(mcp_server.authorization_url or "") + merged_params = {**dict(parse_qsl(parsed_auth_url.query)), **passthrough_params} + return RedirectResponse(urlunparse(parsed_auth_url._replace(query=urlencode(merged_params)))) + + async def authorize_with_server( request: Request, mcp_server: MCPServer, @@ -401,11 +590,28 @@ async def authorize_with_server( response_type: Optional[str] = None, scope: Optional[str] = None, ): - if mcp_server.auth_type != "oauth2": - raise HTTPException(status_code=400, detail="MCP server is not OAuth2") + _raise_if_not_oauth2(mcp_server) if mcp_server.authorization_url is None: raise HTTPException(status_code=400, detail="MCP server authorization url is not set") + if mcp_server.is_dcr_bridge: + # Enforce S256 PKCE on both bridge arms. The relay arm forwards the validated, + # now-non-optional pair to the upstream authorize; the short-circuit arm keeps + # calling this for its enforcement side effect, then falls through to the gateway + # /callback flow below, which reads the original code_challenge names. + bridge_challenge, bridge_method = _require_s256_pkce(code_challenge, code_challenge_method) + if _dcr_bridge_relays_client_registration(mcp_server): + return _redirect_to_upstream_authorize( + mcp_server=mcp_server, + client_id=client_id, + redirect_uri=redirect_uri, + state=state, + code_challenge=bridge_challenge, + code_challenge_method=bridge_method, + response_type=response_type, + scope=scope, + ) + # Trusted redirect_uri: same-origin, loopback, or ops-allowlisted. # The URI is encrypted into the OAuth state and decoded on # /callback to redirect the user back; a non-trusted URI would be @@ -421,11 +627,12 @@ async def authorize_with_server( code_challenge_method=code_challenge_method, client_redirect_uri=redirect_uri, ) + relay_state = secrets.token_urlsafe(_OAUTH_STATE_HANDLE_BYTES) params = { "client_id": mcp_server.client_id if mcp_server.client_id else client_id, "redirect_uri": f"{request_base_url}/callback", - "state": encoded_state, + "state": relay_state, "response_type": response_type or "code", } if scope: @@ -442,7 +649,9 @@ async def authorize_with_server( existing_params = dict(parse_qsl(parsed_auth_url.query)) existing_params.update(params) final_url = urlunparse(parsed_auth_url._replace(query=urlencode(existing_params))) - return RedirectResponse(final_url) + response = RedirectResponse(final_url) + _set_oauth_state_cookie(response, request, relay_state, encoded_state) + return response async def exchange_token_with_server( @@ -457,14 +666,19 @@ async def exchange_token_with_server( refresh_token: Optional[str] = None, scope: Optional[str] = None, ): + _raise_if_not_oauth2(mcp_server) if grant_type not in ("authorization_code", "refresh_token"): raise HTTPException(status_code=400, detail="Unsupported grant_type") if mcp_server.token_url is None: raise HTTPException(status_code=400, detail="MCP server token url is not set") + # The id and secret must come from the same source. When the server-side client_id wins, + # falling back to the caller's secret pairs the persisted client with a foreign secret; the + # register short-circuit hands clients a placeholder secret ("dummy"), so a re-auth against a + # persisted public PKCE client (no stored secret) would send that placeholder and the IdP 401s. resolved_client_id = mcp_server.client_id if mcp_server.client_id else client_id - resolved_client_secret = mcp_server.client_secret if mcp_server.client_secret else client_secret + resolved_client_secret = mcp_server.client_secret if mcp_server.client_id else client_secret try: client_auth = build_token_endpoint_client_auth( auth_method=mcp_server.token_endpoint_auth_method, @@ -493,11 +707,21 @@ async def exchange_token_with_server( status_code=400, detail="code is required for authorization_code grant", ) + bridge_token_relay = _dcr_bridge_relays_client_registration(mcp_server) + if bridge_token_relay and not redirect_uri: + raise HTTPException( + status_code=400, + detail=( + "redirect_uri is required for the authorization_code grant on this server; " + "send the same redirect_uri used on the authorization request" + ), + ) proxy_base_url = get_request_base_url(request) + resolved_redirect_uri = redirect_uri if bridge_token_relay else f"{proxy_base_url}/callback" token_data = { "grant_type": "authorization_code", "code": code, - "redirect_uri": f"{proxy_base_url}/callback", + "redirect_uri": resolved_redirect_uri, **client_auth.body, } if code_verifier: @@ -515,7 +739,17 @@ async def exchange_token_with_server( detail="MCP upstream token endpoint returned no response", ) - response.raise_for_status() + try: + response.raise_for_status() + except httpx.HTTPStatusError as exc: + if "invalid_target" in exc.response.text: + verbose_logger.warning( + "MCP server %s: the upstream authorization server rejected the token request with " + "invalid_target; it may require RFC 8707 resource indicators, which the gateway " + "does not send yet (tracked as LIT-4339)", + mcp_server.server_id, + ) + raise token_response = response.json() access_token = token_response["access_token"] @@ -573,6 +807,203 @@ async def exchange_token_with_server( return JSONResponse(result, headers=TOKEN_NO_CACHE_HEADERS) +class _DcrClientRegistration(BaseModel): + """RFC 7591 dynamic client registration response, narrowed to the fields the gateway + must persist to authenticate later token-endpoint calls. Extra members are ignored.""" + + client_id: str + client_secret: Optional[str] = None + token_endpoint_auth_method: Optional[str] = None + + +class _PersistedDcrCredentials(BaseModel): + client_id: Optional[str] = None + client_secret: Optional[str] = None + token_endpoint_auth_method: Optional[str] = None + + +def _get_persisted_dcr_credentials(credentials: object) -> Optional[_PersistedDcrCredentials]: + if not credentials: + return None + try: + return ( + _PersistedDcrCredentials.model_validate_json(credentials) + if isinstance(credentials, str) + else _PersistedDcrCredentials.model_validate(credentials) + ) + except ValidationError: + return None + + +def _decrypt_persisted_dcr_credential(value: Optional[str], key: str) -> Optional[str]: + if value is None: + return None + return decrypt_value_helper( + value=value, + key=key, + exception_type="debug", + return_original_value=True, + ) + + +def _apply_persisted_dcr_credentials(mcp_server: MCPServer, credentials: _PersistedDcrCredentials) -> bool: + client_id = _decrypt_persisted_dcr_credential(credentials.client_id, "client_id") + if not client_id: + return False + mcp_server.client_id = client_id + mcp_server.client_secret = _decrypt_persisted_dcr_credential(credentials.client_secret, "client_secret") + mcp_server.token_endpoint_auth_method = credentials.token_endpoint_auth_method + return True + + +async def _get_persisted_mcp_server_with_dcr_client_id( + mcp_server: MCPServer, +) -> Optional[tuple["LiteLLM_MCPServerTable", _PersistedDcrCredentials]]: + from litellm.proxy._experimental.mcp_server.db import get_mcp_server # noqa: PLC0415 + from litellm.proxy.utils import get_prisma_client_or_throw # noqa: PLC0415 + + try: + prisma_client = get_prisma_client_or_throw("Database not connected. Cannot read MCP OAuth client registration.") + persisted_mcp_server = await get_mcp_server( + prisma_client=prisma_client, + server_id=mcp_server.server_id, + ) + except Exception as exc: # noqa: BLE001 + verbose_logger.debug( + "register_client_with_server: failed to read persisted DCR client registration for server_id=%s: %s", + mcp_server.server_id, + exc, + ) + return None + + if persisted_mcp_server is None: + return None + + credentials = _get_persisted_dcr_credentials(persisted_mcp_server.credentials) + if credentials is None or not credentials.client_id: + return None + + return persisted_mcp_server, credentials + + +async def _reuse_persisted_dcr_client_if_available(mcp_server: MCPServer) -> bool: + persisted = await _get_persisted_mcp_server_with_dcr_client_id(mcp_server) + if persisted is None: + return False + persisted_mcp_server, credentials = persisted + if not _apply_persisted_dcr_credentials(mcp_server, credentials): + return False + + from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( # noqa: PLC0415 + global_mcp_server_manager, + ) + + try: + await global_mcp_server_manager.update_server(persisted_mcp_server) + except Exception as exc: # noqa: BLE001 + verbose_logger.warning( + "register_client_with_server: failed to refresh persisted DCR client registration for server_id=%s: %s", + mcp_server.server_id, + exc, + ) + return bool(mcp_server.client_id) + + +DcrRegistrationPersistenceResult = Literal["persisted", "reused", "skipped", "failed"] + + +async def _persist_dcr_client_registration( + mcp_server: MCPServer, registration_response: object +) -> DcrRegistrationPersistenceResult: + """Persist the dynamically registered OAuth client (RFC 7591) onto the MCP server row. + + The interactive authorization_code flow mints a ``client_id`` via Dynamic Client + Registration that discovery cannot re-derive; without persisting it the autonomous + ``refresh_token`` grant has no client identity, so an expired access token forces a + full re-authorization instead of a silent refresh. Mirrors the ``encrypt_credentials`` + write that ``client_credentials`` and token exchange already use. Failures are logged, + never raised: registration still returns to the caller even when persistence fails. + + The client-forwarded token modes (``true_passthrough`` / ``oauth_delegate``) are skipped + unconditionally: the caller holds the upstream token and the gateway must hold no OAuth + client identity for these servers. Persisting here would stamp ``oauth2_flow`` and a + ``client_id`` onto a server whose mode promises the gateway stores nothing, making a + fresh pass-through server read as gateway-authorized. + """ + if mcp_server.is_true_passthrough or mcp_server.is_oauth_delegate: + return "skipped" + + try: + registration = _DcrClientRegistration.model_validate(registration_response) + except ValidationError as exc: + verbose_logger.warning( + "register_client_with_server: DCR response has no usable client_id for server_id=%s; " + "client registration not persisted (%s)", + mcp_server.server_id, + exc, + ) + return "failed" + + if await _reuse_persisted_dcr_client_if_available(mcp_server): + return "reused" + + credentials: MCPCredentials = { + "client_id": registration.client_id, + **({"client_secret": registration.client_secret} if registration.client_secret is not None else {}), + **( + {"token_endpoint_auth_method": "client_secret_basic"} + if registration.token_endpoint_auth_method == "client_secret_basic" + else {} + ), + } + + from litellm.proxy._experimental.mcp_server.db import update_mcp_server # noqa: PLC0415 + from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( # noqa: PLC0415 + global_mcp_server_manager, + ) + from litellm.proxy._types import UpdateMCPServerRequest # noqa: PLC0415 + from litellm.proxy.utils import get_prisma_client_or_throw # noqa: PLC0415 + + try: + prisma_client = get_prisma_client_or_throw( + "Database not connected. Cannot persist MCP OAuth client registration." + ) + updated_row = await update_mcp_server( + prisma_client=prisma_client, + data=UpdateMCPServerRequest( + server_id=mcp_server.server_id, + credentials=credentials, + oauth2_flow="authorization_code", + **({"token_url": mcp_server.token_url} if mcp_server.token_url else {}), + ), + touched_by="mcp_oauth_dcr", + ) + await global_mcp_server_manager.update_server(updated_row) + return "persisted" + except Exception as exc: # noqa: BLE001 + verbose_logger.warning( + "register_client_with_server: failed to persist DCR client registration for server_id=%s: %s", + mcp_server.server_id, + exc, + ) + return "failed" + + +_MAX_UPSTREAM_ERROR_CHARS = 500 + + +def _safe_upstream_error_detail(response: httpx.Response) -> str: + """Bounded plaintext summary of an upstream registration failure for the client. + + RFC 7591 error bodies are small JSON objects (``error`` / ``error_description``); relaying the + text lets the client read the real reason instead of a bare 500, and the length bound keeps a + hostile or oversized upstream body from bloating the gateway response.""" + body = response.text + if not body: + return response.reason_phrase or "upstream registration failed" + return body[:_MAX_UPSTREAM_ERROR_CHARS] + + async def register_client_with_server( request: Request, mcp_server: MCPServer, @@ -581,7 +1012,10 @@ async def register_client_with_server( response_types: Optional[list], token_endpoint_auth_method: Optional[str], fallback_client_id: Optional[str] = None, + persist_credentials: bool = False, + client_redirect_uris: Optional[list] = None, ): + _raise_if_not_oauth2(mcp_server) request_base_url = get_request_base_url(request) dummy_return = { "client_id": fallback_client_id or mcp_server.server_name, @@ -589,7 +1023,10 @@ async def register_client_with_server( "redirect_uris": [f"{request_base_url}/callback"], } - if mcp_server.client_id and mcp_server.client_secret: + if mcp_server.client_id: + return dummy_return + + if await _reuse_persisted_dcr_client_if_available(mcp_server): return dummy_return if mcp_server.authorization_url is None: @@ -598,12 +1035,19 @@ async def register_client_with_server( if mcp_server.registration_url is None: return dummy_return + bridge_relay = _dcr_bridge_relays_client_registration(mcp_server) + if bridge_relay and not client_redirect_uris: + raise HTTPException( + status_code=400, + detail="redirect_uris is required to register a client with this server", + ) + register_data = { "client_name": client_name, - "redirect_uris": [f"{request_base_url}/callback"], - "grant_types": grant_types or [], - "response_types": response_types or [], - "token_endpoint_auth_method": token_endpoint_auth_method or "", + "redirect_uris": client_redirect_uris if bridge_relay else [f"{request_base_url}/callback"], + "grant_types": grant_types or (["authorization_code", "refresh_token"] if bridge_relay else []), + "response_types": response_types or (["code"] if bridge_relay else []), + "token_endpoint_auth_method": token_endpoint_auth_method or ("none" if bridge_relay else ""), } headers = { "Content-Type": "application/json", @@ -621,10 +1065,17 @@ async def register_client_with_server( status_code=502, detail="MCP upstream registration endpoint returned no response", ) + if bridge_relay and response.status_code >= 400: + raise HTTPException(status_code=response.status_code, detail=_safe_upstream_error_detail(response)) response.raise_for_status() token_response = response.json() + if persist_credentials and not bridge_relay: + persistence_result = await _persist_dcr_client_registration(mcp_server, token_response) + if persistence_result == "reused": + return dummy_return + return JSONResponse(token_response) @@ -655,6 +1106,7 @@ async def authorize( mcp_server = _resolve_oauth2_server_for_root_endpoints(client_ip=client_ip) if mcp_server is None: raise HTTPException(status_code=404, detail="MCP server not found") + _raise_if_not_oauth2(mcp_server) # Use server's stored client_id when caller doesn't supply one. # Raise a clear error instead of passing an empty string — an empty # client_id would silently produce a broken authorization URL. @@ -791,17 +1243,19 @@ async def callback( error_description, ) if state: + encoded_state = _resolve_encoded_oauth_state(request, state) try: - state_data = decode_state_hash(state) + state_data = decode_state_hash(encoded_state) original_state = state_data.get("original_state") redirect_uri = _get_validated_client_redirect_uri(request, state_data) - except HTTPException: - # Untrusted/invalid client redirect_uri — surface inline rather - # than blindly forwarding the error to an attacker-controlled URL. - return _render_oauth_error_html(error, error_description) except Exception: - # State could not be decrypted (expired key, tampered, etc.). - return _render_oauth_error_html(error, error_description) + # Untrusted/invalid client redirect_uri (HTTPException), or an + # undecryptable state (expired key, tampered): surface the IdP + # error inline rather than forwarding it to an attacker-controlled + # URL, and drop the one-time cookie we can no longer consume. + response = _render_oauth_error_html(error, error_description) + _clear_oauth_state_cookie(response, request, state) + return response params: Dict[str, str] = {"error": error} if error_description: @@ -811,7 +1265,9 @@ async def callback( if original_state is not None: params["state"] = original_state complete_returned_url = _append_query_params(redirect_uri, params) - return RedirectResponse(url=complete_returned_url, status_code=302) + response = RedirectResponse(url=complete_returned_url, status_code=302) + _clear_oauth_state_cookie(response, request, state) + return response # No state — nothing to round-trip to. Show the user the error. return _render_oauth_error_html(error, error_description) @@ -827,7 +1283,8 @@ async def callback( # 3. Successful authorization response. try: - state_data = decode_state_hash(state) + encoded_state = _resolve_encoded_oauth_state(request, state) + state_data = decode_state_hash(encoded_state) original_state = state_data["original_state"] # Re-validate the client redirect URI at the sink. /authorize @@ -840,14 +1297,18 @@ async def callback( params = {"code": code, "state": original_state} complete_returned_url = _append_query_params(redirect_uri, params) - return RedirectResponse(url=complete_returned_url, status_code=302) + response = RedirectResponse(url=complete_returned_url, status_code=302) + _clear_oauth_state_cookie(response, request, state) + return response except HTTPException: # Re-raise so a non-loopback base_url surfaces as 400 instead of # a generic "authentication incomplete" redirect. raise except Exception: - return HTMLResponse("Authentication incomplete. You can close this window.") + response = HTMLResponse("Authentication incomplete. You can close this window.") + _clear_oauth_state_cookie(response, request, state) + return response # ------------------------------ @@ -987,11 +1448,15 @@ async def _build_oauth_protected_resource_response( """ Build OAuth protected resource response with the appropriate URL pattern. - For pass-through MCP servers (``MCPServer.is_oauth_passthrough``), the - gateway proxies the upstream's own ``oauth-protected-resource`` metadata - so that standards-compliant MCP clients discover the **upstream** IdP - instead of the gateway. The ``resource`` field is rewritten to the - gateway's own URL so clients present the bearer token back to the gateway. + For pass-through MCP servers, the gateway proxies the upstream's own + ``oauth-protected-resource`` metadata so standards-compliant MCP clients + discover the **upstream** IdP instead of the gateway. For ``true_passthrough`` + and ``oauth_delegate`` the metadata is returned verbatim (``resource`` stays + the upstream): the caller's token is forwarded to and validated by the + upstream, so its audience must be the upstream — rewriting it to the gateway + would make a strict IdP (e.g. Entra) refuse to mint it or the upstream reject + it. Only the legacy ``is_oauth_passthrough`` opt-in rewrites ``resource`` to + the gateway's own URL so clients present the bearer token back to the gateway. Args: request: FastAPI Request object @@ -1030,9 +1495,18 @@ async def _build_oauth_protected_resource_response( else: resource_url = f"{request_base_url}/mcp" + if mcp_server is not None and mcp_server_name and mcp_server.is_dcr_bridge: + return { + "authorization_servers": [f"{request_base_url}/{mcp_server_name}"], + "resource": resource_url, + "scopes_supported": (mcp_server.scopes if mcp_server.scopes else []), + } + # Pass-through branch: proxy the upstream's own metadata so discovery # directs the client at the real IdP (Okta, Keycloak, …) instead of us. - if mcp_server is not None and mcp_server.is_oauth_passthrough: + if mcp_server is not None and ( + mcp_server.is_oauth_passthrough or mcp_server.is_oauth_delegate or mcp_server.is_true_passthrough + ): try: upstream_metadata = await fetch_upstream_oauth_protected_resource(mcp_server) except Exception as exc: @@ -1048,8 +1522,9 @@ async def _build_oauth_protected_resource_response( ) if upstream_metadata is not None: - response = {**upstream_metadata, "resource": resource_url} - return response + if mcp_server.is_true_passthrough or mcp_server.is_oauth_delegate: + return upstream_metadata + return {**upstream_metadata, "resource": resource_url} # Upstream responded but with non-200 or non-dict payload. For # pass-through servers the gateway is NOT the authorization server, @@ -1063,6 +1538,15 @@ async def _build_oauth_protected_resource_response( detail=(f"Upstream oauth-protected-resource metadata unavailable for MCP server {mcp_server.name!r}"), ) + obo_response = _obo_protected_resource_response(mcp_server, resource_url) + if obo_response is not None: + return obo_response + + # An OBO server with no configured issuer falls through to the gateway default so discovery still + # returns metadata; every other non-oauth2 named server 404s to avoid enumeration. + if mcp_server is None or mcp_server.auth_type != MCPAuth.oauth2_token_exchange: + _raise_unless_oauth2_discovery_server(mcp_server, mcp_server_name, "not an OAuth-protected resource") + return { "authorization_servers": [ (f"{request_base_url}/{mcp_server_name}" if mcp_server_name else f"{request_base_url}") @@ -1072,6 +1556,51 @@ async def _build_oauth_protected_resource_response( } +def _obo_protected_resource_response(mcp_server: Optional[MCPServer], resource_url: str) -> Optional[dict]: + """The OBO (token_exchange) PRM, or None when this server is not OBO / no issuer is configured. + + The client SSOs with the IdP to obtain a subject token, which LiteLLM then exchanges, so discovery + points at the JWT-auth issuer(s) LiteLLM trusts (the same IdP that issues and validates the + subject), not the gateway. None falls the caller back to the gateway default so discovery still + returns metadata; it just can't name the IdP. + """ + if mcp_server is None or mcp_server.auth_type != MCPAuth.oauth2_token_exchange: + return None + issuers = _jwt_auth_issuers() + if not issuers: + return None + return { + "authorization_servers": issuers, + "resource": resource_url, + "scopes_supported": (mcp_server.scopes if mcp_server.scopes else []), + } + + +def _jwt_auth_issuers() -> list: + """The OAuth issuer identifier(s) LiteLLM's JWT auth trusts, for the OBO PRM authorization_servers. + + In token_exchange the IdP that issues the subject JWT is the same one LiteLLM validates it + against, so OBO discovery points clients at the JWT-auth issuer to obtain a subject token. + Sourced from ``JWT_ISSUER`` and any configured ``litellm_jwtauth.issuers``. + """ + import os # noqa: PLC0415 + + from litellm.proxy.proxy_server import general_settings # noqa: PLC0415 + + issuers: list = [] + env_issuer = os.getenv("JWT_ISSUER") + if env_issuer: + issuers.append(env_issuer) + + jwtauth = general_settings.get("litellm_jwtauth") if isinstance(general_settings, dict) else None + raw_issuers = jwtauth.get("issuers") if isinstance(jwtauth, dict) else getattr(jwtauth, "issuers", None) + for cfg in raw_issuers or []: + issuer = cfg.get("issuer") if isinstance(cfg, dict) else getattr(cfg, "issuer", None) + if issuer and issuer not in issuers: + issuers.append(issuer) + return issuers + + # Standard MCP pattern: /.well-known/oauth-protected-resource/mcp/{server_name} # This is the pattern expected by standard MCP clients (mcp-inspector, VSCode Copilot) @router.get( @@ -1149,6 +1678,8 @@ def _build_oauth_authorization_server_response( if mcp_server_name: mcp_server = global_mcp_server_manager.get_mcp_server_by_name(mcp_server_name, client_ip=client_ip) + _raise_unless_oauth2_discovery_server(mcp_server, mcp_server_name, "not an OAuth authorization server") + return { "issuer": request_base_url, # point to your proxy "authorization_endpoint": authorization_endpoint, @@ -1300,6 +1831,7 @@ async def register_client(request: Request, mcp_server_name: Optional[str] = Non response_types=data.get("response_types", []), token_endpoint_auth_method=data.get("token_endpoint_auth_method", ""), fallback_client_id=resolved.server_name or resolved.name, + client_redirect_uris=data.get("redirect_uris"), ) return dummy_return @@ -1314,4 +1846,5 @@ async def register_client(request: Request, mcp_server_name: Optional[str] = Non response_types=data.get("response_types", []), token_endpoint_auth_method=data.get("token_endpoint_auth_method", ""), fallback_client_id=mcp_server_name, + client_redirect_uris=data.get("redirect_uris"), ) diff --git a/litellm/proxy/_experimental/mcp_server/exceptions.py b/litellm/proxy/_experimental/mcp_server/exceptions.py index b3f7ca9bbe2..3e3e549008d 100644 --- a/litellm/proxy/_experimental/mcp_server/exceptions.py +++ b/litellm/proxy/_experimental/mcp_server/exceptions.py @@ -73,3 +73,18 @@ class MCPUpstreamAuthError(Exception): detail=detail, headers={"www-authenticate": challenge} if challenge else None, ) + + +class MCPToolResultError(Exception): + """An MCP tool call completed with ``isError=True`` in its result. + + Never raised on the wire path: streamable HTTP MCP correctly returns tool + failures as HTTP 200 with ``result.isError: true`` per the MCP spec. This + exception only drives the standard failure logging (``status="failure"`` + payload, OTel ERROR span) for such results. + + Lives here rather than ``utils.py`` deliberately: tests reload ``utils`` + to re-read its env-derived constants, and a reload would fork this class + into two identities, breaking ``isinstance`` checks against instances + created before the reload. + """ diff --git a/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py b/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py index b6760e58852..1d681b43b9e 100644 --- a/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py +++ b/litellm/proxy/_experimental/mcp_server/mcp_server_manager.py @@ -13,10 +13,12 @@ import json import os import re import time -from typing import Any, Callable, Dict, List, Literal, Optional, Set, Tuple, Union, cast +from contextlib import asynccontextmanager +from typing import Any, AsyncIterator, Callable, Literal, Optional, Union, cast from urllib.parse import urlparse import anyio +import httpx from fastapi import HTTPException from httpx import HTTPStatusError from mcp import ReadResourceResult, Resource @@ -55,7 +57,11 @@ from litellm.proxy._experimental.mcp_server.elicitation_handler import ( from litellm.proxy._experimental.mcp_server.sampling_handler import ( MCP_SAMPLING_AVAILABLE, ) -from litellm.proxy._experimental.mcp_server.oauth2_token_cache import resolve_mcp_auth +from litellm.proxy._experimental.mcp_server.oauth2_token_cache import ( + MCPPerUserTokenCache, + mcp_per_user_token_cache, + resolve_mcp_auth, +) from litellm.proxy._experimental.mcp_server.outbound_credentials import ( Error, Ok, @@ -63,15 +69,25 @@ from litellm.proxy._experimental.mcp_server.outbound_credentials import ( ) from litellm.proxy._experimental.mcp_server.outbound_credentials.adapter import ( raise_public, + raise_token_exchange_challenge, raise_user_oauth_challenge, to_server_spec, to_subject, ) +from litellm.proxy._experimental.mcp_server.outbound_credentials.oauth_token_store import ( + InvalidatableOAuthTokenStore, +) from litellm.proxy._experimental.mcp_server.outbound_credentials.per_user_oauth_store import ( LazyPerUserOAuthTokenStore, ) +from litellm.proxy._experimental.mcp_server.outbound_credentials.token_exchange_provider import ( + build_token_exchanger, +) from litellm.proxy._experimental.mcp_server.outbound_credentials.types import ( AuthorizationCodeConfig, + PassthroughConfig, + ServerSpec, + TokenExchangeConfig, ) from litellm.proxy._experimental.mcp_server.utils import ( MCP_TOOL_PREFIX_SEPARATOR, @@ -104,10 +120,10 @@ from litellm.proxy._types import ( from litellm.proxy.auth.ip_address_utils import IPAddressUtils from litellm.proxy.common_utils.encrypt_decrypt_utils import decrypt_value_helper from litellm.proxy.common_utils.user_api_key_cache import get_management_object_ttl -from litellm.proxy.utils import ProxyLogging +from litellm.proxy.utils import ProxyLogging, get_server_root_path from litellm.repositories.table_repositories import MCPServerRepository from litellm.types.llms.custom_http import httpxSpecialProvider -from litellm.types.mcp import MCPAuth, MCPStdioConfig +from litellm.types.mcp import DEFAULT_SUBJECT_TOKEN_TYPE, MCPAuth, MCPStdioConfig from litellm.types.mcp_server.mcp_server_manager import ( MCPInfo, MCPOAuthMetadata, @@ -155,10 +171,20 @@ _AZURE_ENTRA_HOSTS = { # BYOK credential cache. Keyed by (user_id, server_id); value is # (values_dict, monotonic_timestamp). Keeps the tool-call and tool-listing # paths off the DB on every request within the TTL window. -_user_env_vars_cache: Dict[Tuple[str, str], Tuple[Dict[str, str], float]] = {} +_user_env_vars_cache: dict[tuple[str, str], tuple[dict[str, str], float]] = {} _USER_ENV_VARS_CACHE_TTL = 60 # seconds _USER_ENV_VARS_CACHE_MAX_SIZE = 4096 # cap to prevent unbounded growth +# Auth types whose upstream OAuth endpoints (protected-resource + authorization-server metadata) the +# gateway discovers from the upstream itself: interactive oauth2 and the two client-forwarded modes. +# OBO/M2M endpoint discovery is decided separately via _obo_needs_endpoint_discovery. Shared by the +# config-YAML and DB server loaders so the two paths cannot drift on which modes trigger discovery. +_UPSTREAM_OAUTH_DISCOVERY_AUTH_TYPES: tuple[MCPAuth, ...] = ( + MCPAuth.oauth2, + MCPAuth.true_passthrough, + MCPAuth.oauth_delegate, +) + def invalidate_user_env_vars_cache(user_id: str, server_id: str) -> None: """Drop a cached entry after the user stores or clears their env var values @@ -166,7 +192,7 @@ def invalidate_user_env_vars_cache(user_id: str, server_id: str) -> None: _user_env_vars_cache.pop((user_id, server_id), None) -def _write_user_env_vars_cache(user_id: str, server_id: str, values: Dict[str, str]) -> None: +def _write_user_env_vars_cache(user_id: str, server_id: str, values: dict[str, str]) -> None: cache_key = (user_id, server_id) # Re-insert at the tail so eviction drops the oldest-written entry, not a # freshly refreshed one, and only sheds a single entry instead of wiping the @@ -179,7 +205,7 @@ def _write_user_env_vars_cache(user_id: str, server_id: str, values: Dict[str, s def _should_strip_caller_authorization( mcp_server: MCPServer, - raw_headers: Optional[Dict[str, str]], + raw_headers: Optional[dict[str, str]], user_api_key_auth: Optional[UserAPIKeyAuth], ) -> bool: """Decide whether the caller's ``Authorization`` header must NOT be @@ -205,7 +231,18 @@ def _should_strip_caller_authorization( pass-through cold-start case (RFC 9728) the bearer in ``Authorization`` is the upstream OAuth token and must be forwarded, so we keep it. + - **oauth_delegate servers**: admission always runs and there is no + anonymous path, so the caller's separate ``Authorization`` is + forwarded only when a distinct ``x-litellm-api-key`` carried + admission. Without that header the ``Authorization`` *was* the + admission credential — a virtual key, an IdP JWT, or an SSO / OIDC / + session token whose ``api_key`` is ``None`` — and must never reach + the upstream, so it is stripped regardless of the ``api_key`` value. """ + if mcp_server.auth_type == MCPAuth.oauth2_token_exchange: + # OBO: the inbound Authorization is the subject token. It is exchanged at the IdP and only the + # exchanged token is sent upstream, so the raw caller bearer must never be forwarded. + return True if mcp_server.has_client_credentials: return True if mcp_server.auth_type == MCPAuth.oauth2 and to_server_spec(mcp_server) is not None: @@ -214,11 +251,13 @@ def _should_strip_caller_authorization( # upstream — it would override another user's stored credential. Delegate and # pass-through return None from to_server_spec and keep forwarding the bearer. return True - if not mcp_server.is_oauth_passthrough: + if not (mcp_server.is_oauth_passthrough or mcp_server.is_oauth_delegate): return False normalized_raw_headers = {str(k).lower(): v for k, v in (raw_headers or {}).items() if isinstance(k, str)} has_explicit_litellm_admission_header = normalized_raw_headers.get("x-litellm-api-key") is not None + if mcp_server.is_oauth_delegate: + return not has_explicit_litellm_admission_header admission_consumed_authorization_as_litellm_key = ( user_api_key_auth is not None and bool(getattr(user_api_key_auth, "api_key", None)) @@ -241,9 +280,162 @@ def _without_authorization( return filtered or None +def _format_byok_openapi_auth_header(mcp_server: MCPServer, mcp_auth_header: str) -> str: + """Format a raw BYOK credential for OpenAPI tool ``Authorization`` injection.""" + if mcp_server.auth_type == MCPAuth.api_key: + return f"ApiKey {mcp_auth_header}" + if mcp_server.auth_type == MCPAuth.basic: + return f"Basic {mcp_auth_header}" + return f"Bearer {mcp_auth_header}" + + +def _openapi_forwarded_extra_headers( + mcp_server: MCPServer, + raw_headers: Optional[dict[str, str]], + user_api_key_auth: Optional[UserAPIKeyAuth], +) -> Optional[dict[str, str]]: + if not mcp_server.extra_headers or not raw_headers: + return None + normalized_raw = {str(k).lower(): v for k, v in raw_headers.items() if isinstance(k, str)} + skip_caller_authorization = _should_strip_caller_authorization( + mcp_server=mcp_server, + raw_headers=raw_headers, + user_api_key_auth=user_api_key_auth, + ) + forwarded: dict[str, str] = {} + for header_name in mcp_server.extra_headers: + if not isinstance(header_name, str): + continue + if skip_caller_authorization and header_name.lower() == "authorization": + continue + value = normalized_raw.get(header_name.lower()) + if value is not None: + forwarded[header_name] = value + return forwarded or None + + +async def _resolve_byok_mcp_auth_header( + mcp_server: MCPServer, + user_api_key_auth: Optional[UserAPIKeyAuth], + mcp_auth_header: Optional[str], +) -> Optional[str]: + """Resolve BYOK credential for tool calls that bypass ``execute_mcp_tool``.""" + if not mcp_server.is_byok: + return mcp_auth_header + + from litellm.proxy._experimental.mcp_server.server import ( + _check_byok_credential, + _get_byok_credential, + ) + + if not mcp_auth_header: + byok_cred = await _get_byok_credential(mcp_server, user_api_key_auth) + if byok_cred is None: + raise HTTPException( + status_code=401, + detail={ + "error": "byok_auth_required", + "server_id": mcp_server.server_id, + "server_name": mcp_server.server_name or mcp_server.name, + "message": ( + "No stored credential found for this BYOK server. " + "Complete the OAuth authorization flow to provide your API key." + ), + }, + headers={"WWW-Authenticate": 'Bearer resource_metadata="/.well-known/oauth-protected-resource"'}, + ) + return byok_cred + + await _check_byok_credential(mcp_server, user_api_key_auth) + return mcp_auth_header + + +def _client_forwarded_authorization_headers( + mcp_server: MCPServer, + oauth2_headers: Optional[dict[str, str]], + raw_headers: Optional[dict[str, str]], + user_api_key_auth: Optional[UserAPIKeyAuth], +) -> Optional[dict[str, str]]: + """Egress headers for the client-forwarded-token modes (``true_passthrough`` / ``oauth_delegate``). + + Forwards the caller's ``Authorization`` to the upstream, stripped when + ``_should_strip_caller_authorization`` says it was consumed as the LiteLLM admission key. Shared by + ``_call_regular_mcp_tool`` and ``server.py``'s ``_prepare_mcp_server_headers`` so the two egress + paths cannot drift, mirroring the ``_should_strip_caller_authorization`` split. + """ + extra_headers = oauth2_headers.copy() if oauth2_headers else None + if extra_headers and _should_strip_caller_authorization( + mcp_server=mcp_server, + raw_headers=raw_headers, + user_api_key_auth=user_api_key_auth, + ): + return _without_authorization(extra_headers) + return extra_headers + + +def _take_forwarded_authorization( + headers: Optional[dict[str, str]], +) -> tuple[Optional[str], Optional[dict[str, str]]]: + """Pop the ``Authorization`` value out of ``headers`` (case-insensitive), returning it with the + remaining headers, so the passthrough resolver arm is the single Authorization source rather than + the header also riding in ``extra_headers`` (which the resolved auth would then defer to).""" + if not headers: + return None, headers + value = next((v for k, v in headers.items() if k.lower() == "authorization"), None) + return value, _without_authorization(headers) + + +def _passthrough_token_from_mcp_auth_header( + mcp_auth_header: Optional[Union[str, dict[str, str]]], +) -> Optional[str]: + """The caller's per-server upstream credential for a passthrough-mode server, or None. + + Sourced from ``x-mcp-{alias}-authorization`` (string or per-header dict form) or the deprecated + global ``x-mcp-auth`` fallback. Per-server headers are the multi-server shape: they bind one + token to one server, so an aggregate scope with several passthrough-mode servers never replays + a single credential across upstreams. The value is forwarded verbatim, so it must be the full + header value (e.g. ``Bearer ``).""" + if isinstance(mcp_auth_header, str): + return mcp_auth_header or None + if isinstance(mcp_auth_header, dict): + return next((v for k, v in mcp_auth_header.items() if k.lower() == "authorization"), None) + return None + + +def _consumes_caller_authorization(server: MCPServer) -> bool: + """True when this server's egress forwards the caller's request-wide ``Authorization`` upstream: + the client-forwarded token modes, legacy OAuth pass-through, and legacy upstream-delegated + interactive oauth2. An unstamped oauth2 row (flow column not yet backfilled) reads as a consumer, + which errs toward suppression — the fail-safe direction.""" + if server.is_true_passthrough or server.is_oauth_delegate or server.is_oauth_passthrough: + return True + return ( + server.auth_type == MCPAuth.oauth2 + and getattr(server, "delegate_auth_to_upstream", False) is True + and not server.has_client_credentials + ) + + +def _caller_authorization_fans_out( + server: MCPServer, + scope_servers: Optional[list[MCPServer]], +) -> bool: + """True when forwarding the caller's request-wide ``Authorization`` to ``server`` inside a + listing fan-out would replay one credential against multiple upstreams: another server in the + scope also consumes it (RFC 9700 cross-resource replay). ``scope_servers`` is None for + explicitly-addressed operations (tool call, get_prompt, read_resource, single-server routes), + where the client named the one target and the gateway is not choosing recipients.""" + if scope_servers is None: + return False + return any( + other is not None and other.server_id != server.server_id and _consumes_caller_authorization(other) + for other in scope_servers + ) + + def _extract_upstream_auth_failure( exc: BaseException, -) -> Optional[Tuple[int, Optional[str]]]: +) -> Optional[tuple[int, Optional[str]]]: """Walk the exception tree looking for an HTTP 401/403 response from the upstream MCP server. @@ -255,8 +447,8 @@ def _extract_upstream_auth_failure( Returns ``(status_code, www_authenticate)`` on match, else ``None``. """ - seen: Set[int] = set() - stack: List[BaseException] = [exc] + seen: set[int] = set() + stack: list[BaseException] = [exc] while stack: current = stack.pop() if id(current) in seen: @@ -337,7 +529,7 @@ def _warn_internal_delegate_pkce_if_applicable(server: MCPServer, *, source: str ) -def _deserialize_json_dict(data: Any) -> Optional[Dict[str, str]]: +def _deserialize_json_dict(data: Any) -> Optional[dict[str, str]]: """ Deserialize optional JSON mappings stored in the database. @@ -358,7 +550,7 @@ def _deserialize_json_dict(data: Any) -> Optional[Dict[str, str]]: return data -def _deserialize_json_list(data: Any) -> Optional[List[Dict[str, Any]]]: +def _deserialize_json_list(data: Any) -> Optional[list[dict[str, Any]]]: """Deserialize a JSON array stored in the DB (``env_vars`` and friends). Returns ``None`` for empty / null / unparseable input. Accepts strings @@ -499,6 +691,21 @@ def _create_elicitation_callback(): class MCPServerManager: _STDIO_ENV_TEMPLATE_PATTERN = re.compile(r"^\$\{(X-[^}]+)\}$") + @staticmethod + def _explicit_oauth2_flow( + oauth2_flow: Optional[str], + ) -> Optional[Literal["client_credentials", "authorization_code"]]: + """DB rows persist their flow (write-time stamps plus the startup backfill) and + config servers must declare it (validated at load), so both builds read the + value verbatim: unknown or null resolves to None, which + ``needs_user_oauth_token`` already treats as interactive. Field-shape inference + survives only in the request-time security helpers (``effective_oauth2_flow`` / + ``resolve_oauth2_flow_for_request``). + """ + if oauth2_flow in ("client_credentials", "authorization_code"): + return cast(Literal["client_credentials", "authorization_code"], oauth2_flow) + return None + @staticmethod def _resolve_oauth2_flow( *, @@ -509,11 +716,18 @@ class MCPServerManager: client_id: Optional[str], client_secret: Optional[str], ) -> Optional[Literal["client_credentials", "authorization_code"]]: - """Infer oauth2_flow for legacy records that omit the field. + """Infer oauth2_flow from field shape when the value is omitted. - DB rows created before oauth2_flow support may have OAuth2 client - credentials + token_url but a null oauth2_flow. Treat these as M2M, - unless authorization_url is present (interactive OAuth). + SECURITY-SENSITIVE: this is the shape-inference engine both request-time security + helpers delegate to, so it is what decides M2M-vs-interactive for an unstamped row. + Always access it through ``effective_oauth2_flow`` (boolean/enum decisions) or + ``resolve_oauth2_flow_for_request`` (the egress object backstop), which are the single + choke points for request-time resolution; do not call it directly from security sites + and do not weaken its M2M-shape branch without accounting for those callers. DB rows + are stamped at write time and by the startup backfill, config servers must declare + oauth2_flow (validated at load), and both builds read the value verbatim via + ``_explicit_oauth2_flow``. Delete this whole request-time layer only once the backstop + warning stays silent in production. """ if oauth2_flow in ("client_credentials", "authorization_code"): return cast(Literal["client_credentials", "authorization_code"], oauth2_flow) @@ -528,12 +742,79 @@ class MCPServerManager: return "client_credentials" return None - def __init__(self, cred_provider: Optional[UpstreamCredentialProvider] = None): - self._cred_provider = cred_provider or UpstreamCredentialProvider( - oauth_token_store=LazyPerUserOAuthTokenStore(self.get_mcp_server_by_id) + @staticmethod + def effective_oauth2_flow(server: "MCPServer") -> Optional[Literal["client_credentials", "authorization_code"]]: + """The oauth2_flow a security decision must use for ``server`` this request. + + Column-first, shape-fallback: a stamped row returns its explicit value; an + unstamped (null) row whose fields carry the M2M shape resolves to + ``client_credentials`` so it is treated as M2M and fails closed. Every + security-sensitive reader (anonymous-delegate allowlist and gate, egress flow + resolution) goes through this one helper rather than reading the bare + ``has_client_credentials`` column, which is unreliable for null rows. + """ + return MCPServerManager._resolve_oauth2_flow( + auth_type=server.auth_type, + oauth2_flow=server.oauth2_flow, + token_url=server.token_url, + authorization_url=server.authorization_url, + client_id=server.client_id, + client_secret=server.client_secret, ) - self.registry: Dict[str, MCPServer] = {} - self.config_mcp_servers: Dict[str, MCPServer] = {} + + @staticmethod + def resolve_oauth2_flow_for_request(server: "MCPServer") -> "MCPServer": + """Return ``server`` with its effective oauth2_flow applied, for egress paths. + + A stamped row is returned unchanged (its effective flow equals the stored value). + An unstamped M2M-shape row is returned as a per-request copy carrying + ``oauth2_flow=client_credentials`` so downstream ``has_client_credentials`` / + ``needs_user_oauth_token`` compute correctly and the stored client credentials are + used instead of forwarding the caller's Authorization. Use this at every point that + resolves an allowed server id into an ``MCPServer`` for a tool call or listing. + """ + effective = MCPServerManager.effective_oauth2_flow(server) + if effective is None or effective == server.oauth2_flow: + return server + verbose_logger.warning( + "MCP server %s has no persisted oauth2_flow but matches the %s shape; using the " + "inferred flow for this request. The startup backfill leaves this ambiguous M2M " + "shape unstamped on purpose, so it will NOT self-heal: set oauth2_flow explicitly " + "in the dashboard or via PUT /v1/mcp/server (client_credentials for M2M, or " + "authorization_code after an interactive sign-in).", + server.server_id, + effective, + ) + return server.model_copy(update={"oauth2_flow": effective}) + + @staticmethod + def _obo_needs_endpoint_discovery( + auth_type: Optional[MCPAuthType], + token_exchange_endpoint: Optional[str], + token_url: Optional[str], + ) -> bool: + """An ``oauth2_token_exchange`` server with no configured token endpoint can have it + discovered (RFC 9728 -> RFC 8414) the same way the ``oauth2`` flow already does; an explicitly + configured ``token_exchange_endpoint``/``token_url`` wins and skips the discovery round-trip. + """ + return auth_type == MCPAuth.oauth2_token_exchange and not (token_exchange_endpoint or token_url) + + def __init__( + self, + cred_provider: Optional[UpstreamCredentialProvider] = None, + per_user_oauth_token_store: Optional[InvalidatableOAuthTokenStore] = None, + per_user_token_cache: Optional[MCPPerUserTokenCache] = None, + ): + self._per_user_oauth_token_store = per_user_oauth_token_store or LazyPerUserOAuthTokenStore( + self.get_mcp_server_by_id + ) + self._per_user_token_cache = per_user_token_cache or mcp_per_user_token_cache + self._cred_provider = cred_provider or UpstreamCredentialProvider( + oauth_token_store=self._per_user_oauth_token_store, + token_exchanger=build_token_exchanger(), + ) + self.registry: dict[str, MCPServer] = {} + self.config_mcp_servers: dict[str, MCPServer] = {} """ eg. [ @@ -550,17 +831,24 @@ class MCPServerManager: ] """ - self.tool_name_to_mcp_server_name_mapping: Dict[str, str] = {} + # Per-server outbound tool-call concurrency limiters, lazily created from + # each server's max_concurrent_requests. Keyed by server_id so the cap + # survives the registry atomic-swap on config reload; a missing key means + # the server has no configured limit. The limit is cached alongside the + # semaphore so an edited limit rebuilds it instead of keeping the old cap + # until restart. + self._server_call_semaphores: dict[str, tuple[int, asyncio.Semaphore]] = {} + self.tool_name_to_mcp_server_name_mapping: dict[str, str] = {} """ { "gmail_send_email": "zapier_mcp_server", } """ - self._upstream_initialize_instructions_by_server_id: Dict[str, str] = {} + self._upstream_initialize_instructions_by_server_id: dict[str, str] = {} # Per-server monotonic timestamp of last upstream prefetch attempt (success, # empty result, or failure). Used to throttle re-probes for servers that do # not return instructions, and to apply a short cooldown after failures. - self._upstream_initialize_instructions_probed_at: Dict[str, float] = {} + self._upstream_initialize_instructions_probed_at: dict[str, float] = {} def _remember_upstream_initialize_instructions(self, server: MCPServer, client: MCPClient) -> None: raw = getattr(client, "_last_initialize_instructions", None) @@ -616,7 +904,7 @@ class MCPServerManager: user_api_key_auth=None, raise_on_missing=False, ) - extra_headers: Optional[Dict[str, str]] = dict(resolved_static_headers) if resolved_static_headers else None + extra_headers: Optional[dict[str, str]] = dict(resolved_static_headers) if resolved_static_headers else None client = await self._create_mcp_client( server=server, mcp_auth_header=None, @@ -636,7 +924,7 @@ class MCPServerManager: e, ) - def get_registry(self) -> Dict[str, MCPServer]: + def get_registry(self) -> dict[str, MCPServer]: """ Get the registered MCP Servers from the registry and union with the config MCP Servers """ @@ -644,8 +932,8 @@ class MCPServerManager: async def load_servers_from_config( self, - mcp_servers_config: Dict[str, Any], - mcp_aliases: Optional[Dict[str, str]] = None, + mcp_servers_config: dict[str, Any], + mcp_aliases: Optional[dict[str, str]] = None, ): """ Load the MCP Servers from the config @@ -663,7 +951,7 @@ class MCPServerManager: for server_name, server_config in mcp_servers_config.items(): validate_mcp_server_name(server_name) - _mcp_info: Dict[str, Any] = server_config.get("mcp_info", None) or {} + _mcp_info: dict[str, Any] = server_config.get("mcp_info", None) or {} # Preserve all custom fields from config while setting defaults for core fields mcp_info: MCPInfo = _mcp_info.copy() # Set default values for core fields if not present @@ -711,14 +999,27 @@ class MCPServerManager: ) auth_type = server_config.get("auth_type", None) - if server_url and auth_type is not None and auth_type == MCPAuth.oauth2: + if server_url and ( + auth_type in _UPSTREAM_OAUTH_DISCOVERY_AUTH_TYPES + or self._obo_needs_endpoint_discovery( + auth_type, + server_config.get("token_exchange_endpoint"), + server_config.get("token_url"), + ) + ): mcp_oauth_metadata = await self._descovery_metadata( server_url=server_url, + allow_origin_fallback=auth_type in _UPSTREAM_OAUTH_DISCOVERY_AUTH_TYPES, ) else: mcp_oauth_metadata = None - resolved_scopes = server_config.get("scopes") or (mcp_oauth_metadata.scopes if mcp_oauth_metadata else None) + # Filter blank scopes (e.g. YAML ``scopes: [""]``) the same way the DB-build path does, so + # an all-blank list normalizes to None rather than a ``("",)`` tuple that skips the + # entra_obo fail-closed scope precondition and POSTs an empty scope to the IdP. + resolved_scopes = self._extract_scopes(server_config.get("scopes")) or ( + mcp_oauth_metadata.scopes if mcp_oauth_metadata else None + ) resolved_authorization_url = server_config.get("authorization_url") or ( mcp_oauth_metadata.authorization_url if mcp_oauth_metadata else None ) @@ -729,6 +1030,38 @@ class MCPServerManager: mcp_oauth_metadata.registration_url if mcp_oauth_metadata else None ) + config_oauth2_flow = server_config.get("oauth2_flow", None) + if auth_type == MCPAuth.oauth2 and config_oauth2_flow not in ( + "client_credentials", + "authorization_code", + ): + raise ValueError( + f"Invalid config for MCP server '{server_name or server_id}': auth_type oauth2 " + f"requires an explicit oauth2_flow (got {config_oauth2_flow!r}). Set " + "oauth2_flow: client_credentials for machine-to-machine servers (the proxy mints " + "a shared token at token_url using client_id/client_secret, no user interaction) " + "or oauth2_flow: authorization_code for interactive servers (per-user tokens via " + "browser sign-in, including delegate_auth_to_upstream)." + ) + + config_dcr_bridge = server_config.get("dcr_bridge", None) + if config_dcr_bridge is not None and not isinstance(config_dcr_bridge, bool): + raise ValueError( + f"Invalid config for MCP server '{server_name or server_id}': dcr_bridge " + f"must be a boolean (got {config_dcr_bridge!r})." + ) + if config_dcr_bridge and auth_type not in ( + MCPAuth.true_passthrough, + MCPAuth.oauth_delegate, + ): + raise ValueError( + f"Invalid config for MCP server '{server_name or server_id}': dcr_bridge is only " + f"supported for auth_type true_passthrough or oauth_delegate (got {auth_type!r}). " + "The DCR bridge serves gateway-hosted OAuth discovery for the client-forwarded " + "token modes; interactive oauth2 servers already run the gateway " + "authorization-code flow." + ) + new_server = MCPServer( server_id=server_id, name=name_for_prefix, @@ -742,14 +1075,7 @@ class MCPServerManager: # oauth specific fields client_id=server_config.get("client_id", None), client_secret=server_config.get("client_secret", None), - oauth2_flow=self._resolve_oauth2_flow( - auth_type=auth_type, - oauth2_flow=server_config.get("oauth2_flow", None), - token_url=resolved_token_url, - authorization_url=resolved_authorization_url, - client_id=server_config.get("client_id", None), - client_secret=server_config.get("client_secret", None), - ), + oauth2_flow=self._explicit_oauth2_flow(config_oauth2_flow), scopes=resolved_scopes, authorization_url=resolved_authorization_url, token_url=resolved_token_url, @@ -771,6 +1097,7 @@ class MCPServerManager: available_on_public_internet=bool(server_config.get("available_on_public_internet", True)), delegate_auth_to_upstream=bool(server_config.get("delegate_auth_to_upstream", False)), oauth_passthrough=bool(server_config.get("oauth_passthrough", False)), + dcr_bridge=config_dcr_bridge, # AWS SigV4 fields aws_access_key_id=server_config.get("aws_access_key_id", None), aws_secret_access_key=server_config.get("aws_secret_access_key", None), @@ -785,11 +1112,13 @@ class MCPServerManager: audience=server_config.get("audience", None), subject_token_type=server_config.get( "subject_token_type", - "urn:ietf:params:oauth:token-type:access_token", + DEFAULT_SUBJECT_TOKEN_TYPE, ), + token_exchange_profile=server_config.get("token_exchange_profile", "rfc8693"), allow_sampling=bool(server_config.get("allow_sampling", False)), allow_elicitation=bool(server_config.get("allow_elicitation", False)), timeout=server_config.get("timeout", None), + max_concurrent_requests=server_config.get("max_concurrent_requests", None), ) self._assign_unique_short_prefix(new_server) _warn_internal_delegate_pkce_if_applicable(new_server, source="config") @@ -851,7 +1180,7 @@ class MCPServerManager: server_prefix = get_server_prefix(server) # Build headers from server configuration - headers: Dict[str, str] = {} + headers: dict[str, str] = {} # Add authentication headers if configured if server.authentication_token: @@ -961,7 +1290,7 @@ class MCPServerManager: openapi_key_prefix = prefix_root + MCP_TOOL_PREFIX_SEPARATOR global_mcp_tool_registry.unregister_tools_with_prefix(openapi_key_prefix) - owned_raw: Set[str] = set() + owned_raw: set[str] = set() for p in iter_known_server_prefixes(server): if p: owned_raw.add(p) @@ -970,7 +1299,7 @@ class MCPServerManager: owned_normalized = {normalize_server_name(x) for x in owned_raw} - stale_mapping_keys: List[str] = [] + stale_mapping_keys: list[str] = [] for tool_name, mapped_server in list(self.tool_name_to_mcp_server_name_mapping.items()): if mapped_server in owned_raw: stale_mapping_keys.append(tool_name) @@ -998,7 +1327,7 @@ class MCPServerManager: mcp_server: LiteLLM_MCPServerTable, *, env_vars_are_encrypted: bool, - ) -> Optional[List[Dict[str, Any]]]: + ) -> Optional[list[dict[str, Any]]]: env_vars_list = _deserialize_json_list(getattr(mcp_server, "env_vars", None)) if env_vars_are_encrypted: from litellm.proxy._experimental.mcp_server.db import ( # noqa: PLC0415 @@ -1073,7 +1402,7 @@ class MCPServerManager: # AWS SigV4 credential fields aws_creds = self._extract_aws_credentials(credentials_dict, credentials_are_encrypted) - scopes: Optional[List[str]] = None + scopes: Optional[list[str]] = None if credentials_dict: scopes_value = credentials_dict.get("scopes") if scopes_value is not None: @@ -1090,9 +1419,20 @@ class MCPServerManager: auth_type = cast(MCPAuthType, mcp_server.auth_type) server_url = mcp_server.url - needs_discovery = bool(server_url) and auth_type == MCPAuth.oauth2 and not mcp_server.authorization_url + needs_discovery = bool(server_url) and ( + (auth_type in _UPSTREAM_OAUTH_DISCOVERY_AUTH_TYPES and not mcp_server.authorization_url) + or self._obo_needs_endpoint_discovery( + auth_type, + mcp_server.token_exchange_endpoint + or (credentials_dict.get("token_exchange_endpoint") if credentials_dict else None), + mcp_server.token_url, + ) + ) mcp_oauth_metadata = ( - await self._descovery_metadata(server_url=server_url) # type: ignore[arg-type] + await self._descovery_metadata( + server_url=server_url, # type: ignore[arg-type] + allow_origin_fallback=auth_type in _UPSTREAM_OAUTH_DISCOVERY_AUTH_TYPES, + ) if needs_discovery else None ) @@ -1115,15 +1455,7 @@ class MCPServerManager: env_vars=env_vars_list, client_id=client_id_value or getattr(mcp_server, "client_id", None), client_secret=client_secret_value or getattr(mcp_server, "client_secret", None), - oauth2_flow=self._resolve_oauth2_flow( - auth_type=auth_type, - oauth2_flow=getattr(mcp_server, "oauth2_flow", None), - token_url=mcp_server.token_url or getattr(mcp_oauth_metadata, "token_url", None), - authorization_url=mcp_server.authorization_url - or getattr(mcp_oauth_metadata, "authorization_url", None), - client_id=client_id_value or getattr(mcp_server, "client_id", None), - client_secret=client_secret_value or getattr(mcp_server, "client_secret", None), - ), + oauth2_flow=self._explicit_oauth2_flow(getattr(mcp_server, "oauth2_flow", None)), scopes=resolved_scopes, authorization_url=mcp_server.authorization_url or getattr(mcp_oauth_metadata, "authorization_url", None), token_url=mcp_server.token_url or getattr(mcp_oauth_metadata, "token_url", None), @@ -1141,6 +1473,7 @@ class MCPServerManager: available_on_public_internet=bool(getattr(mcp_server, "available_on_public_internet", True)), delegate_auth_to_upstream=bool(getattr(mcp_server, "delegate_auth_to_upstream", False)), oauth_passthrough=bool(getattr(mcp_server, "oauth_passthrough", False)), + dcr_bridge=getattr(mcp_server, "dcr_bridge", None), created_at=getattr(mcp_server, "created_at", None), updated_at=getattr(mcp_server, "updated_at", None), tool_name_to_display_name=_deserialize_json_dict(getattr(mcp_server, "tool_name_to_display_name", None)), @@ -1158,16 +1491,64 @@ class MCPServerManager: aws_role_name=aws_creds.get("aws_role_name"), aws_session_name=aws_creds.get("aws_session_name"), instructions=mcp_server.instructions, - # Token Exchange (OBO) fields — read from credentials JSON blob - token_exchange_endpoint=(credentials_dict.get("token_exchange_endpoint") if credentials_dict else None), - audience=(credentials_dict.get("audience") if credentials_dict else None), - subject_token_type=(credentials_dict.get("subject_token_type") if credentials_dict else None) - or "urn:ietf:params:oauth:token-type:access_token", + # Token exchange (OBO) fields: dedicated columns, with the credentials blob as a + # back-compat fallback for servers persisted before the columns existed. + token_exchange_endpoint=mcp_server.token_exchange_endpoint + or (credentials_dict.get("token_exchange_endpoint") if credentials_dict else None), + audience=mcp_server.audience or (credentials_dict.get("audience") if credentials_dict else None), + subject_token_type=mcp_server.subject_token_type + or (credentials_dict.get("subject_token_type") if credentials_dict else None) + or DEFAULT_SUBJECT_TOKEN_TYPE, + token_exchange_profile=mcp_server.token_exchange_profile + or (credentials_dict.get("token_exchange_profile") if credentials_dict else None) + or "rfc8693", timeout=getattr(mcp_server, "timeout", None), + max_concurrent_requests=getattr(mcp_server, "max_concurrent_requests", None), ) _warn_internal_delegate_pkce_if_applicable(new_server, source="database") + await self._persist_discovered_obo_token_url( + server_id=mcp_server.server_id, + auth_type=auth_type, + existing_token_url=mcp_server.token_url, + discovered_token_url=new_server.token_url, + ) return new_server + async def _persist_discovered_obo_token_url( + self, + *, + server_id: str, + auth_type: Optional[MCPAuthType], + existing_token_url: Optional[str], + discovered_token_url: Optional[str], + ) -> None: + """Write a freshly discovered OBO token endpoint back onto the DB row. + + ``build_mcp_server_from_table`` resolves ``token_url`` via RFC 9728 -> RFC 8414 for an + ``oauth2_token_exchange`` server that has none configured, but that resolved value otherwise + lives only on the returned in-memory object; the row keeps ``token_url=None`` so every rebuild + re-runs discovery, and a transient upstream outage during a rebuild leaves the server with no + endpoint until discovery next succeeds. Persisting it makes ``_obo_needs_endpoint_discovery`` + return False on the next build. Fires at most once per server (skipped once the row has a + value), and is best-effort: a write failure just means discovery runs again next time. + """ + if auth_type != MCPAuth.oauth2_token_exchange: + return + if existing_token_url or not discovered_token_url: + return + from litellm.proxy.proxy_server import prisma_client # noqa: PLC0415 + + if prisma_client is None: + return + try: + await MCPServerRepository(prisma_client).table.update( + where={"server_id": server_id}, + data={"token_url": discovered_token_url}, + ) + verbose_logger.debug("Persisted discovered OBO token_url for MCP server %s", server_id) + except Exception as exc: # noqa: BLE001 - best-effort; a failed write re-discovers next build + verbose_logger.warning("Failed to persist discovered OBO token_url for MCP server %s: %s", server_id, exc) + async def _maybe_register_openapi_tools(self, server: MCPServer, *, initialize_mapping: bool = True): """Register OpenAPI tools if the server has a spec_path configured.""" if server.spec_path: @@ -1235,18 +1616,79 @@ class MCPServerManager: verbose_logger.debug(f"Failed to udpate MCP server: {str(e)}") raise e - def get_all_mcp_server_ids(self) -> Set[str]: + def get_all_mcp_server_ids(self) -> set[str]: """ Get all MCP server IDs """ all_servers = list(self.get_registry().values()) return {server.server_id for server in all_servers} - def get_allow_all_keys_server_ids(self) -> List[str]: + def get_allow_all_keys_server_ids(self) -> list[str]: """Return server IDs that bypass per-key restrictions.""" return [server.server_id for server in self.get_registry().values() if server.allow_all_keys is True] - async def get_allowed_mcp_servers(self, user_api_key_auth: Optional[UserAPIKeyAuth] = None) -> List[str]: + @staticmethod + def get_byom_submitted_servers_cache_key(user_id: str) -> str: + return f"byom_submitted_servers:{user_id}" + + async def invalidate_byom_submitted_servers_cache(self, user_id: str | None) -> None: + if not user_id: + return + try: + from litellm.proxy.proxy_server import user_api_key_cache + + await user_api_key_cache.async_delete_cache(key=self.get_byom_submitted_servers_cache_key(user_id)) + except Exception as e: # noqa: BLE001 + verbose_logger.warning(f"Failed to invalidate BYOM submitted MCP server cache: {str(e)}") + + async def _get_active_submitted_mcp_server_ids_for_user( + self, user_api_key_auth: UserAPIKeyAuth | None + ) -> list[str]: + submitter_user_id = getattr(user_api_key_auth, "user_id", None) if user_api_key_auth else None + if not submitter_user_id: + return [] + + try: + from litellm.proxy._experimental.mcp_server.db import ( # noqa: PLC0415 + get_active_submitted_mcp_server_ids_for_user, + ) + from litellm.proxy.proxy_server import prisma_client, user_api_key_cache + except Exception as e: # noqa: BLE001 + verbose_logger.warning(f"Failed to load BYOM submitted MCP server cache dependencies: {str(e)}") + return [] + + byom_cache_key = self.get_byom_submitted_servers_cache_key(submitter_user_id) + submitted_server_ids: list[str] | None = None + try: + cached_submitted_server_ids = await user_api_key_cache.async_get_cache(key=byom_cache_key) + if cached_submitted_server_ids is not None: + submitted_server_ids = cast(list[str], cached_submitted_server_ids) + except Exception as e: # noqa: BLE001 + verbose_logger.warning(f"Failed to read BYOM submitted MCP server cache: {str(e)}") + + if submitted_server_ids is None: + if prisma_client is None: + submitted_server_ids = [] + else: + try: + submitted_server_ids = await get_active_submitted_mcp_server_ids_for_user( + prisma_client, submitter_user_id + ) + except Exception as e: # noqa: BLE001 + verbose_logger.warning(f"Failed to read BYOM submitted MCP servers from database: {str(e)}") + submitted_server_ids = [] + try: + await user_api_key_cache.async_set_cache( + key=byom_cache_key, + value=submitted_server_ids, + ttl=60, + ) + except Exception as e: # noqa: BLE001 + verbose_logger.warning(f"Failed to write BYOM submitted MCP server cache: {str(e)}") + + return [server_id for server_id in submitted_server_ids if self.get_mcp_server_by_id(server_id) is not None] + + async def get_allowed_mcp_servers(self, user_api_key_auth: Optional[UserAPIKeyAuth] = None) -> list[str]: """ Get the allowed MCP Servers for the user. @@ -1259,25 +1701,30 @@ class MCPServerManager: allow_all_server_ids = self.get_allow_all_keys_server_ids() + # The key explicitly opted out of every MCP server. Return zero before + # layering on allow_all_keys or submitted servers so the opt-out is absolute. + key_object_permission = user_api_key_auth.object_permission if user_api_key_auth else None + if key_object_permission is not None and ( + SpecialMCPServerNames.no_mcp_servers.value in (key_object_permission.mcp_servers or []) + ): + return [] + + # Check if object_permission.mcp_servers is explicitly set (not None, empty list is valid) + has_explicit_object_permission = key_object_permission is not None and ( + key_object_permission.mcp_servers is not None + ) + if has_explicit_object_permission: + verbose_logger.debug(f"Object permission mcp_servers explicitly set: {key_object_permission.mcp_servers}") + + # BYOM creator visibility never widens a key that was explicitly scoped: + # only keys without their own mcp_servers list get submitted servers unioned in. + submitted_server_ids = ( + [] + if has_explicit_object_permission + else await self._get_active_submitted_mcp_server_ids_for_user(user_api_key_auth) + ) + try: - # The key explicitly opted out of every MCP server. Return zero before - # layering on allow_all_keys servers so the opt-out is absolute. - key_object_permission = user_api_key_auth.object_permission if user_api_key_auth else None - if key_object_permission is not None and ( - SpecialMCPServerNames.no_mcp_servers.value in (key_object_permission.mcp_servers or []) - ): - return [] - - # Check if object_permission.mcp_servers is explicitly set - has_explicit_object_permission = False - if user_api_key_auth and user_api_key_auth.object_permission: - # Check if mcp_servers is explicitly set (not None, empty list is valid) - if user_api_key_auth.object_permission.mcp_servers is not None: - has_explicit_object_permission = True - verbose_logger.debug( - f"Object permission mcp_servers explicitly set: {user_api_key_auth.object_permission.mcp_servers}" - ) - # If admin but NO explicit object permission, get all servers if user_api_key_auth and _user_has_admin_view(user_api_key_auth) and not has_explicit_object_permission: verbose_logger.debug("Admin user without explicit object_permission - returning all servers") @@ -1299,6 +1746,7 @@ class MCPServerManager: in_toolset_scope = _mcp_active_toolset_id.get() is not None if not in_toolset_scope: combined_servers.update(allow_all_server_ids) + combined_servers.update(submitted_server_ids) # For anonymous callers (no user_id, no role), also surface any # servers the operator has opted into upstream-delegated auth. @@ -1316,12 +1764,18 @@ class MCPServerManager: delegate_server_ids = [ server.server_id for server in self.get_registry().values() - if getattr(server, "auth_type", None) == MCPAuth.oauth2 - and getattr(server, "delegate_auth_to_upstream", False) is True - # M2M servers must not be exposed anonymously: an - # unauthenticated caller would get LiteLLM to proxy tool - # calls using its stored client_credentials. - and not server.has_client_credentials + if ( + getattr(server, "auth_type", None) == MCPAuth.oauth2 + and getattr(server, "delegate_auth_to_upstream", False) is True + # M2M servers must not be exposed anonymously: an + # unauthenticated caller would get LiteLLM to proxy tool + # calls using its stored client_credentials. Resolve the flow + # rather than reading has_client_credentials so an unstamped + # M2M-shape row (null column, verbatim-read as non-M2M) still + # fails closed here, matching the anonymous-delegate auth gate. + and MCPServerManager.effective_oauth2_flow(server) != "client_credentials" + ) + or getattr(server, "auth_type", None) == MCPAuth.true_passthrough ] combined_servers.update(delegate_server_ids) @@ -1331,14 +1785,14 @@ class MCPServerManager: except Exception: # noqa: BLE001 verbose_logger.exception( "Failed to get allowed MCP servers; team-level object_permission " - "grants may be dropped. Falling back to global servers only." + "grants may be dropped. Falling back to global and submitted servers." ) - return allow_all_server_ids + return list(dict.fromkeys(allow_all_server_ids + submitted_server_ids)) async def resolve_toolset_tool_permissions( self, - toolset_ids: List[str], - ) -> Dict[str, List[str]]: + toolset_ids: list[str], + ) -> dict[str, list[str]]: """ Resolve a list of toolset IDs into a mcp_tool_permissions dict. @@ -1360,7 +1814,7 @@ class MCPServerManager: try: toolsets = await list_mcp_toolsets(prisma_client, toolset_ids=toolset_ids) - tool_permissions: Dict[str, List[str]] = {} + tool_permissions: dict[str, list[str]] = {} for toolset in toolsets: for tool in toolset.tools: raw_name = tool["tool_name"] @@ -1453,7 +1907,7 @@ class MCPServerManager: ) return toolset - def filter_server_ids_by_ip(self, server_ids: List[str], client_ip: Optional[str]) -> List[str]: + def filter_server_ids_by_ip(self, server_ids: list[str], client_ip: Optional[str]) -> list[str]: """ Filter server IDs by client IP — external callers only see public servers. @@ -1463,8 +1917,8 @@ class MCPServerManager: return filtered def filter_server_ids_by_ip_with_info( - self, server_ids: List[str], client_ip: Optional[str] - ) -> Tuple[List[str], int]: + self, server_ids: list[str], client_ip: Optional[str] + ) -> tuple[list[str], int]: """ Filter server IDs by client IP — external callers only see public servers. @@ -1484,7 +1938,7 @@ class MCPServerManager: blocked += 1 return allowed, blocked - async def get_tools_for_server(self, server_id: str) -> List[MCPTool]: + async def get_tools_for_server(self, server_id: str) -> list[MCPTool]: """ Get the tools for a given server """ @@ -1502,8 +1956,8 @@ class MCPServerManager: self, user_api_key_auth: Optional[UserAPIKeyAuth] = None, mcp_auth_header: Optional[str] = None, - mcp_server_auth_headers: Optional[Dict[str, Union[str, Dict[str, str]]]] = None, - ) -> List[MCPTool]: + mcp_server_auth_headers: Optional[dict[str, Union[str, dict[str, str]]]] = None, + ) -> list[MCPTool]: """ List all tools available across all MCP Servers. @@ -1520,7 +1974,7 @@ class MCPServerManager: verbose_logger.debug("SERVER MANAGER LISTING TOOLS") - async def _fetch_server_tools(server_id: str) -> List[MCPTool]: + async def _fetch_server_tools(server_id: str) -> list[MCPTool]: """Fetch tools from a single server with error handling.""" server = self.get_mcp_server_by_id(server_id) if server is None: @@ -1528,7 +1982,7 @@ class MCPServerManager: return [] # Get server-specific auth header if available - server_auth_header: Optional[Union[str, Dict[str, str]]] = None + server_auth_header: Optional[Union[str, dict[str, str]]] = None if mcp_server_auth_headers: from litellm.proxy._experimental.mcp_server.utils import ( lookup_mcp_server_auth_in_headers, @@ -1562,7 +2016,7 @@ class MCPServerManager: results = await asyncio.gather(*tasks) # Flatten results into single list - list_tools_result: List[MCPTool] = [tool for tools in results for tool in tools] + list_tools_result: list[MCPTool] = [tool for tools in results for tool in tools] verbose_logger.info(f"Successfully fetched {len(list_tools_result)} tools total from all servers") return list_tools_result @@ -1572,8 +2026,8 @@ class MCPServerManager: ######################################################### @staticmethod def _extract_bearer_token( - oauth2_headers: Optional[Dict[str, str]], - raw_headers: Optional[Dict[str, str]], + oauth2_headers: Optional[dict[str, str]], + raw_headers: Optional[dict[str, str]], ) -> Optional[str]: """Extract the bare Bearer token from oauth2_headers or raw_headers. @@ -1593,17 +2047,32 @@ class MCPServerManager: return auth_value return None + def _obo_subject_token( + self, + server: MCPServer, + raw_headers: Optional[dict[str, str]], + ) -> Optional[str]: + """The caller's bearer as the token_exchange (OBO) subject token, for that mode only. + + Prompts/resources discovery and reads on a token_exchange server must exchange the caller's + token like the tools paths do, not connect with no credential. Other modes never read the + inbound bearer, so return None to avoid forwarding it. + """ + if server.auth_type != MCPAuth.oauth2_token_exchange: + return None + return self._extract_bearer_token(None, raw_headers) + def _build_stdio_env( self, server: MCPServer, - raw_headers: Optional[Dict[str, str]] = None, - ) -> Optional[Dict[str, str]]: + raw_headers: Optional[dict[str, str]] = None, + ) -> Optional[dict[str, str]]: """Resolve stdio env values, supporting header-driven placeholders.""" if server.transport != MCPTransport.stdio or not server.env: return None - resolved_env: Dict[str, str] = {} + resolved_env: dict[str, str] = {} normalized_headers = {k.lower(): v for k, v in (raw_headers or {}).items()} for env_key, env_value in server.env.items(): @@ -1645,7 +2114,7 @@ class MCPServerManager: user_api_key_auth: Optional[UserAPIKeyAuth], *, raise_on_missing: bool = True, - ) -> Optional[Dict[str, str]]: + ) -> Optional[dict[str, str]]: """Return server.static_headers with ``${NAME}`` interpolated. Globals come from ``server.env_vars`` entries with ``scope=="global"``. @@ -1688,7 +2157,7 @@ class MCPServerManager: referenced_user_vars = referenced & user_var_names required_user_vars = {name for name in referenced_user_vars if name not in global_values} - user_values: Dict[str, str] = {} + user_values: dict[str, str] = {} if required_user_vars: try: user_values = await self._load_user_env_vars(server, user_api_key_auth) @@ -1727,7 +2196,7 @@ class MCPServerManager: # admin globals win, so a stale row from when a var was user-scoped can # never override the global value the admin set after switching it. scoped_user_values = {name: value for name, value in user_values.items() if name in user_var_names} - merged_vars: Dict[str, str] = {**scoped_user_values, **global_values} + merged_vars: dict[str, str] = {**scoped_user_values, **global_values} if not static_headers: return static_headers return interpolate_headers(static_headers, merged_vars) @@ -1738,7 +2207,7 @@ class MCPServerManager: user_api_key_auth: Optional[UserAPIKeyAuth], *, force_refresh: bool = False, - ) -> Dict[str, str]: + ) -> dict[str, str]: """Look up the calling user's env var values for ``server``. Returns an empty dict when no user is available. Results are cached in a @@ -1783,12 +2252,99 @@ class MCPServerManager: _write_user_env_vars_cache(user_id, server.server_id, values) return values + async def _resolve_v2_auth( + self, + *, + server: MCPServer, + spec: ServerSpec, + provider: UpstreamCredentialProvider, + subject_token: Optional[str], + user_api_key_auth: Optional[UserAPIKeyAuth], + extra_headers: Optional[dict[str, str]], + ) -> tuple[Optional[httpx.Auth], Optional[dict[str, str]]]: + """Resolve a v2-owned server's upstream credential into ``(resolved_auth, extra_headers)``. + + On a missing/rejected per-user credential this raises the mode's discovery challenge + (authorization_code's browser-OAuth 401, token_exchange's RFC 9728 challenge) or maps any + other ``CredError`` onto its public HTTP status; it never returns an error as a value. + """ + match await provider.resolve_credentials(to_subject(user_api_key_auth, subject_token), spec): + case Ok(auth): + # NoOpAuth has no header_name and so never conflicts. + header_name = getattr(auth, "header_name", None) + conflicts = bool( + header_name and extra_headers and any(key.lower() == header_name.lower() for key in extra_headers) + ) + if not conflicts: + return auth, extra_headers + if isinstance(spec.config, (TokenExchangeConfig, AuthorizationCodeConfig)): + # The resolver owns the per-user credential here (token_exchange's exchanged + # token, authorization_code's stored token). It is authoritative: a guardrail such + # as MCPJWTSigner, static_headers, or any other injected Authorization must NOT + # shadow it (otherwise the upstream gets e.g. the signer's JWT instead of the + # exchanged token and rejects it). Drop the conflicting header so the resolved + # token reaches upstream. + return auth, _without_authorization(extra_headers) + # Other modes: an Authorization already supplied via extra_headers (a forwarded caller + # header or static_headers) is intentional and wins; v1 applies those last. + return None, extra_headers + case Error(err): + if err.tag == "unauthorized" and isinstance(spec.config, AuthorizationCodeConfig): + # authorization_code's missing per-user token -> the per-server browser-OAuth + # challenge, built here where the full MCPServer is in hand. + raise_user_oauth_challenge(server, root_path=get_server_root_path()) + if err.tag == "unauthorized" and isinstance(spec.config, TokenExchangeConfig): + # token_exchange (OBO): a missing/rejected subject token -> the RFC 9728 challenge + # pointing at the IdP the client must SSO with to obtain one, rather than an opaque + # 401. No gateway-side browser flow. An IdP step-up rejection (Entra Conditional + # Access) threads its claims blob into the challenge for the client to satisfy. + raise_token_exchange_challenge( + server, + root_path=get_server_root_path(), + claims=err.unauthorized.claims, + ) + raise_public(err) + + async def preflight_token_exchange( + self, + server: MCPServer, + oauth2_headers: Optional[dict[str, str]], + user_api_key_auth: Optional[UserAPIKeyAuth], + ) -> None: + """Run the OBO exchange for a caller-supplied subject at the transport edge. + + Single-server routes call this before the MCP session opens, where an HTTP status and + ``WWW-Authenticate`` still reach the client. A rejected subject raises the RFC 9728 + challenge and any other ``CredError`` maps onto its public HTTP status, so an exchange + failure surfaces as a failure instead of the session continuing into an empty tool list. + A successful exchange is cached by the exchanger, so the session's list/call reuses it. + """ + if server.auth_type != MCPAuth.oauth2_token_exchange: + return + subject_token = self._extract_bearer_token(oauth2_headers, None) + if not subject_token: + return + spec = to_server_spec(server) + if spec is None or not isinstance(spec.config, TokenExchangeConfig): + return + match await self._cred_provider.resolve_credentials(to_subject(user_api_key_auth, subject_token), spec): + case Ok(_): + return + case Error(err): + if err.tag == "unauthorized": + raise_token_exchange_challenge( + server, + root_path=get_server_root_path(), + claims=err.unauthorized.claims, + ) + raise_public(err) + async def _create_mcp_client( self, server: MCPServer, - mcp_auth_header: Optional[Union[str, Dict[str, str]]] = None, - extra_headers: Optional[Dict[str, str]] = None, - stdio_env: Optional[Dict[str, str]] = None, + mcp_auth_header: Optional[Union[str, dict[str, str]]] = None, + extra_headers: Optional[dict[str, str]] = None, + stdio_env: Optional[dict[str, str]] = None, subject_token: Optional[str] = None, user_api_key_auth: Optional[UserAPIKeyAuth] = None, cred_provider: Optional[UpstreamCredentialProvider] = None, @@ -1817,11 +2373,18 @@ class MCPServerManager: spec = None if transport == MCPTransport.stdio else to_server_spec(server) provider = cred_provider or self._cred_provider # A caller-supplied per-request override (mcp_auth_header / x-mcp-*) defers to the v1 path - # so it wins - except for authorization_code, whose per-user token the v2 resolver owns. A - # caller must not be able to substitute another user's stored credential, so we keep the v2 - # spec and ignore the override there; the REST tools preview supplies its not-yet-persisted - # token through the resolver (cred_provider), never this path. - if spec is not None and mcp_auth_header and not isinstance(spec.config, AuthorizationCodeConfig): + # so it wins - except for the modes the v2 resolver owns per-caller (authorization_code's + # stored token, token_exchange's RFC 8693 minted token, and the passthrough modes' + # forwarded caller token). A caller must not be able to substitute another user's stored + # credential, nor silently disable the OBO exchange and forward an arbitrary bearer + # upstream, so we keep the v2 spec and ignore the override for these; the REST tools + # preview supplies its not-yet-persisted token through the resolver (cred_provider), + # never this path. + if ( + spec is not None + and mcp_auth_header + and not isinstance(spec.config, (AuthorizationCodeConfig, PassthroughConfig, TokenExchangeConfig)) + ): spec = None auth_value = ( await resolve_mcp_auth(server, mcp_auth_header, subject_token=subject_token) if spec is None else None @@ -1887,26 +2450,20 @@ class MCPServerManager: server_url = server.url or "" if spec is not None: - match await provider.resolve_credentials(to_subject(user_api_key_auth, subject_token), spec): - case Ok(auth): - resolved_auth = auth - # Do not override an Authorization already supplied via extra_headers - # (a guardrail hook such as the JWT signer, static_headers, or a - # forwarded caller header): v1 applies those last, so they win. NoOpAuth - # has no header_name and so never skips. - header_name = getattr(resolved_auth, "header_name", None) - if ( - header_name - and extra_headers - and any(key.lower() == header_name.lower() for key in extra_headers) - ): - resolved_auth = None - case Error(err): - if err.tag == "unauthorized": - # The arm signals a missing per-user token semantically; raise the - # per-server OAuth challenge here, where the full MCPServer is in hand. - raise_user_oauth_challenge(server) - raise_public(err) + inbound_token = subject_token + if isinstance(spec.config, PassthroughConfig): + inbound_token, extra_headers = _take_forwarded_authorization(extra_headers) + per_server_token = _passthrough_token_from_mcp_auth_header(mcp_auth_header) + if per_server_token is not None: + inbound_token = per_server_token + resolved_auth, extra_headers = await self._resolve_v2_auth( + server=server, + spec=spec, + provider=provider, + subject_token=inbound_token, + user_api_key_auth=user_api_key_auth, + extra_headers=extra_headers, + ) return MCPClient( server_url=server_url, transport_type=transport, @@ -1946,12 +2503,13 @@ class MCPServerManager: async def _get_tools_from_server( self, server: MCPServer, - mcp_auth_header: Optional[Union[str, Dict[str, str]]] = None, - extra_headers: Optional[Dict[str, str]] = None, + mcp_auth_header: Optional[Union[str, dict[str, str]]] = None, + extra_headers: Optional[dict[str, str]] = None, add_prefix: bool = True, - raw_headers: Optional[Dict[str, str]] = None, + raw_headers: Optional[dict[str, str]] = None, user_api_key_auth: Optional[UserAPIKeyAuth] = None, - ) -> List[MCPTool]: + oauth2_headers: Optional[dict[str, str]] = None, + ) -> list[MCPTool]: """ Helper method to get tools from a single MCP server with prefixed names. @@ -2024,11 +2582,21 @@ class MCPServerManager: stdio_env = self._build_stdio_env(server, raw_headers) + # token_exchange (OBO) discovery needs the caller's token too: list it with the user's own + # token (mirrors the call path), not v1's deleted client_credentials fallback. Other modes + # never read the inbound bearer, so leave subject_token None to avoid forwarding it. + subject_token = ( + self._extract_bearer_token(oauth2_headers, raw_headers) + if server.auth_type == MCPAuth.oauth2_token_exchange + else None + ) + client = await self._create_mcp_client( server=server, mcp_auth_header=mcp_auth_header, extra_headers=extra_headers, stdio_env=stdio_env, + subject_token=subject_token, user_api_key_auth=user_api_key_auth, ) @@ -2055,18 +2623,40 @@ class MCPServerManager: ] return tools else: - tools = await self._fetch_tools_with_timeout(client, server.name, server=server) + tools = await self._fetch_tools_with_timeout(client, server.name) self._remember_upstream_initialize_instructions(server, client) prefixed_or_original_tools = self._create_prefixed_tools(tools, server, add_prefix=add_prefix) return prefixed_or_original_tools - except MCPUpstreamAuthError: + except MCPUpstreamAuthError as upstream_auth_error: # Pass-through 401 must surface to single-server routes so the # client triggers the upstream OAuth flow. The multi-server # aggregator catches this explicitly to keep absorbing. + if server.is_dcr_bridge and upstream_auth_error.www_authenticate is not None: + raise MCPUpstreamAuthError( + status_code=upstream_auth_error.status_code, + www_authenticate=None, + server_name=upstream_auth_error.server_name, + ) from upstream_auth_error raise + except HTTPException as e: + # A v2 resolver auth challenge (token_exchange's RFC 9728 401, authorization_code's + # browser-OAuth 401, or a 403) is raised at client-build time, inside this try. Route it + # through the same MCPUpstreamAuthError channel as pass-through so single-server routes + # surface the challenge (the client re-authenticates) while the aggregator keeps absorbing. + # Non-auth HTTP errors stay absorbed so one misconfigured server can't blank the listing. + if e.status_code in (401, 403): + headers = e.headers or {} + challenge_header = headers.get("WWW-Authenticate") or headers.get("www-authenticate") + raise MCPUpstreamAuthError( + status_code=e.status_code, + www_authenticate=None if server.is_dcr_bridge else challenge_header, + server_name=server.name, + ) from e + verbose_logger.warning(f"Failed to get tools from server {server.name}: {str(e)}") + return [] except Exception as e: verbose_logger.warning(f"Failed to get tools from server {server.name}: {str(e)}") return [] @@ -2074,11 +2664,11 @@ class MCPServerManager: async def get_prompts_from_server( self, server: MCPServer, - mcp_auth_header: Optional[Union[str, Dict[str, str]]] = None, - extra_headers: Optional[Dict[str, str]] = None, + mcp_auth_header: Optional[Union[str, dict[str, str]]] = None, + extra_headers: Optional[dict[str, str]] = None, add_prefix: bool = True, - raw_headers: Optional[Dict[str, str]] = None, - ) -> List[Prompt]: + raw_headers: Optional[dict[str, str]] = None, + ) -> list[Prompt]: """ Helper method to get prompts from a single MCP server with prefixed names. @@ -2102,12 +2692,14 @@ class MCPServerManager: extra_headers.update(server.static_headers) stdio_env = self._build_stdio_env(server, raw_headers) + subject_token = self._obo_subject_token(server, raw_headers) client = await self._create_mcp_client( server=server, mcp_auth_header=mcp_auth_header, extra_headers=extra_headers, stdio_env=stdio_env, + subject_token=subject_token, ) prompts = await client.list_prompts() @@ -2123,11 +2715,11 @@ class MCPServerManager: async def get_resources_from_server( self, server: MCPServer, - mcp_auth_header: Optional[Union[str, Dict[str, str]]] = None, - extra_headers: Optional[Dict[str, str]] = None, + mcp_auth_header: Optional[Union[str, dict[str, str]]] = None, + extra_headers: Optional[dict[str, str]] = None, add_prefix: bool = True, - raw_headers: Optional[Dict[str, str]] = None, - ) -> List[Resource]: + raw_headers: Optional[dict[str, str]] = None, + ) -> list[Resource]: """Fetch available resources from a single MCP server.""" verbose_logger.debug(f"Connecting to url: {server.url}") @@ -2142,12 +2734,14 @@ class MCPServerManager: extra_headers.update(server.static_headers) stdio_env = self._build_stdio_env(server, raw_headers) + subject_token = self._obo_subject_token(server, raw_headers) client = await self._create_mcp_client( server=server, mcp_auth_header=mcp_auth_header, extra_headers=extra_headers, stdio_env=stdio_env, + subject_token=subject_token, ) resources = await client.list_resources() @@ -2163,11 +2757,11 @@ class MCPServerManager: async def get_resource_templates_from_server( self, server: MCPServer, - mcp_auth_header: Optional[Union[str, Dict[str, str]]] = None, - extra_headers: Optional[Dict[str, str]] = None, + mcp_auth_header: Optional[Union[str, dict[str, str]]] = None, + extra_headers: Optional[dict[str, str]] = None, add_prefix: bool = True, - raw_headers: Optional[Dict[str, str]] = None, - ) -> List[ResourceTemplate]: + raw_headers: Optional[dict[str, str]] = None, + ) -> list[ResourceTemplate]: """Fetch available resource templates from a single MCP server.""" verbose_logger.debug(f"Connecting to url: {server.url}") @@ -2182,12 +2776,14 @@ class MCPServerManager: extra_headers.update(server.static_headers) stdio_env = self._build_stdio_env(server, raw_headers) + subject_token = self._obo_subject_token(server, raw_headers) client = await self._create_mcp_client( server=server, mcp_auth_header=mcp_auth_header, extra_headers=extra_headers, stdio_env=stdio_env, + subject_token=subject_token, ) resource_templates = await client.list_resource_templates() @@ -2206,9 +2802,9 @@ class MCPServerManager: self, server: MCPServer, url: AnyUrl, - mcp_auth_header: Optional[Union[str, Dict[str, str]]] = None, - extra_headers: Optional[Dict[str, str]] = None, - raw_headers: Optional[Dict[str, str]] = None, + mcp_auth_header: Optional[Union[str, dict[str, str]]] = None, + extra_headers: Optional[dict[str, str]] = None, + raw_headers: Optional[dict[str, str]] = None, ) -> ReadResourceResult: """Read resource contents from a specific MCP server.""" @@ -2221,12 +2817,14 @@ class MCPServerManager: extra_headers.update(server.static_headers) stdio_env = self._build_stdio_env(server, raw_headers) + subject_token = self._obo_subject_token(server, raw_headers) client = await self._create_mcp_client( server=server, mcp_auth_header=mcp_auth_header, extra_headers=extra_headers, stdio_env=stdio_env, + subject_token=subject_token, ) return await client.read_resource(url) @@ -2235,10 +2833,10 @@ class MCPServerManager: self, server: MCPServer, prompt_name: str, - arguments: Optional[Dict[str, Any]] = None, - mcp_auth_header: Optional[Union[str, Dict[str, str]]] = None, - extra_headers: Optional[Dict[str, str]] = None, - raw_headers: Optional[Dict[str, str]] = None, + arguments: Optional[dict[str, Any]] = None, + mcp_auth_header: Optional[Union[str, dict[str, str]]] = None, + extra_headers: Optional[dict[str, str]] = None, + raw_headers: Optional[dict[str, str]] = None, ) -> GetPromptResult: """Fetch a specific prompt definition from a single MCP server.""" @@ -2251,12 +2849,14 @@ class MCPServerManager: extra_headers.update(server.static_headers) stdio_env = self._build_stdio_env(server, raw_headers) + subject_token = self._obo_subject_token(server, raw_headers) client = await self._create_mcp_client( server=server, mcp_auth_header=mcp_auth_header, extra_headers=extra_headers, stdio_env=stdio_env, + subject_token=subject_token, ) get_prompt_request_params = GetPromptRequestParams( @@ -2309,8 +2909,17 @@ class MCPServerManager: async def _descovery_metadata( self, server_url: str, + *, + allow_origin_fallback: bool = True, ) -> Optional[MCPOAuthMetadata]: - """Discover OAuth metadata by following RFC 9728 (protected resource metadata discovery).""" + """Discover OAuth metadata by following RFC 9728 (protected resource metadata discovery). + + ``allow_origin_fallback`` controls the last-resort guess that treats the resource server's own + origin as its authorization server when nothing is advertised. The browser ``oauth2`` flow keeps + it (a human sees the redirect), but token_exchange (OBO) sets it False so the gateway never + exchanges a subject token against an endpoint it inferred rather than one explicitly configured + or authoritatively advertised via RFC 9728 / RFC 8414. + """ try: client = get_async_httpx_client(llm_provider=httpxSpecialProvider.MCP) @@ -2360,7 +2969,7 @@ class MCPServerManager: ) = await self._attempt_well_known_discovery(server_url) metadata = None - if not authorization_servers: + if allow_origin_fallback and not authorization_servers: try: parsed_url = urlparse(server_url) if parsed_url.scheme and parsed_url.netloc: @@ -2382,7 +2991,7 @@ class MCPServerManager: verbose_logger.debug("MCP OAuth discovery failed for %s: %s", server_url, exc) return None - def _parse_www_authenticate_header(self, header_value: Optional[str]) -> Tuple[Optional[str], Optional[List[str]]]: + def _parse_www_authenticate_header(self, header_value: Optional[str]) -> tuple[Optional[str], Optional[list[str]]]: if not header_value: return None, None @@ -2390,7 +2999,7 @@ class MCPServerManager: params_section = params_section or header_value param_pattern = re.compile(r"([a-zA-Z0-9_]+)\s*=\s*\"?([^\",]+)\"?") - params: Dict[str, str] = { + params: dict[str, str] = { match.group(1).lower(): match.group(2).strip() for match in param_pattern.finditer(params_section) } @@ -2404,7 +3013,7 @@ class MCPServerManager: async def _fetch_oauth_metadata_from_resource( self, resource_metadata_url: str, server_url: str - ) -> Tuple[List[str], Optional[List[str]]]: + ) -> tuple[list[str], Optional[list[str]]]: if not resource_metadata_url: return [], None @@ -2439,7 +3048,7 @@ class MCPServerManager: return authorization_servers, scopes - async def _attempt_well_known_discovery(self, server_url: str) -> Tuple[List[str], Optional[List[str]]]: + async def _attempt_well_known_discovery(self, server_url: str) -> tuple[list[str], Optional[list[str]]]: try: parsed = urlparse(server_url) except Exception: @@ -2452,7 +3061,7 @@ class MCPServerManager: path = parsed.path or "" path = path.strip("/") - candidate_urls: List[str] = [] + candidate_urls: list[str] = [] if path: candidate_urls.append(f"{base}/.well-known/oauth-protected-resource/{path}") candidate_urls.append(f"{base}/.well-known/oauth-protected-resource") @@ -2468,7 +3077,7 @@ class MCPServerManager: return [], None async def _fetch_authorization_server_metadata( - self, authorization_servers: List[str], server_url: str + self, authorization_servers: list[str], server_url: str ) -> Optional[MCPOAuthMetadata]: for issuer in authorization_servers: metadata = await self._fetch_single_authorization_server_metadata(issuer, server_url) @@ -2490,7 +3099,7 @@ class MCPServerManager: base = f"{parsed.scheme}://{parsed.netloc}" path = (parsed.path or "").strip("/") - candidate_urls: List[str] = [] + candidate_urls: list[str] = [] if path: candidate_urls.append(f"{base}/.well-known/oauth-authorization-server/{path}") candidate_urls.append(f"{base}/.well-known/openid-configuration/{path}") @@ -2522,6 +3131,14 @@ class MCPServerManager: continue scopes = self._extract_scopes(data.get("scopes_supported")) + verbose_logger.debug( + "Authorization server metadata from %s: issuer=%s grant_types_supported=%s " + "token_endpoint_auth_methods_supported=%s", + url, + data.get("issuer"), + data.get("grant_types_supported"), + data.get("token_endpoint_auth_methods_supported"), + ) metadata = MCPOAuthMetadata( scopes=scopes, authorization_url=data.get("authorization_endpoint"), @@ -2576,9 +3193,9 @@ class MCPServerManager: def _extract_aws_credentials( self, - credentials_dict: Optional[Dict[str, str]], + credentials_dict: Optional[dict[str, str]], credentials_are_encrypted: bool, - ) -> Dict[str, Optional[str]]: + ) -> dict[str, Optional[str]]: """Extract and decrypt AWS SigV4 credential fields from credentials dict.""" if not credentials_dict: return {} @@ -2604,7 +3221,7 @@ class MCPServerManager: "aws_session_name": credentials_dict.get("aws_session_name"), } - def _extract_scopes(self, scopes_value: Any) -> Optional[List[str]]: + def _extract_scopes(self, scopes_value: Any) -> Optional[list[str]]: if isinstance(scopes_value, str): scopes = [s.strip() for s in scopes_value.split() if s.strip()] return scopes or None @@ -2617,46 +3234,34 @@ class MCPServerManager: self, client: MCPClient, server_name: str, - server: Optional[MCPServer] = None, - ) -> List[MCPTool]: + ) -> list[MCPTool]: """ Fetch tools from MCP client with timeout and error handling. Uses anyio.fail_after() instead of asyncio.wait_for() to avoid conflicts with the MCP SDK's anyio TaskGroup. See GitHub issue #20715 for details. - For OAuth pass-through and upstream-delegated OAuth2 MCP servers, an - upstream HTTP 401 is converted into :class:`MCPUpstreamAuthError` - instead of being swallowed to an empty tool list. That lets the - single-server HTTP routes surface a proper 401 + ``WWW-Authenticate`` - challenge so standards-compliant MCP clients trigger the upstream - OAuth flow. Other servers keep today's swallow-and-log behaviour so - the multi-server ``/mcp`` aggregator doesn't get tainted by a single - bad server. + An upstream HTTP 401 is converted into :class:`MCPUpstreamAuthError` + instead of being swallowed to an empty tool list, regardless of the + server's auth_type. Callers route it by surface: the single-server HTTP + routes turn it into a 401 + ``WWW-Authenticate`` challenge so standards- + compliant MCP clients trigger the upstream OAuth flow, while the + multi-server ``/mcp`` aggregator absorbs it to an empty list so one + unauthenticated server doesn't fail the whole listing. Only a 401 + (missing/invalid credential) drives the re-auth challenge; a 403 + (authenticated but forbidden, e.g. insufficient scope) is not a re-auth + signal and, like other non-auth errors, returns an empty list. Args: client: MCP client instance server_name: Name of the server for logging - server: Optional MCPServer; when upstream auth is delegated, auth - errors are re-raised as :class:`MCPUpstreamAuthError`. Returns: List of tools from the server """ - should_surface_upstream_auth = bool( - server is not None - and ( - server.is_oauth_passthrough - or ( - server.auth_type == MCPAuth.oauth2 - and getattr(server, "delegate_auth_to_upstream", False) is True - and not server.has_client_credentials - ) - ) - ) try: with anyio.fail_after(MCP_TOOL_LISTING_TIMEOUT): - tools = await client.list_tools(raise_on_error=should_surface_upstream_auth) + tools = await client.list_tools(raise_on_error=True) verbose_logger.debug(f"Tools from {server_name}: {tools}") return tools except TimeoutError: @@ -2669,16 +3274,15 @@ class MCPServerManager: verbose_logger.warning(f"Connection error while listing tools from {server_name}: {str(e)}") return [] except Exception as e: - if should_surface_upstream_auth: - auth_info = _extract_upstream_auth_failure(e) - if auth_info is not None: - status_code, www_authenticate = auth_info - verbose_logger.info(f"Upstream auth failure from MCP server {server_name}: HTTP {status_code}") - raise MCPUpstreamAuthError( - status_code=status_code, - www_authenticate=www_authenticate, - server_name=server_name, - ) from e + auth_info = _extract_upstream_auth_failure(e) + if auth_info is not None and auth_info[0] == 401: + _, www_authenticate = auth_info + verbose_logger.info(f"Upstream auth failure from MCP server {server_name}: HTTP 401") + raise MCPUpstreamAuthError( + status_code=401, + www_authenticate=www_authenticate, + server_name=server_name, + ) from e verbose_logger.warning(f"Error listing tools from {server_name}: {str(e)}") return [] @@ -2687,7 +3291,7 @@ class MCPServerManager: def _assign_unique_short_prefix( self, server: MCPServer, - registry: Optional[Dict[str, MCPServer]] = None, + registry: Optional[dict[str, MCPServer]] = None, ) -> None: """Resolve and cache a collision-free short tool prefix on ``server``. @@ -2711,7 +3315,7 @@ class MCPServerManager: if not server.server_id: return - used: Dict[str, str] = {} + used: dict[str, str] = {} registry_for_collision_check = registry or self.get_registry() for other in registry_for_collision_check.values(): if other.server_id == server.server_id: @@ -2744,7 +3348,7 @@ class MCPServerManager: "attempts; the 3-character prefix space is too crowded." ) - def _create_prefixed_tools(self, tools: List[MCPTool], server: MCPServer, add_prefix: bool = True) -> List[MCPTool]: + def _create_prefixed_tools(self, tools: list[MCPTool], server: MCPServer, add_prefix: bool = True) -> list[MCPTool]: """ Create prefixed tools and update tool mapping. @@ -2782,8 +3386,8 @@ class MCPServerManager: return prefixed_tools def _create_prefixed_prompts( - self, prompts: List[Prompt], server: MCPServer, add_prefix: bool = True - ) -> List[Prompt]: + self, prompts: list[Prompt], server: MCPServer, add_prefix: bool = True + ) -> list[Prompt]: """ Create prefixed prompts and update prompt mapping. @@ -2809,11 +3413,11 @@ class MCPServerManager: return prefixed_prompts def _create_prefixed_resources( - self, resources: List[Resource], server: MCPServer, add_prefix: bool = True - ) -> List[Resource]: + self, resources: list[Resource], server: MCPServer, add_prefix: bool = True + ) -> list[Resource]: """Prefix resource names and track origin server for read requests.""" - prefixed_resources: List[Resource] = [] + prefixed_resources: list[Resource] = [] prefix = get_server_prefix(server) for resource in resources: @@ -2826,13 +3430,13 @@ class MCPServerManager: def _create_prefixed_resource_templates( self, - resource_templates: List[ResourceTemplate], + resource_templates: list[ResourceTemplate], server: MCPServer, add_prefix: bool = True, - ) -> List[ResourceTemplate]: + ) -> list[ResourceTemplate]: """Prefix resource template names for multi-server scenarios.""" - prefixed_templates: List[ResourceTemplate] = [] + prefixed_templates: list[ResourceTemplate] = [] prefix = get_server_prefix(server) for resource_template in resource_templates: @@ -2865,7 +3469,7 @@ class MCPServerManager: ) return True - def validate_allowed_params(self, tool_name: str, arguments: Dict[str, Any], server: MCPServer) -> None: + def validate_allowed_params(self, tool_name: str, arguments: dict[str, Any], server: MCPServer) -> None: """ Filter arguments to only include allowed parameters for the given tool. @@ -2956,7 +3560,7 @@ class MCPServerManager: self, server: MCPServer, tool_name: str, - arguments: Dict[str, Any], + arguments: dict[str, Any], ) -> CallToolResult: """ Call an OpenAPI tool handler directly. @@ -3013,13 +3617,13 @@ class MCPServerManager: async def pre_call_tool_check( self, name: str, - arguments: Dict[str, Any], + arguments: dict[str, Any], server_name: str, user_api_key_auth: Optional[UserAPIKeyAuth], proxy_logging_obj: ProxyLogging, server: MCPServer, - raw_headers: Optional[Dict[str, str]] = None, - ) -> Dict[str, Any]: + raw_headers: Optional[dict[str, str]] = None, + ) -> dict[str, Any]: """ Run pre-call checks and guardrail hooks for an MCP tool call. @@ -3079,7 +3683,7 @@ class MCPServerManager: # Convert to LLM format for existing guardrail compatibility synthetic_llm_data = proxy_logging_obj._convert_mcp_to_llm_format(mcp_request_obj, pre_hook_kwargs) - hook_result: Dict[str, Any] = {} + hook_result: dict[str, Any] = {} try: # Use standard pre_call_hook modified_data = await proxy_logging_obj.pre_call_hook( @@ -3109,7 +3713,7 @@ class MCPServerManager: def _create_during_hook_task( self, name: str, - arguments: Dict[str, Any], + arguments: dict[str, Any], server_name_from_prefix: Optional[str], user_api_key_auth: Optional[UserAPIKeyAuth], proxy_logging_obj: ProxyLogging, @@ -3144,19 +3748,79 @@ class MCPServerManager: ) ) + def _get_call_semaphore(self, mcp_server: MCPServer) -> Optional[asyncio.Semaphore]: + limit = mcp_server.max_concurrent_requests + if limit is None or limit <= 0: + return None + cached = self._server_call_semaphores.get(mcp_server.server_id) + if cached is not None and cached[0] == limit: + return cached[1] + semaphore = asyncio.Semaphore(limit) + self._server_call_semaphores[mcp_server.server_id] = (limit, semaphore) + return semaphore + + @asynccontextmanager + async def _limit_outbound_concurrency(self, mcp_server: MCPServer) -> AsyncIterator[None]: + semaphore = self._get_call_semaphore(mcp_server) + if semaphore is None: + yield + return + async with semaphore: + yield + + async def _obo_call_tool_with_retry( + self, + *, + client: MCPClient, + call_tool_params: MCPCallToolRequestParams, + host_progress_callback: Optional[Callable], + mcp_server: MCPServer, + server_auth_header: str | dict[str, str] | None, + extra_headers: Optional[dict[str, str]], + stdio_env: Optional[dict[str, str]], + subject_token: Optional[str], + user_api_key_auth: Optional[UserAPIKeyAuth], + ) -> CallToolResult: + """Call a token_exchange (OBO) tool; on an upstream 401/403 re-mint the token once and retry. + + The exchanged token is baked into the client at build time, so the retry invalidates the + cached exchange and rebuilds the client (which re-exchanges). One retry only: a non-auth + failure or a second auth failure degrades to the normal ``isError`` result, and a re-exchange + that now fails surfaces its own 401 challenge from ``_create_mcp_client``. + """ + try: + return await client.call_tool( + call_tool_params, host_progress_callback=host_progress_callback, raise_on_error=True + ) + except Exception as exc: + if _extract_upstream_auth_failure(exc) is None: + return MCPClient.error_tool_result(exc) + spec = to_server_spec(mcp_server) + if spec is not None: + await self._cred_provider.invalidate_credentials(to_subject(user_api_key_auth, subject_token), spec) + retry_client = await self._create_mcp_client( + server=mcp_server, + mcp_auth_header=server_auth_header, + extra_headers=extra_headers, + stdio_env=stdio_env, + subject_token=subject_token, + user_api_key_auth=user_api_key_auth, + ) + return await retry_client.call_tool(call_tool_params, host_progress_callback=host_progress_callback) + async def _call_regular_mcp_tool( self, mcp_server: MCPServer, original_tool_name: str, - arguments: Dict[str, Any], - tasks: List, + arguments: dict[str, Any], + tasks: list, mcp_auth_header: Optional[str], - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]], - oauth2_headers: Optional[Dict[str, str]], - raw_headers: Optional[Dict[str, str]], + mcp_server_auth_headers: Optional[dict[str, dict[str, str]]], + oauth2_headers: Optional[dict[str, str]], + raw_headers: Optional[dict[str, str]], proxy_logging_obj: Optional[ProxyLogging], host_progress_callback: Optional[Callable] = None, - hook_extra_headers: Optional[Dict[str, str]] = None, + hook_extra_headers: Optional[dict[str, str]] = None, user_api_key_auth: Optional[UserAPIKeyAuth] = None, ) -> CallToolResult: """ @@ -3187,7 +3851,7 @@ class MCPServerManager: # Get server-specific auth header if available (case-insensitive) # FIX: Added case-insensitive matching to handle auth header keys that may not match # the exact case of server alias/name (e.g., '1litellmagcgateway' vs '1LiteLLMAGCGateway') - server_auth_header: Optional[Union[Dict[str, str], str]] = None + server_auth_header: Optional[Union[dict[str, str], str]] = None if mcp_server_auth_headers: # Normalize keys for case-insensitive lookup from litellm.proxy._experimental.mcp_server.utils import ( @@ -3206,7 +3870,7 @@ class MCPServerManager: # Extract subject token for OAuth2 Token Exchange (OBO) flow subject_token: Optional[str] = None - extra_headers: Optional[Dict[str, str]] = None + extra_headers: Optional[dict[str, str]] = None if mcp_server.auth_type == MCPAuth.oauth2_token_exchange: subject_token = self._extract_bearer_token(oauth2_headers, raw_headers) elif mcp_server.auth_type == MCPAuth.oauth2: @@ -3225,6 +3889,13 @@ class MCPServerManager: user_api_key_auth=user_api_key_auth, ): extra_headers = _without_authorization(extra_headers) + elif mcp_server.is_true_passthrough or mcp_server.is_oauth_delegate: + extra_headers = _client_forwarded_authorization_headers( + mcp_server=mcp_server, + oauth2_headers=oauth2_headers, + raw_headers=raw_headers, + user_api_key_auth=user_api_key_auth, + ) if mcp_server.extra_headers and raw_headers: if extra_headers is None: @@ -3302,10 +3973,74 @@ class MCPServerManager: arguments=arguments, ) - async def _call_tool_via_client(client, params): - return await client.call_tool(params, host_progress_callback=host_progress_callback) + if mcp_server.auth_type == MCPAuth.oauth2_token_exchange and subject_token: + # OBO: the exchanged token may have been revoked/rotated upstream since it was cached, so + # an upstream 401 gets one re-mint + retry. Gated to this mode; all others keep the plain + # single call below. + async def _obo_call_tool_limited(): + async with self._limit_outbound_concurrency(mcp_server): + return await self._obo_call_tool_with_retry( + client=client, + call_tool_params=call_tool_params, + host_progress_callback=host_progress_callback, + mcp_server=mcp_server, + server_auth_header=server_auth_header, + extra_headers=extra_headers, + stdio_env=stdio_env, + subject_token=subject_token, + user_api_key_auth=user_api_key_auth, + ) - tasks.append(asyncio.create_task(_call_tool_via_client(client, call_tool_params))) + tool_call_coro = _obo_call_tool_limited() + else: + # Scoped to the two client-forwarded token modes this stack introduced; legacy + # oauth2 + delegate_auth_to_upstream (is_oauth_passthrough) is being removed, so it is not + # added here even though the list path still relays for it. + relays_upstream_auth = mcp_server.is_true_passthrough or mcp_server.is_oauth_delegate + server_label = mcp_server.name or mcp_server.server_name or mcp_server.alias or "" + + async def _call_tool_via_client(client, params): + async with self._limit_outbound_concurrency(mcp_server): + if not relays_upstream_auth: + return await client.call_tool(params, host_progress_callback=host_progress_callback) + # The client-forwarded modes carry the caller's own upstream token, so an upstream + # 401 (expired/invalid token) is the caller's to resolve: relay it as + # MCPUpstreamAuthError so single-server REST callers turn it into a 401 + + # WWW-Authenticate and re-run the upstream OAuth flow. Only 401 is a re-auth signal + # (mirrors the list path and MCPUpstreamAuthError's contract); a 403 is a genuine + # authorization failure that re-auth won't fix, so it takes the non-auth branch and + # stays a visible warning. raise_on_error only re-raises transport failures + # (tool-level isError results are still returned normally); a non-auth failure keeps + # the same isError degradation the default path produces. + try: + return await client.call_tool( + params, host_progress_callback=host_progress_callback, raise_on_error=True + ) + except Exception as e: + auth_info = _extract_upstream_auth_failure(e) + if auth_info is None or auth_info[0] != 401: + # A genuine (non-auth or 403-forbidden) upstream/transport failure. + # raise_on_error demoted the client-layer log to debug, so surface it here at + # warning level to keep the outage visible; the caller still gets the graceful + # isError result the default masking path would have produced. Log the + # exception type only, never str(e), which for an httpx error embeds the + # upstream URL (a credential can hide in it). + verbose_logger.warning( + "Pass-through MCP tool call failed against %s (non-auth, %s)", + server_label, + type(e).__name__, + ) + return client.error_tool_result(e) + _, www_authenticate = auth_info + raise MCPUpstreamAuthError( + status_code=401, + www_authenticate=www_authenticate, + server_name=server_label, + ) from e + + tool_call_coro = _call_tool_via_client(client, call_tool_params) + + tasks.append(asyncio.create_task(tool_call_coro)) _timeout = mcp_server.timeout if mcp_server.timeout is not None else MCP_CLIENT_TIMEOUT try: @@ -3390,12 +4125,34 @@ class MCPServerManager: return False return await self._cred_provider.has_user_token(to_subject(user_api_key_auth, None), spec) + async def invalidate_user_oauth_token_cache(self, user_id: str, server_id: str) -> None: + """Drop every cached token for ``(user_id, server_id)`` after the credential row changes + (re-auth, revoke, config-change purge): the v2 chain's cache and the legacy per-user token + cache, so the next resolve reads the new row instead of serving the replaced token until its + cache TTL, whichever path resolves it. This is the single invalidation point for per-user + OAuth tokens; callers must not evict individual caches directly. Best-effort: a cache-drop + failure is logged, never raised, because the DB write already succeeded and the TTL remains + the backstop. + """ + try: + await self._per_user_oauth_token_store.invalidate(user_id, server_id) + except Exception as exc: # noqa: BLE001 - cache drop is best-effort; TTL is the backstop + verbose_logger.warning( + "Failed to invalidate cached MCP OAuth token for user=%s server=%s: %s", user_id, server_id, exc + ) + try: + await self._per_user_token_cache.delete(user_id, server_id) + except Exception as exc: # noqa: BLE001 - cache drop is best-effort; TTL is the backstop + verbose_logger.warning( + "Failed to drop legacy cached MCP OAuth token for user=%s server=%s: %s", user_id, server_id, exc + ) + async def _resolve_oauth2_headers_for_tool_call( self, mcp_server: MCPServer, - oauth2_headers: Optional[Dict[str, str]], + oauth2_headers: Optional[dict[str, str]], user_api_key_auth: Optional[UserAPIKeyAuth], - ) -> Optional[Dict[str, str]]: + ) -> Optional[dict[str, str]]: """Look up per-user OAuth headers when the client did not supply a token.""" if not mcp_server.needs_user_oauth_token or oauth2_headers or user_api_key_auth is None: return oauth2_headers @@ -3432,7 +4189,7 @@ class MCPServerManager: async def _gather_openapi_tool_tasks( self, - tasks: List[Any], + tasks: list[Any], proxy_logging_obj: Optional[ProxyLogging], ) -> CallToolResult: """Await OpenAPI tool tasks and return the tool call result.""" @@ -3452,13 +4209,13 @@ class MCPServerManager: self, server_name: str, name: str, - arguments: Dict[str, Any], + arguments: dict[str, Any], user_api_key_auth: Optional[UserAPIKeyAuth] = None, mcp_auth_header: Optional[str] = None, - mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]] = None, + mcp_server_auth_headers: Optional[dict[str, dict[str, str]]] = None, proxy_logging_obj: Optional[ProxyLogging] = None, - oauth2_headers: Optional[Dict[str, str]] = None, - raw_headers: Optional[Dict[str, str]] = None, + oauth2_headers: Optional[dict[str, str]] = None, + raw_headers: Optional[dict[str, str]] = None, host_progress_callback: Optional[Callable] = None, ) -> CallToolResult: """ @@ -3480,12 +4237,21 @@ class MCPServerManager: start_time = datetime.datetime.now() mcp_server = self._resolve_mcp_server_for_tool_call(server_name, name) + # Resolved before any hook runs so a missing BYOK credential (401) never + # leaves during-hook side effects (audit logging, rate-limit bookkeeping) + # recorded against a call that ultimately fails. + mcp_auth_header = await _resolve_byok_mcp_auth_header( + mcp_server, + user_api_key_auth, + mcp_auth_header, + ) + ######################################################### # Pre MCP Tool Call Hook # Allow validation and modification of tool calls before execution # Using standard pre_call_hook ######################################################### - hook_result: Dict[str, Any] = {} + hook_result: dict[str, Any] = {} if proxy_logging_obj: hook_result = await self.pre_call_tool_check( name=name, @@ -3525,7 +4291,28 @@ class MCPServerManager: "transport to enable hook header injection.", server_name, ) - tasks.append(asyncio.create_task(self._call_openapi_tool_handler(mcp_server, name, arguments))) + + auth_header_value = ( + _format_byok_openapi_auth_header(mcp_server, mcp_auth_header) if mcp_auth_header else None + ) + forwarded_headers = _openapi_forwarded_extra_headers(mcp_server, raw_headers, user_api_key_auth) + + async def _call_openapi_via_handler(): + from litellm.proxy._experimental.mcp_server.openapi_to_mcp_generator import ( + _request_auth_header, + _request_extra_headers, + ) + + auth_token = _request_auth_header.set(auth_header_value) + extra_token = _request_extra_headers.set(forwarded_headers) + try: + async with self._limit_outbound_concurrency(mcp_server): + return await self._call_openapi_tool_handler(mcp_server, name, arguments) + finally: + _request_auth_header.reset(auth_token) + _request_extra_headers.reset(extra_token) + + tasks.append(asyncio.create_task(_call_openapi_via_handler())) else: return await self._call_regular_mcp_tool( mcp_server=mcp_server, @@ -3606,7 +4393,7 @@ class MCPServerManager: # Build prefix → server lookup covering every known form a tool name # may take (alias / server_name / server_id / short ID). This is what # makes the short-prefix mode work without breaking historical names. - prefix_to_server: Dict[str, MCPServer] = {} + prefix_to_server: dict[str, MCPServer] = {} for server in registry_servers: for known_prefix in iter_known_server_prefixes(server): normalised = normalize_server_name(known_prefix) @@ -3667,7 +4454,7 @@ class MCPServerManager: verbose_logger.info(f"Found {len(db_mcp_servers)} MCP servers in database") previous_registry = self.registry - new_registry: Dict[str, MCPServer] = {} + new_registry: dict[str, MCPServer] = {} # Stage one: build every server. Stage two assigns short prefixes # against the *full* set so dedup is deterministic regardless of @@ -3713,7 +4500,7 @@ class MCPServerManager: # Assign short prefixes against the full candidate set without # publishing the staged registry to concurrent callers. - registered_registry: Dict[str, MCPServer] = {} + registered_registry: dict[str, MCPServer] = {} registered_openapi_tools = False for server_id, new_server in new_registry.items(): try: @@ -3739,7 +4526,7 @@ class MCPServerManager: verbose_logger.debug("MCP registry refreshed (%s servers in registry)", len(registered_registry)) - def get_mcp_servers_from_ids(self, server_ids: List[str]) -> List[MCPServer]: + def get_mcp_servers_from_ids(self, server_ids: list[str]) -> list[MCPServer]: servers = [] registry = self.get_registry() for server in registry.values(): @@ -3747,7 +4534,7 @@ class MCPServerManager: servers.append(server) return servers - def _get_general_settings(self) -> Dict[str, Any]: + def _get_general_settings(self) -> dict[str, Any]: """Get general_settings, importing lazily to avoid circular imports.""" try: from litellm.proxy.proxy_server import ( @@ -3790,7 +4577,7 @@ class MCPServerManager: return server return None - def get_public_mcp_servers(self) -> List[MCPServer]: + def get_public_mcp_servers(self) -> list[MCPServer]: """ Return the MCP servers published to the AI Hub via /v1/mcp/make_public. @@ -3820,7 +4607,7 @@ class MCPServerManager: if server.available_on_public_internet or server.server_id in public_ids ] - def expand_permission_list(self, identifiers: List[str]) -> List[str]: + def expand_permission_list(self, identifiers: list[str]) -> list[str]: """ Expand a permission list of server_ids/names/aliases into concrete server_ids against the current region's config + DB registry union. @@ -3836,12 +4623,12 @@ class MCPServerManager: if not identifiers: return [] registry = self.get_registry() - expanded: Set[str] = set() + expanded: set[str] = set() for identifier in identifiers: if identifier in registry: expanded.add(identifier) continue - matches: List[str] = [ + matches: list[str] = [ server_id for server_id, server in registry.items() if server.alias == identifier or server.server_name == identifier or server.name == identifier @@ -3862,8 +4649,8 @@ class MCPServerManager: def expand_tool_permissions( self, - tool_permissions: Optional[Dict[str, List[str]]], - ) -> Dict[str, List[str]]: + tool_permissions: Optional[dict[str, list[str]]], + ) -> dict[str, list[str]]: """ Rewrite an ``mcp_tool_permissions`` dict keyed by id/name/alias so every key is a concrete server_id where possible. Tool lists from @@ -3878,7 +4665,7 @@ class MCPServerManager: """ if not tool_permissions: return {} - result: Dict[str, List[str]] = {} + result: dict[str, list[str]] = {} for key, tools in tool_permissions.items(): for server_id in self.expand_permission_list([key]): result.setdefault(server_id, []).extend(tools or []) @@ -3919,7 +4706,7 @@ class MCPServerManager: return server return None - def get_filtered_registry(self, client_ip: Optional[str] = None) -> Dict[str, MCPServer]: + def get_filtered_registry(self, client_ip: Optional[str] = None) -> dict[str, MCPServer]: """ Get registry filtered by client IP access control. @@ -4079,16 +4866,23 @@ class MCPServerManager: authorization_url=server.authorization_url, token_url=server.token_url, registration_url=server.registration_url, + oauth2_flow=server.oauth2_flow, + dcr_bridge=server.dcr_bridge, + token_exchange_endpoint=server.token_exchange_endpoint, + audience=server.audience, + subject_token_type=server.subject_token_type, + token_exchange_profile=server.token_exchange_profile, allow_all_keys=server.allow_all_keys, instructions=server.instructions, timeout=server.timeout, + max_concurrent_requests=server.max_concurrent_requests, ) async def get_all_mcp_servers_with_health_and_teams( self, user_api_key_auth: Optional[UserAPIKeyAuth] = None, - server_ids: Optional[List[str]] = None, - ) -> List[LiteLLM_MCPServerTable]: + server_ids: Optional[list[str]] = None, + ) -> list[LiteLLM_MCPServerTable]: """ Get all MCP servers that the user has access to, with health status and team information. @@ -4117,7 +4911,7 @@ class MCPServerManager: async def get_all_allowed_mcp_servers( self, user_api_key_auth: Optional[UserAPIKeyAuth] = None, - ) -> List[LiteLLM_MCPServerTable]: + ) -> list[LiteLLM_MCPServerTable]: """ Get all MCP servers that the user has access to. @@ -4130,7 +4924,7 @@ class MCPServerManager: # Get allowed server IDs allowed_server_ids = await self.get_allowed_mcp_servers(user_api_key_auth) - list_mcp_servers: List[LiteLLM_MCPServerTable] = [] + list_mcp_servers: list[LiteLLM_MCPServerTable] = [] for server_id in allowed_server_ids: server = self.get_mcp_server_by_id(server_id) @@ -4145,8 +4939,8 @@ class MCPServerManager: @staticmethod def _env_vars_to_models( - env_vars: Optional[List[Dict[str, Any]]], - ) -> Optional[List[MCPEnvVar]]: + env_vars: Optional[list[dict[str, Any]]], + ) -> Optional[list[MCPEnvVar]]: if env_vars is None: return None return [MCPEnvVar.model_validate(env_var) for env_var in env_vars] @@ -4166,6 +4960,8 @@ class MCPServerManager: teams=[], mcp_access_groups=server.access_groups or [], allowed_tools=server.allowed_tools or [], + tool_name_to_display_name=server.tool_name_to_display_name, + tool_name_to_description=server.tool_name_to_description, extra_headers=server.extra_headers or [], mcp_info=server.mcp_info, static_headers=server.static_headers, @@ -4179,33 +4975,40 @@ class MCPServerManager: authorization_url=server.authorization_url, token_url=server.token_url, registration_url=server.registration_url, + oauth2_flow=server.oauth2_flow, + token_exchange_endpoint=server.token_exchange_endpoint, + audience=server.audience, + subject_token_type=server.subject_token_type, + token_exchange_profile=server.token_exchange_profile, allow_all_keys=server.allow_all_keys, available_on_public_internet=server.available_on_public_internet, delegate_auth_to_upstream=server.delegate_auth_to_upstream, oauth_passthrough=getattr(server, "oauth_passthrough", False), + dcr_bridge=server.dcr_bridge, is_byok=server.is_byok, byok_description=server.byok_description, byok_api_key_help_url=server.byok_api_key_help_url, source_url=server.source_url, instructions=server.instructions, timeout=server.timeout, + max_concurrent_requests=server.max_concurrent_requests, ) - async def get_all_mcp_servers_unfiltered(self) -> List[LiteLLM_MCPServerTable]: + async def get_all_mcp_servers_unfiltered(self) -> list[LiteLLM_MCPServerTable]: """Return all MCP servers from registry without applying access controls.""" registry = self.get_registry() if not registry: return [] - servers: List[LiteLLM_MCPServerTable] = [] + servers: list[LiteLLM_MCPServerTable] = [] for server in registry.values(): servers.append(self._build_mcp_server_table(server)) return servers async def get_all_mcp_servers_with_health_unfiltered( - self, server_ids: Optional[List[str]] = None - ) -> List[LiteLLM_MCPServerTable]: + self, server_ids: Optional[list[str]] = None + ) -> list[LiteLLM_MCPServerTable]: """Return health info for all servers in registry regardless of user access.""" registry = self.get_registry() @@ -4222,7 +5025,7 @@ class MCPServerManager: return await self._run_health_checks(target_server_ids) - async def _run_health_checks(self, target_server_ids: List[str]) -> List[LiteLLM_MCPServerTable]: + async def _run_health_checks(self, target_server_ids: list[str]) -> list[LiteLLM_MCPServerTable]: if not target_server_ids: return [] diff --git a/litellm/proxy/_experimental/mcp_server/oauth2_flow_backfill.py b/litellm/proxy/_experimental/mcp_server/oauth2_flow_backfill.py new file mode 100644 index 00000000000..02cec2475e2 --- /dev/null +++ b/litellm/proxy/_experimental/mcp_server/oauth2_flow_backfill.py @@ -0,0 +1,155 @@ +"""Startup backfill for oauth2 MCP server rows persisted before oauth2_flow was written. + +Rows created before the write-side stamps (DCR persist, UI create, REST create) carry a +null ``oauth2_flow`` and rely on read-time field-shape inference, which cannot tell a +DCR-registered interactive server from an M2M server unless endpoint discovery succeeds +first. This backfill classifies each null row once, at rest, using signals inference +never had, and persists the result so the read path never has to infer again. + +Signal order, strongest first: + +1. Per-user OAuth token rows exist for the server: only the interactive flow mints + per-user tokens, so this is definitive and immune to the discovery trap. BYOK API + keys share the same table (``LiteLLM_MCPUserCredentials``), so only rows whose + payload decodes as a ``type: oauth2`` token count as proof; bare keys and + undecodable rows prove nothing about the flow. +2. ``authorization_url`` persisted: interactive needs a user-facing authorization + endpoint; M2M (RFC 6749 section 4.4) never has one. +3. ``registration_url`` persisted: dynamic client registration (RFC 7591) exists to mint + clients for the interactive flow; M2M servers are configured with static credentials. +4. ``token_url`` plus decryptable ``client_id`` and ``client_secret``: ambiguous, left + unstamped. The shape is shared by M2M servers and DCR-registered interactive servers + whose authorization endpoint lives only in discovery (registered but never signed + in), so stamping client_credentials here could permanently route per-user traffic + through the proxy's stored client credential. The row keeps working through the + request-time backstop and a warning names it with the one-line fix (set oauth2_flow + via the dashboard or ``PUT /v1/mcp/server``); a completed interactive sign-in also + heals it via rule 1 at the next boot. +5. Anything else is interactive: matching how ``needs_user_oauth_token`` treats a null + flow, so the stamp never changes runtime routing for rows no rule recognizes. + +The backfill never stamps client_credentials: M2M is asserted by a human (config +requires it, the API accepts it, the dashboard sets it), mirroring the config-level +validation error. Runs before the first registry load on every boot and is idempotent: +a healed fleet has no null rows and the backfill exits after one query. +""" + +import json +from collections import Counter +from typing import Any, Literal, Optional + +from litellm._logging import verbose_proxy_logger +from litellm.proxy._experimental.mcp_server.db import _decode_oauth_payload, decrypt_credentials +from litellm.proxy.utils import PrismaClient +from litellm.types.mcp import MCPCredentials + +OAuth2Flow = Literal["client_credentials", "authorization_code"] +BackfillRule = Literal[ + "per_user_tokens", + "authorization_url", + "registration_url", + "ambiguous_m2m_shape", + "interactive_default", +] + +_BACKFILL_AUDIT_ACTOR = "oauth2_flow_backfill" + + +def _decrypted_credentials(raw_credentials: Any) -> Optional[MCPCredentials]: + if raw_credentials is None: + return None + if isinstance(raw_credentials, str): + try: + parsed = json.loads(raw_credentials) + except (ValueError, TypeError): + return None + else: + parsed = raw_credentials + if not isinstance(parsed, dict): + return None + return decrypt_credentials(credentials=dict(parsed)) + + +def classify_null_flow_row( + *, + has_per_user_tokens: bool, + authorization_url: Optional[str], + registration_url: Optional[str], + token_url: Optional[str], + credentials: Optional[MCPCredentials], +) -> tuple[Optional[OAuth2Flow], BackfillRule]: + if has_per_user_tokens: + return "authorization_code", "per_user_tokens" + if authorization_url: + return "authorization_code", "authorization_url" + if registration_url: + return "authorization_code", "registration_url" + if token_url and credentials and credentials.get("client_id") and credentials.get("client_secret"): + return None, "ambiguous_m2m_shape" + return "authorization_code", "interactive_default" + + +async def backfill_null_oauth2_flows(prisma_client: PrismaClient) -> dict[BackfillRule, int]: + """Classify every ``auth_type=oauth2`` row whose ``oauth2_flow`` is null; stamp the provable + ones, warn on the ambiguous ones, and return counts per rule.""" + null_rows: list[Any] = await prisma_client.db.litellm_mcpservertable.find_many( + where={"auth_type": "oauth2", "oauth2_flow": None}, + ) + if not null_rows: + return {} + + server_ids = [row.server_id for row in null_rows] + token_rows: list[Any] = await prisma_client.db.litellm_mcpusercredentials.find_many( + where={"server_id": {"in": server_ids}}, + ) + server_ids_with_oauth_tokens: set[str] = { + token_row.server_id for token_row in token_rows if _decode_oauth_payload(token_row.credential_b64) is not None + } + + classified = tuple( + ( + row, + classify_null_flow_row( + has_per_user_tokens=row.server_id in server_ids_with_oauth_tokens, + authorization_url=row.authorization_url, + registration_url=row.registration_url, + token_url=row.token_url, + credentials=_decrypted_credentials(row.credentials), + ), + ) + for row in null_rows + ) + + for row, (flow, rule) in classified: + if flow is None: + verbose_proxy_logger.warning( + "oauth2_flow backfill: server_id=%s is ambiguous (client credentials + token_url, " + "no interactive signal); left unstamped. Set oauth2_flow explicitly via the " + "dashboard or PUT /v1/mcp/server: client_credentials if this server is M2M, or " + "complete an interactive sign-in and it will be stamped authorization_code at the " + "next boot.", + row.server_id, + ) + else: + verbose_proxy_logger.info( + "oauth2_flow backfill: server_id=%s stamped %s (rule=%s)", + row.server_id, + flow, + rule, + ) + + stamped_flows = {flow for _, (flow, _) in classified if flow is not None} + for stamped_flow in stamped_flows: + server_ids_for_flow = [row.server_id for row, (row_flow, _) in classified if row_flow == stamped_flow] + await prisma_client.db.litellm_mcpservertable.update_many( + where={"server_id": {"in": server_ids_for_flow}, "oauth2_flow": None}, + data={"oauth2_flow": stamped_flow, "updated_by": _BACKFILL_AUDIT_ACTOR}, + ) + + counts: dict[BackfillRule, int] = dict(Counter(rule for _, (_, rule) in classified)) + verbose_proxy_logger.info( + "oauth2_flow backfill: processed %d oauth2 server row(s): %s", + len(null_rows), + counts, + ) + return counts diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/adapter.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/adapter.py index 815fc2ba29d..e87e8081ced 100644 --- a/litellm/proxy/_experimental/mcp_server/outbound_credentials/adapter.py +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/adapter.py @@ -12,7 +12,7 @@ every other mode so the caller defers to v1 (parity-safe); it grows one branch p from __future__ import annotations import base64 -from typing import TYPE_CHECKING, NoReturn, Optional +from typing import TYPE_CHECKING, Literal, NoReturn, Optional from fastapi import HTTPException from pydantic import SecretStr @@ -23,11 +23,13 @@ from litellm.proxy._experimental.mcp_server.outbound_credentials.types import ( AuthorizationCodeConfig, CredError, NoneConfig, + PassthroughConfig, ServerSpec, SharedKey, Subject, + TokenExchangeConfig, ) -from litellm.types.mcp import MCPAuth +from litellm.types.mcp import DEFAULT_SUBJECT_TOKEN_TYPE, MCPAuth if TYPE_CHECKING: from litellm.proxy._types import UserAPIKeyAuth @@ -61,8 +63,10 @@ def to_server_spec(server: MCPServer) -> Optional[ServerSpec]: an ``assert_never`` tail, so a newly added auth mode fails the type gate here until it is explicitly mapped or explicitly deferred, rather than silently falling through to v1. Live modes: ``none``, the static-header family (``api_key`` plus the Authorization schemes, - all shared-key), and ``oauth2`` per-user tokens (``authorization_code``); client_credentials - (M2M), delegated/passthrough oauth2, token exchange, and SigV4 return None and stay on v1. + all shared-key), ``oauth2`` per-user tokens (``authorization_code``), ``oauth2_token_exchange`` + (OBO), and the client-forwarded token modes ``true_passthrough`` / ``oauth_delegate`` + (``PassthroughConfig``); client_credentials (M2M), delegated/passthrough oauth2, and SigV4 + return None and stay on v1. """ if server.is_byok: return None # per-user BYOK source not migrated yet -> defer to v1 (any auth_type) @@ -92,11 +96,49 @@ def to_server_spec(server: MCPServer) -> Optional[ServerSpec]: ) # client_credentials (M2M) and delegate/passthrough oauth2 stay on v1 return None - case MCPAuth.oauth2_token_exchange | MCPAuth.aws_sigv4: - return None # token exchange and SigV4 are not migrated yet -> defer to v1 + case MCPAuth.true_passthrough | MCPAuth.oauth_delegate: + return ServerSpec(server_id=server.server_id, resource=resource, config=PassthroughConfig()) + case MCPAuth.oauth2_token_exchange: + return _token_exchange_spec(server, resource) + case MCPAuth.aws_sigv4: + return None # SigV4 is not migrated yet -> defer to v1 assert_never(auth_type) +def _token_exchange_spec(server: MCPServer, resource: str) -> Optional[ServerSpec]: + """Build a token_exchange (OBO) spec, or defer (None) when it is not OBO-configured. + + An OBO server with ``client_id``/``client_secret`` is owned by the v2 arm even if the + ``token_exchange_endpoint``/``token_url`` is absent: a missing endpoint then fails closed (412) at + the exchanger rather than silently deferring to v1 and connecting unauthenticated, since the + gateway must not guess the IdP or fall back to a weaker source. Without client credentials there is + nothing to own, so the server stays on v1 (parity-safe). ``profile`` selects the wire dialect + (``rfc8693`` default, ``entra_obo`` for Microsoft Entra On-Behalf-Of); an unrecognized value + normalizes to ``rfc8693`` so a bad config value cannot crash spec-building. ``audience`` is + forwarded only when the operator set it; a missing one is omitted, not derived. + """ + endpoint = server.token_exchange_endpoint or server.token_url + if not server.client_id or not server.client_secret: + return None + profile: Literal["rfc8693", "entra_obo"] = ( + "entra_obo" if server.token_exchange_profile == "entra_obo" else "rfc8693" + ) + return ServerSpec( + server_id=server.server_id, + resource=resource, + config=TokenExchangeConfig( + profile=profile, + subject_token_type=server.subject_token_type or DEFAULT_SUBJECT_TOKEN_TYPE, + token_exchange_endpoint=endpoint, + audience=server.audience, + client_id=server.client_id, + client_secret=SecretStr(server.client_secret), + token_endpoint_auth_method=server.token_endpoint_auth_method, + scopes=tuple(server.scopes or ()), + ), + ) + + def _shared_key_spec( server: MCPServer, resource: str, @@ -148,23 +190,75 @@ def raise_public(error: CredError) -> NoReturn: assert_never(error.tag) -def raise_user_oauth_challenge(server: MCPServer) -> NoReturn: +def oauth_protected_resource_path(root_path: str, server: MCPServer) -> str: + """The server's RFC 9728 Protected Resource Metadata path, the shared anchor of both challenges. + + ``root_path`` is the proxy's ``SERVER_ROOT_PATH``, resolved by the caller (the imperative shell) + so this stays a pure function of its inputs; ``"/"`` and ``""`` both mean no prefix. The path is + relative, so it resolves against the caller's own host (correct even behind a reverse proxy). + """ + prefix = "" if root_path == "/" else root_path + name = server.alias or server.server_name or server.name or server.server_id + return f"/.well-known/oauth-protected-resource{prefix}/mcp/{name}" + + +def raise_user_oauth_challenge(server: MCPServer, *, root_path: str) -> NoReturn: """Raise the 401 an ``authorization_code`` server returns at egress when the user has no token. - Points at the server's RFC 9728 Protected Resource Metadata (``resource_metadata``), which names - the upstream authorization server the client must complete OAuth with. The URL is per-server and - relative, so it resolves against the caller's own host (correct even behind a reverse proxy) - without needing request context. The listing-phase 401 still emits the RFC 8414 ``authorization_uri`` - form pending the format unification; both target the same server, so the difference is cosmetic. + Points at the server's RFC 9728 Protected Resource Metadata, which names the upstream + authorization server the client must complete OAuth with. The listing-phase 401 still emits the + RFC 8414 ``authorization_uri`` form pending the format unification; both target the same server, + so the difference is cosmetic. """ - from litellm.proxy.utils import get_server_root_path # noqa: PLC0415 - - root = get_server_root_path() - prefix = "" if root == "/" else root - name = server.alias or server.server_name or server.name or server.server_id - resource_metadata = f"/.well-known/oauth-protected-resource{prefix}/mcp/{name}" + resource_metadata = oauth_protected_resource_path(root_path, server) raise HTTPException( status_code=401, detail="Unauthorized", headers={"WWW-Authenticate": f'Bearer resource_metadata="{resource_metadata}"'}, ) + + +def raise_token_exchange_challenge( + server: MCPServer, + *, + root_path: str, + claims: str | None = None, +) -> NoReturn: + """Raise the RFC 9728 / RFC 6750 challenge an OBO (``token_exchange``) server returns when the + caller's subject token is missing or the IdP rejected it. + + Points at the server's Protected Resource Metadata, whose ``authorization_servers`` names the IdP + the client must SSO with to obtain a subject token; ``error="invalid_token"`` tells a + spec-compliant MCP client to discover that AS and retry with a fresh bearer. Mirrors + ``raise_user_oauth_challenge`` but for the exchange flow: there is no gateway-side browser OAuth — + the client re-authenticates directly with the IdP, and LiteLLM then exchanges the resulting token. + + An IdP step-up rejection (Entra Conditional Access / CAE) passes its ``claims`` blob. Per the + Microsoft claims-challenge format the challenge then uses ``error="insufficient_claims"`` (the + value MSAL-family clients key on) and carries the claims base64-encoded in a ``claims`` parameter + the client replays to the IdP to satisfy the step-up. Without a claims blob the challenge keeps + ``error="invalid_token"`` and is byte-identical to the static one. Both the error value (one of + two literals) and the base64 claims draw from a fixed alphabet, so nothing from the IdP body + reaches the header unescaped. + """ + resource_metadata = oauth_protected_resource_path(root_path, server) + encoded_claims = base64.b64encode(claims.encode()).decode() if claims else None + error = "insufficient_claims" if encoded_claims else "invalid_token" + error_description = ( + "Step-up authentication required; satisfy the returned claims challenge with the IdP and retry" + if encoded_claims + else "Missing or invalid subject token; authenticate with the IdP and retry" + ) + www_authenticate = ", ".join( + ( + f'Bearer resource_metadata="{resource_metadata}"', + f'error="{error}"', + f'error_description="{error_description}"', + *((f'claims="{encoded_claims}"',) if encoded_claims else ()), + ) + ) + raise HTTPException( + status_code=401, + detail="Unauthorized", + headers={"WWW-Authenticate": www_authenticate}, + ) diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/bridge_credentials.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/bridge_credentials.py new file mode 100644 index 00000000000..5530fbc46fd --- /dev/null +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/bridge_credentials.py @@ -0,0 +1,169 @@ +"""Producer and consumer helpers for the DCR-bridge ``oauth_delegate`` envelope. + +A DCR-bridge ``oauth_delegate`` client presents ONE bearer that is a litellm-signed +envelope (see :mod:`.envelope`) carrying both a litellm identity and the upstream OAuth +token. The gateway token endpoint mints it (producer) at OAuth issuance, and at the MCP +admission edge the gateway derives the envelope keys from the proxy ``master_key``, opens +it, admits the request under the recovered identity, and forwards the inner upstream token +to the upstream MCP server (consumer). This module is the pure surface for both sides; the +token-endpoint and admission wiring live in their respective call sites. +""" + +import hashlib +from datetime import datetime +from functools import lru_cache +from typing import Literal, TypeAlias + +from pydantic import BaseModel, ConfigDict, SecretStr + +from litellm.proxy._experimental.mcp_server.outbound_credentials.envelope import ( + EnvelopeIdentity, + EnvelopeKeys, + EnvelopeMintError, + OpenedEnvelope, + SealedEnvelope, + UpstreamTokenGrant, + is_envelope, + mint_envelope, + open_envelope, +) + +_SIGNING_KEY_DOMAIN = b"litellm-mcp-bridge:envelope-signing:" +_ENCRYPTION_KEY_DOMAIN = b"litellm-mcp-bridge:envelope-encryption:" + +# scrypt work factors (RFC 7914). n=2**15 with r=8/p=1 costs ~50ms and ~32MB per derivation, which +# makes offline guessing of a candidate master key memory-hard rather than a bare hash comparison. +_SCRYPT_N = 2**15 +_SCRYPT_R = 8 +_SCRYPT_P = 1 +# scrypt's working-set is ~128 * N * r * p bytes; cap at twice that so the maxmem ceiling scales +# with every work factor and a future p or r bump does not trip "memory limit exceeded". +_SCRYPT_MAXMEM = 128 * _SCRYPT_N * _SCRYPT_R * _SCRYPT_P * 2 +_DERIVED_KEY_BYTES = 32 + + +@lru_cache(maxsize=8) +def envelope_keys_from_master_key(master_key: str) -> EnvelopeKeys: + """Derive the envelope signing and encryption keys from the proxy master key. + + A memory-hard scrypt KDF (RFC 7914) over two distinct domain-label salts yields two + independent 256-bit subkeys from the one secret, so the producer (mint) and consumer + (open) agree on keys without persisting any. scrypt is used rather than a bare hash or + HMAC so that a captured envelope is not a cheap offline oracle for the master key: each + candidate guess costs a full memory-hard derivation, which is what protects a deployment + whose master key is weaker than it should be. The result is cached (the master key is + fixed for a process), so the KDF runs once per key and adds nothing to the per-request + admission path. The derivation is deterministic; rotating ``master_key`` invalidates + every outstanding envelope, which is the intended behavior for a signing-key change. + """ + signing = hashlib.scrypt( + master_key.encode(), + salt=_SIGNING_KEY_DOMAIN, + n=_SCRYPT_N, + r=_SCRYPT_R, + p=_SCRYPT_P, + maxmem=_SCRYPT_MAXMEM, + dklen=_DERIVED_KEY_BYTES, + ).hex() + encryption = hashlib.scrypt( + master_key.encode(), + salt=_ENCRYPTION_KEY_DOMAIN, + n=_SCRYPT_N, + r=_SCRYPT_R, + p=_SCRYPT_P, + maxmem=_SCRYPT_MAXMEM, + dklen=_DERIVED_KEY_BYTES, + ).hex() + return EnvelopeKeys(signing_key=SecretStr(signing), encryption_key=SecretStr(encryption)) + + +def build_bridge_token_response( + identity: EnvelopeIdentity, + grant: UpstreamTokenGrant, + keys: EnvelopeKeys, + now: datetime, +) -> SealedEnvelope | EnvelopeMintError: + """Seal ``grant`` for ``identity`` into the client-held bearer the token endpoint returns. + + The producer mirror of :func:`resolve_bridge_envelope`: a thin, pure wrapper over + :func:`mint_envelope` that returns the sealed envelope, or the mint error as a value + (an oversized grant) for the caller to map onto an OAuth error response. + """ + return mint_envelope(identity, grant, keys, now) + + +class NotBridgeEnvelope(BaseModel): + """The bearer is not an envelope; admission continues on its normal path.""" + + model_config = ConfigDict(frozen=True) + tag: Literal["not_bridge_envelope"] = "not_bridge_envelope" + + +class BridgeEnvelopeAdmitted(BaseModel): + """A valid envelope: the identity to admit under and the full upstream ``Authorization`` + value (``token_type access_token``) to forward to the upstream MCP server.""" + + model_config = ConfigDict(frozen=True) + tag: Literal["admitted"] = "admitted" + identity: EnvelopeIdentity + upstream_authorization: SecretStr + + +class BridgeEnvelopeInvalid(BaseModel): + """The bearer is envelope-shaped but did not open (expired, tampered, wrong key); + admission must fail closed rather than fall through to normal validation.""" + + model_config = ConfigDict(frozen=True) + tag: Literal["invalid"] = "invalid" + + +BridgeEnvelopeResult: TypeAlias = NotBridgeEnvelope | BridgeEnvelopeAdmitted | BridgeEnvelopeInvalid + + +def _strip_bearer(value: str) -> str: + parts = value.split(None, 1) + if len(parts) == 2 and parts[0].lower() == "bearer": + return parts[1] + return value + + +def is_bridge_envelope_shaped(authorization_value: str) -> bool: + """Cheap, keyless test that an ``Authorization`` value carries an envelope (optional + ``Bearer`` scheme stripped). The admission edge engages the bridge arm only for an + envelope, so a plain upstream bearer falls through to normal oauth2 admission.""" + return is_envelope(_strip_bearer(authorization_value)) + + +def resolve_bridge_envelope( + authorization_value: str, + keys: EnvelopeKeys, + now: datetime, + expected_server_id: str, +) -> BridgeEnvelopeResult: + """Classify an ``Authorization`` value presented to a bridge ``oauth_delegate`` server. + + Strips an optional ``Bearer`` scheme, then returns ``NotBridgeEnvelope`` for a + non-envelope bearer (normal admission continues), ``BridgeEnvelopeAdmitted`` with the + recovered identity and the upstream ``Authorization`` value to forward for a valid + envelope, and ``BridgeEnvelopeInvalid`` for an envelope-shaped bearer that will not + open. Never raises: it is total over hostile input via :func:`open_envelope`. + + ``expected_server_id`` is the ``server_id`` of the MCP server the request targets; an + opened envelope whose sealed ``server_id`` does not match is rejected as + ``BridgeEnvelopeInvalid``. Binding here (rather than leaving it to the caller) prevents + replaying an envelope minted for one server against another, which would forward the + first server's upstream credential across a server boundary. ``server_id`` is not a + secret (the caller targets that server), so a plain equality check is sufficient and, + unlike ``hmac.compare_digest`` on ``str``, does not raise on a non-ASCII server_id. + """ + candidate = _strip_bearer(authorization_value) + if not is_envelope(candidate): + return NotBridgeEnvelope() + opened = open_envelope(candidate, keys, now) + if not isinstance(opened, OpenedEnvelope): + return BridgeEnvelopeInvalid() + if opened.identity.server_id != expected_server_id: + return BridgeEnvelopeInvalid() + grant = opened.grant + upstream_authorization = f"{grant.token_type} {grant.access_token.get_secret_value()}" + return BridgeEnvelopeAdmitted(identity=opened.identity, upstream_authorization=SecretStr(upstream_authorization)) diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/envelope.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/envelope.py new file mode 100644 index 00000000000..298bc8d98cc --- /dev/null +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/envelope.py @@ -0,0 +1,358 @@ +"""Client-held sealed envelope for the oauth_delegate DCR bridge. + +A DCR-bridge client holds ONE bearer that must carry BOTH a litellm identity and the +upstream OAuth grant, with zero server-side storage. The gateway token endpoint mints a +litellm-signed envelope (:func:`mint_envelope`); the MCP edge validates it, recovers the +identity claims and the inner upstream grant (:func:`open_envelope`), and forwards the +inner access token upstream. This module is pure and unwired: it imports nothing from +endpoint or edge code, reads no proxy globals, and takes all key material and the clock +as explicit parameters. + +Wire shape: ``llm_env_`` + an HS256 JWT (same signing approach as the BYOK session +bearer in ``byok_oauth_endpoints.py``). Registered claims are ``iss``/``iat``/``exp``; +custom claims are ``user_id``, ``server_id``, and ``grant``, where ``grant`` is the +upstream token grant serialized to JSON, encrypted with the repo's symmetric +encryption helpers (``encrypt_value``/``decrypt_value`` from +``encrypt_decrypt_utils`` — the same family ``encrypt_value_helper`` applies to +persisted DCR credentials), and base64url-encoded, so the inner token never appears +in plaintext anywhere in the envelope. + +Failures are values: :func:`open_envelope` returns one of the frozen +``EnvelopeOpenError`` variants (discriminated on ``tag``) for invalid, expired, +tampered, or undecryptable input, and :func:`mint_envelope` returns +``EnvelopeTooLarge`` for oversized grants. Error values carry tags and sizes only, +never token material. + +The pydantic input models reject programmer errors at construction (e.g. a +non-positive ``expires_in`` or an empty required field). :func:`open_envelope` is +additionally total over hostile, attacker-controlled input: it never raises, only +returns an ``EnvelopeOpenError``. :func:`mint_envelope` operates on a +gateway-supplied grant (an upstream IdP's UTF-8 JSON token response), so it does not +defend against non-UTF-8 field content that cannot survive JSON parsing; its only +value-typed failure is ``EnvelopeTooLarge``. +""" + +from __future__ import annotations + +import base64 +from datetime import datetime, timedelta +from typing import Literal, TypeAlias + +import jwt +from pydantic import BaseModel, ConfigDict, Field, SecretStr, ValidationError + +from litellm.proxy.common_utils.encrypt_decrypt_utils import decrypt_value, encrypt_value + +ENVELOPE_PREFIX = "llm_env_" +"""Marker prefix on every serialized envelope so the edge can cheaply tell an envelope +from a raw upstream token before doing any cryptography.""" + +ENVELOPE_ISSUER = "litellm-mcp-bridge" +"""``iss`` claim stamped into every envelope and required back on open.""" + +MAX_ENVELOPE_TTL_SECONDS = 3600 +"""Hard ceiling on envelope lifetime. ``exp`` is ``min(upstream expires_in, this cap)`` +(the cap alone when the upstream omits ``expires_in``), matching the 1h lifetime of the +BYOK session bearer this module's signing approach is borrowed from: a client-held +credential should never outlive a bounded window even when the upstream token does.""" + +MAX_ENVELOPE_BYTES = 12288 +"""Size cap on the final serialized envelope (prefix + JWT, in bytes). Upstream JWTs +commonly run 2-4KB; base64 plus encryption overhead roughly doubles that inside the +envelope, and common proxy/server header limits sit around 16KB total. 12288 leaves +comfortable headroom for a large upstream token while keeping the envelope safely +transmittable as a single Authorization header. Oversized grants are rejected with a +typed error, never truncated.""" + +_ENVELOPE_JWT_ALGORITHM = "HS256" + + +class EnvelopeIdentity(BaseModel): + """The litellm identity the envelope binds the inner grant to.""" + + model_config = ConfigDict(frozen=True) + user_id: str = Field(min_length=1) + server_id: str = Field(min_length=1) + + +class UpstreamTokenGrant(BaseModel): + """The upstream OAuth token response fields sealed inside the envelope. + + ``expires_in`` must be positive when present; a non-positive value is a programmer + error rejected at construction. Token fields are ``SecretStr`` so reprs never leak + them. + """ + + model_config = ConfigDict(frozen=True) + access_token: SecretStr = Field(min_length=1) + token_type: str = Field(min_length=1) + refresh_token: SecretStr | None = None + scope: str | None = None + expires_in: int | None = Field(default=None, gt=0) + + +class EnvelopeKeys(BaseModel): + """Injected key material: the HS256 signing key and the symmetric encryption key. + + ``signing_key`` must be at least 32 bytes: HS256's HMAC-SHA256 has a 256-bit + security level, RFC 7518 requires a key of at least that size, and a shorter key + makes PyJWT emit ``InsecureKeyLengthWarning``. + """ + + model_config = ConfigDict(frozen=True) + signing_key: SecretStr = Field(min_length=32) + encryption_key: SecretStr = Field(min_length=1) + + +class SealedEnvelope(BaseModel): + """A minted envelope: the client-held bearer value and when it expires.""" + + model_config = ConfigDict(frozen=True) + token: SecretStr + expires_at: datetime + + +class OpenedEnvelope(BaseModel): + """A validated envelope: the identity it was minted for and the recovered grant.""" + + model_config = ConfigDict(frozen=True) + identity: EnvelopeIdentity + grant: UpstreamTokenGrant + + +class EnvelopeTooLarge(BaseModel): + """The serialized envelope exceeded ``MAX_ENVELOPE_BYTES``; carries sizes only.""" + + model_config = ConfigDict(frozen=True) + tag: Literal["envelope_too_large"] = "envelope_too_large" + size_bytes: int + max_bytes: int + + +EnvelopeMintError: TypeAlias = EnvelopeTooLarge + + +class NotAnEnvelope(BaseModel): + """The candidate does not carry the envelope prefix.""" + + model_config = ConfigDict(frozen=True) + tag: Literal["not_an_envelope"] = "not_an_envelope" + + +class BadSignature(BaseModel): + """The JWT signature does not verify under the provided signing key.""" + + model_config = ConfigDict(frozen=True) + tag: Literal["bad_signature"] = "bad_signature" + + +class Expired(BaseModel): + """The envelope's ``exp`` is not in the future relative to the provided ``now``.""" + + model_config = ConfigDict(frozen=True) + tag: Literal["expired"] = "expired" + + +class MalformedPayload(BaseModel): + """The token is not a well-formed envelope: undecodable JWT, wrong issuer, missing + or mistyped claims, or a decrypted grant that fails validation.""" + + model_config = ConfigDict(frozen=True) + tag: Literal["malformed_payload"] = "malformed_payload" + + +class DecryptFailed(BaseModel): + """The signed ``grant`` blob could not be decrypted under the provided key.""" + + model_config = ConfigDict(frozen=True) + tag: Literal["decrypt_failed"] = "decrypt_failed" + + +EnvelopeOpenError: TypeAlias = NotAnEnvelope | BadSignature | Expired | MalformedPayload | DecryptFailed + + +class _EnvelopeClaims(BaseModel): + """Decoded-claims boundary that pins the exact shape :func:`mint_envelope` emits. + + ``user_id``/``server_id`` mirror the ``min_length`` constraints of + :class:`EnvelopeIdentity` so any claim set that validates here also constructs an + identity, keeping :func:`open_envelope` raise-free: a correctly signed JWT with an + empty identity claim fails here and maps to ``MalformedPayload``. + + ``strict`` rejects coerced types (``exp: "123"``, ``exp: 123.0``) rather than opening + on them, and ``extra="forbid"`` rejects any claim the gateway never mints (a hostile + ``nbf``/``aud``/... rides along on a re-signed token). Since PyJWT's own ``iat``/ + ``nbf``/``exp`` validators are disabled at decode (they raise on hostile claim types + and, for ``iat``/``nbf``, compare against the wall clock rather than the injected + ``now``), this model is the sole, total type gate for every registered claim. + """ + + model_config = ConfigDict(frozen=True, strict=True, extra="forbid") + iss: str + iat: int + exp: int + user_id: str = Field(min_length=1) + server_id: str = Field(min_length=1) + grant: str = Field(min_length=1) + + +class _GrantWire(BaseModel): + model_config = ConfigDict(frozen=True) + access_token: str + token_type: str + refresh_token: str | None = None + scope: str | None = None + expires_in: int | None = None + + +def is_envelope(candidate: str) -> bool: + """Cheap prefix check so the edge can route envelopes vs raw tokens without crypto.""" + return candidate.startswith(ENVELOPE_PREFIX) + + +def mint_envelope( + identity: EnvelopeIdentity, + grant: UpstreamTokenGrant, + keys: EnvelopeKeys, + now: datetime, +) -> SealedEnvelope | EnvelopeMintError: + """Seal ``grant`` for ``identity`` into a client-held envelope. + + ``exp`` is ``min(grant.expires_in, MAX_ENVELOPE_TTL_SECONDS)`` seconds from ``now`` + (the cap alone when ``expires_in`` is absent). Returns ``EnvelopeTooLarge`` when the + serialized envelope exceeds ``MAX_ENVELOPE_BYTES``. + """ + expires_at = now + timedelta(seconds=_envelope_ttl_seconds(grant.expires_in)) + claims = _EnvelopeClaims( + iss=ENVELOPE_ISSUER, + iat=int(now.timestamp()), + exp=int(expires_at.timestamp()), + user_id=identity.user_id, + server_id=identity.server_id, + grant=_encrypt_grant_blob(_grant_plaintext(grant), keys.encryption_key), + ) + token = ENVELOPE_PREFIX + jwt.encode( + claims.model_dump(), + keys.signing_key.get_secret_value(), + algorithm=_ENVELOPE_JWT_ALGORITHM, + ) + size_bytes = len(token.encode("utf-8")) + if size_bytes > MAX_ENVELOPE_BYTES: + return EnvelopeTooLarge(size_bytes=size_bytes, max_bytes=MAX_ENVELOPE_BYTES) + return SealedEnvelope(token=SecretStr(token), expires_at=expires_at) + + +def open_envelope( + candidate: str, + keys: EnvelopeKeys, + now: datetime, +) -> OpenedEnvelope | EnvelopeOpenError: + """Validate ``candidate`` and recover the identity and inner grant. + + Never raises for bad input: every invalid, expired, tampered, or undecryptable + candidate maps to a distinct ``EnvelopeOpenError`` variant. The recovered + ``grant.expires_in`` is the value the upstream reported at mint time and is not + re-derived, so it is stale by up to the envelope's lifetime; callers that need a + live remaining lifetime should use ``now`` against the upstream, not this field. + """ + if not is_envelope(candidate): + return NotAnEnvelope() + # UTF-8 byte length is never below character length, so a character count already over the + # cap rejects an oversize candidate in O(1) without encoding it; the exact byte check then + # runs only on candidates already bounded to <= MAX_ENVELOPE_BYTES characters. + if len(candidate) > MAX_ENVELOPE_BYTES: + return MalformedPayload() + if len(candidate.encode("utf-8", "surrogatepass")) > MAX_ENVELOPE_BYTES: + return MalformedPayload() + claims = _decode_claims(candidate.removeprefix(ENVELOPE_PREFIX), keys.signing_key) + if not isinstance(claims, _EnvelopeClaims): + return claims + if now.timestamp() >= claims.exp: + return Expired() + grant = _decrypt_grant(claims.grant, keys.encryption_key) + if not isinstance(grant, UpstreamTokenGrant): + return grant + return OpenedEnvelope( + identity=EnvelopeIdentity(user_id=claims.user_id, server_id=claims.server_id), + grant=grant, + ) + + +def _envelope_ttl_seconds(upstream_expires_in: int | None) -> int: + if upstream_expires_in is None: + return MAX_ENVELOPE_TTL_SECONDS + return min(upstream_expires_in, MAX_ENVELOPE_TTL_SECONDS) + + +def _grant_plaintext(grant: UpstreamTokenGrant) -> str: + wire = _GrantWire( + access_token=grant.access_token.get_secret_value(), + token_type=grant.token_type, + refresh_token=None if grant.refresh_token is None else grant.refresh_token.get_secret_value(), + scope=grant.scope, + expires_in=grant.expires_in, + ) + return wire.model_dump_json(exclude_none=True) + + +def _decode_claims( + compact: str, + signing_key: SecretStr, +) -> _EnvelopeClaims | BadSignature | MalformedPayload: + """Verify the HS256 signature and shape of an attacker-controlled compact JWT. + + ``compact`` is fully hostile and bounded to ``MAX_ENVELOPE_BYTES`` by the caller. + PyJWT's ``iat``/``nbf``/``exp`` validators are disabled: they raise on hostile claim + types and, for ``iat``/``nbf``, compare against the wall clock rather than the + injected ``now`` (``exp`` is checked by the caller against ``now``). Apart from a + signature mismatch (``BadSignature``), every decode failure is ``MalformedPayload``: + a non-UTF-8 candidate surfaces as ``UnicodeEncodeError`` (a ``ValueError``), a + non-string registered claim such as ``iss`` as a ``TypeError`` from PyJWT's claim + validators, and a wrong issuer or structurally invalid token as an + ``InvalidTokenError``. ``_EnvelopeClaims`` is the total type gate for the payload. + """ + try: + payload = jwt.decode( + compact, + signing_key.get_secret_value(), + algorithms=[_ENVELOPE_JWT_ALGORITHM], + issuer=ENVELOPE_ISSUER, + options={ + "verify_exp": False, + "verify_iat": False, + "verify_nbf": False, + "require": ["iss", "iat", "exp"], + }, + ) + except jwt.InvalidSignatureError: + return BadSignature() + except (jwt.InvalidTokenError, ValueError, TypeError): + return MalformedPayload() + try: + return _EnvelopeClaims.model_validate(payload) + except ValidationError: + return MalformedPayload() + + +def _encrypt_grant_blob(plaintext: str, encryption_key: SecretStr) -> str: + ciphertext = bytes(encrypt_value(value=plaintext, signing_key=encryption_key.get_secret_value())) + return base64.urlsafe_b64encode(ciphertext).decode("ascii") + + +def _decrypt_grant( + blob: str, + encryption_key: SecretStr, +) -> UpstreamTokenGrant | DecryptFailed | MalformedPayload: + from nacl.exceptions import CryptoError + + try: + plaintext = decrypt_value( + value=base64.urlsafe_b64decode(blob), + signing_key=encryption_key.get_secret_value(), + ) + except (CryptoError, ValueError): + return DecryptFailed() + try: + return UpstreamTokenGrant.model_validate_json(plaintext) + except ValidationError: + return MalformedPayload() diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/oauth_token_store.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/oauth_token_store.py index fd2cb2f3e06..c1c70cf9050 100644 --- a/litellm/proxy/_experimental/mcp_server/outbound_credentials/oauth_token_store.py +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/oauth_token_store.py @@ -69,6 +69,17 @@ class OAuthTokenStore(Protocol): async def fetch(self, user_id: str, server_id: str) -> OAuthToken | None: ... +class InvalidatableOAuthTokenStore(OAuthTokenStore, Protocol): + """An ``OAuthTokenStore`` whose cached entry for a ``(user, server)`` pair can be dropped. + + The write side calls ``invalidate`` after a (re)authorization or revocation changes the + credential row, so reads stop serving the replaced token immediately instead of until its + cache TTL. ``CachedOAuthTokenStore`` (the top of the per-user chain) satisfies this. + """ + + async def invalidate(self, user_id: str, server_id: str) -> None: ... + + class TokenRefresher(Protocol): """Mints a fresh token from an expired one and persists it, returning the new token. diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/per_user_oauth_store.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/per_user_oauth_store.py index 3bc10f1a0eb..21001c09f25 100644 --- a/litellm/proxy/_experimental/mcp_server/outbound_credentials/per_user_oauth_store.py +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/per_user_oauth_store.py @@ -24,8 +24,8 @@ from litellm.proxy._experimental.mcp_server.outbound_credentials.dual_cache_toke ) from litellm.proxy._experimental.mcp_server.outbound_credentials.oauth_token_store import ( CachedOAuthTokenStore, + InvalidatableOAuthTokenStore, OAuthToken, - OAuthTokenStore, RefreshCoordinator, RefreshingTokenStore, TokenCacheBackend, @@ -51,7 +51,7 @@ if TYPE_CHECKING: _DEFAULT_TTL_SECONDS = 300.0 ServerLookup = Callable[[str], "MCPServer | None"] -StoreBuilder = Callable[[ServerLookup], tuple[OAuthTokenStore, bool]] +StoreBuilder = Callable[[ServerLookup], tuple[InvalidatableOAuthTokenStore, bool]] async def _read_credential(user_id: str, server_id: str) -> dict[str, object] | None: @@ -185,7 +185,7 @@ class LazyPerUserOAuthTokenStore: self._server_lookup = server_lookup self._store_builder = store_builder self._redis_available = redis_available - self._store: OAuthTokenStore | None = None + self._store: InvalidatableOAuthTokenStore | None = None self._uses_redis = False self._fetch_lock = asyncio.Condition() self._local_fetches = 0 @@ -203,7 +203,26 @@ class LazyPerUserOAuthTokenStore: if not uses_redis: await self._finish_local_fetch() - async def _store_for_fetch(self) -> tuple[OAuthTokenStore, bool]: + async def invalidate(self, user_id: str, server_id: str) -> None: + """Drop the chain's cached entry for ``(user_id, server_id)`` after the credential row + changes (re-auth, revoke). Builds the chain if no fetch has run yet, so a shared (Redis) + cache entry written by another worker is dropped too; the in-process case is then a no-op + on an empty cache. + """ + if self._uses_redis: + store = self._store + if store is not None: + await store.invalidate(user_id, server_id) + return + + store, uses_redis = await self._store_for_fetch() + try: + await store.invalidate(user_id, server_id) + finally: + if not uses_redis: + await self._finish_local_fetch() + + async def _store_for_fetch(self) -> tuple[InvalidatableOAuthTokenStore, bool]: async with self._fetch_lock: while ( self._store is not None and not self._uses_redis and self._redis_available() and self._local_fetches > 0 diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/resolver.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/resolver.py index f9a9fa00b23..ecfd471190c 100644 --- a/litellm/proxy/_experimental/mcp_server/outbound_credentials/resolver.py +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/resolver.py @@ -7,9 +7,11 @@ no precedence cascade. It is wildcard-free with an `assert_never` tail, so addin an arm fails the type gate (basedpyright `reportMatchNotExhaustive`); a bypassed gate fails loudly at runtime instead of returning `None`. -`none` and `api_key` (shared-key source) are live, as is `authorization_code`, which reads the -user's token from the injected `OAuthTokenStore`. The remaining arms are `not_implemented` stubs -that each land in a follow-up PR with their seam. Pure v2: no imports from v1. +`none`, `api_key` (shared-key source), and `passthrough` (forwards the caller's own inbound token) +are live, as is `authorization_code`, which reads the user's token from the injected +`OAuthTokenStore`, and `token_exchange`, which swaps the caller's inbound token through the +injected `TokenExchanger`. The remaining arms are `not_implemented` stubs that each land in a +follow-up PR with their seam. Pure v2: no imports from v1. """ from __future__ import annotations @@ -31,6 +33,9 @@ from litellm.proxy._experimental.mcp_server.outbound_credentials.result import ( Ok, Result, ) +from litellm.proxy._experimental.mcp_server.outbound_credentials.token_exchanger import ( + TokenExchanger, +) from litellm.proxy._experimental.mcp_server.outbound_credentials.types import ( ApiKeyConfig, AuthorizationCodeConfig, @@ -55,16 +60,36 @@ class _NullOAuthTokenStore: return None +class _NullTokenExchanger: + """Fail-closed default: with no exchanger wired, token_exchange cannot produce a credential.""" + + async def exchange( + self, subject_token: str, server: ServerSpec, config: TokenExchangeConfig, *, tenant_id: str = "" + ) -> Result[OAuthToken, CredError]: + return Error(CredError.of_misconfigured("token exchange collaborator not wired")) + + async def invalidate( + self, subject_token: str, server: ServerSpec, config: TokenExchangeConfig, *, tenant_id: str = "" + ) -> None: + return None + + class UpstreamCredentialProvider: """Produces the one `httpx.Auth` for a `(subject, upstream)` pair, per declared mode. Collaborators (the per-mode credential stores and token fetchers) are injected as each arm is built; the live `none` and `api_key`-shared arms read from the config and need none, while - `authorization_code` reads the user's token from the injected `OAuthTokenStore`. + `authorization_code` reads the user's token from the injected `OAuthTokenStore` and + `token_exchange` swaps the caller's token through the injected `TokenExchanger`. """ - def __init__(self, oauth_token_store: OAuthTokenStore | None = None) -> None: + def __init__( + self, + oauth_token_store: OAuthTokenStore | None = None, + token_exchanger: TokenExchanger | None = None, + ) -> None: self._oauth_token_store: OAuthTokenStore = oauth_token_store or _NullOAuthTokenStore() + self._token_exchanger: TokenExchanger = token_exchanger or _NullTokenExchanger() async def resolve_credentials(self, subject: Subject, server: ServerSpec) -> Result[httpx.Auth, CredError]: match server.config: @@ -73,11 +98,11 @@ class UpstreamCredentialProvider: case ApiKeyConfig() as config: return self._api_key(config) case PassthroughConfig(): - return _not_implemented(AuthSpecKind.passthrough) + return self._passthrough(subject) case ClientCredentialsConfig(): return _not_implemented(AuthSpecKind.client_credentials) - case TokenExchangeConfig(): - return _not_implemented(AuthSpecKind.token_exchange) + case TokenExchangeConfig() as config: + return await self._token_exchange(subject, server, config) case AuthorizationCodeConfig(): return await self._authorization_code(subject, server) case AwsSigV4Config(): @@ -94,6 +119,18 @@ class UpstreamCredentialProvider: """ return await self._authz_token(subject, server) is not None + def _passthrough(self, subject: Subject) -> Result[httpx.Auth, CredError]: + """Forward the caller's own upstream credential verbatim; the gateway mints nothing. + + The inbound token is the caller's already-disambiguated ``Authorization`` (never the LiteLLM + admission credential; the edge adapter drops that before building the ``Subject``). When it is + absent the request is sent unauthenticated so the upstream's own 401 surfaces, rather than the + gateway challenging on the upstream's behalf. + """ + if subject.inbound_token is None: + return Ok(NoOpAuth()) + return Ok(StaticHeaderAuth(subject.inbound_token.get_secret_value(), header_name="Authorization")) + def _api_key(self, config: ApiKeyConfig) -> Result[httpx.Auth, CredError]: match config.key_source: case SharedKey() as source: @@ -110,6 +147,43 @@ class UpstreamCredentialProvider: return Error(CredError.of_unauthorized("Authorization required: complete the OAuth flow for this server.")) return Ok(StaticHeaderAuth(f"Bearer {token.access_token}", header_name="Authorization")) + async def _token_exchange( + self, subject: Subject, server: ServerSpec, config: TokenExchangeConfig + ) -> Result[StaticHeaderAuth, CredError]: + """RFC 8693 OBO: exchange the caller's inbound token for an upstream-bound bearer. + + No inbound token means there is nothing to exchange, so the arm fails closed with a 401 rather + than falling through to a weaker source (§1.5); the exchanger handles the IdP round-trip and + caching and returns the upstream token or a typed error. + """ + inbound = subject.inbound_token + if inbound is None: + return Error( + CredError.of_unauthorized( + "Token exchange requires a caller token to exchange (OBO).", + www_authenticate='Bearer error="invalid_request"', + ) + ) + match await self._token_exchanger.exchange( + inbound.get_secret_value(), server, config, tenant_id=subject.tenant_id + ): + case Ok(token): + return Ok(StaticHeaderAuth(f"Bearer {token.access_token}", header_name="Authorization")) + case Error(err): + return Error(err) + + async def invalidate_credentials(self, subject: Subject, server: ServerSpec) -> None: + """Drop any cached credential the resolver owns for this `(subject, server)`. + + Used after an upstream rejects the injected credential, so the next resolve re-mints rather + than serving the same rejected token until TTL. Only `token_exchange` holds a re-mintable + cached credential here; other modes are a no-op. + """ + if isinstance(server.config, TokenExchangeConfig) and subject.inbound_token is not None: + await self._token_exchanger.invalidate( + subject.inbound_token.get_secret_value(), server, server.config, tenant_id=subject.tenant_id + ) + async def _authz_token(self, subject: Subject, server: ServerSpec) -> OAuthToken | None: """The user's authorization_code token, or None when absent or the store is unreachable. diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/token_exchange_provider.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/token_exchange_provider.py new file mode 100644 index 00000000000..e49de4559c6 --- /dev/null +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/token_exchange_provider.py @@ -0,0 +1,114 @@ +"""Composition root for the v2-native token_exchange (OBO) exchanger. + +Wires the pure ``OboTokenExchanger`` to its runtime edges: the real httpx POST against the IdP and +the configured cache sizing/TTL constants. ``build_token_exchanger`` is built once at egress +construction and reused, so the in-process exchanged-token cache survives across requests. Unlike the +per-user store, nothing here reads a runtime global at build time (the httpx client is acquired per +call), so it needs no lazy wrapper. +""" + +from __future__ import annotations + +import httpx + +from litellm._logging import verbose_logger +from litellm.constants import ( + MCP_OAUTH2_TOKEN_CACHE_DEFAULT_TTL, + MCP_OAUTH2_TOKEN_CACHE_MIN_TTL, + MCP_OAUTH2_TOKEN_EXPIRY_BUFFER_SECONDS, + MCP_TOKEN_EXCHANGE_CACHE_MAX_SIZE, +) +from litellm.proxy._experimental.mcp_server.outbound_credentials.oauth_token_store import ( + InMemoryTokenCacheBackend, +) +from litellm.proxy._experimental.mcp_server.outbound_credentials.token_exchanger import ( + OboTokenExchanger, + SubjectTokenRejected, + TokenExchangeClientError, +) + +# RFC 6749 5.2 error codes that mean the gateway's own request/credentials are wrong (not the +# caller's subject token), so they surface as a 500 the caller can't fix by re-authenticating. +_GATEWAY_FAULT_OAUTH_ERRORS = frozenset( + {"invalid_client", "unauthorized_client", "unsupported_grant_type", "invalid_target", "invalid_scope"} +) + + +def _oauth_error_fields(response: httpx.Response) -> tuple[str | None, str | None]: + """Read the RFC 6749 5.2 ``error`` code and the IdP's step-up ``claims`` blob from a + token-endpoint error body, as ``(error, claims)`` with None for whatever is absent. + + ``claims`` is the Entra Conditional Access / CAE challenge (a JSON string the client must + replay to the IdP to satisfy the step-up); it is the caller's own requirement, not an IdP + internal, so it may travel to the caller. The ``error_description`` is deliberately not read: + it can carry IdP internals and must never reach the caller. + """ + try: + body: object = response.json() + except Exception: # noqa: BLE001 + return None, None + if not isinstance(body, dict): + return None, None + code = body.get("error") + claims = body.get("claims") + return ( + code if isinstance(code, str) else None, + claims if isinstance(claims, str) and claims else None, + ) + + +async def _post_exchange_endpoint( + url: str, form: dict[str, str], client_auth_headers: dict[str, str] +) -> dict[str, object] | None: + from litellm.llms.custom_httpx.http_handler import ( # noqa: PLC0415 + get_async_httpx_client, # pyright: ignore + ) + from litellm.types.llms.custom_http import httpxSpecialProvider # noqa: PLC0415 + + # litellm's httpx handler and httpx.Response are only partially typed; the IdP returns a JSON + # object and the exchanger validates each field, so the untyped boundary is contained here. + # A 4xx is the IdP rejecting the subject (non-retryable -> 401 via SubjectTokenRejected); any + # other failure is a miss (-> None -> upstream_unavailable -> 503), matching v1's fail-closed. + headers = {"Accept": "application/json", **client_auth_headers} + try: + client = get_async_httpx_client(llm_provider=httpxSpecialProvider.MCP) # pyright: ignore + response = await client.post(url, headers=headers, data=form) # pyright: ignore + response.raise_for_status() # pyright: ignore + parsed: object = response.json() # pyright: ignore + except httpx.HTTPStatusError as status_err: + status_code = status_err.response.status_code + if 400 <= status_code < 500: + oauth_error, claims = _oauth_error_fields(status_err.response) + if oauth_error in _GATEWAY_FAULT_OAUTH_ERRORS: + verbose_logger.warning( + "MCP token exchange rejected as %s (HTTP %d); check the gateway client credentials, " + "audience, and scope for this server", + oauth_error, + status_code, + ) + raise TokenExchangeClientError(oauth_error) from status_err + raise SubjectTokenRejected( + f"IdP rejected the subject token (HTTP {status_code})", + claims=claims, + ) from status_err + verbose_logger.warning("MCP token exchange request failed: %s", status_err) + return None + except Exception as exc: # noqa: BLE001 + verbose_logger.warning("MCP token exchange request failed: %s", exc) + return None + if not isinstance(parsed, dict): + # A valid-but-non-object JSON body (list/string/number) would crash the field parsing; map it + # to a miss so it surfaces as a typed upstream_unavailable, not a 500. + verbose_logger.warning("MCP token exchange returned non-object JSON (%s)", type(parsed).__name__) + return None + return parsed # pyright: ignore + + +def build_token_exchanger() -> OboTokenExchanger: + return OboTokenExchanger( + _post_exchange_endpoint, + cache=InMemoryTokenCacheBackend(max_size=MCP_TOKEN_EXCHANGE_CACHE_MAX_SIZE), + default_ttl_seconds=MCP_OAUTH2_TOKEN_CACHE_DEFAULT_TTL, + min_ttl_seconds=MCP_OAUTH2_TOKEN_CACHE_MIN_TTL, + expiry_buffer_seconds=MCP_OAUTH2_TOKEN_EXPIRY_BUFFER_SECONDS, + ) diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/token_exchanger.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/token_exchanger.py new file mode 100644 index 00000000000..02b6d4eafb1 --- /dev/null +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/token_exchanger.py @@ -0,0 +1,376 @@ +"""v2-native OBO token exchange: swap the caller's token for an upstream-bound one. + +The pure core of the ``token_exchange`` mode. Given the caller's inbound token and the server's +``TokenExchangeConfig``, ``OboTokenExchanger.exchange`` POSTs the grant selected by ``config.profile`` +to the configured endpoint and returns the upstream-bound ``access_token`` as a typed ``OAuthToken``, +or a typed ``CredError`` - never a raise (the HTTP edge is the injected ``ExchangeHttpPost``, whose +adapter contains the I/O). Two profiles share this one engine: ``rfc8693`` (the RFC 8693 token-exchange +grant) and ``entra_obo`` (Microsoft Entra On-Behalf-Of, which is the RFC 7523 ``jwt-bearer`` grant); +only the request form differs, so the cache, single-flight, and TTL machinery are dialect-agnostic. The +exchanged token is cached and single-flighted per ``(subject_token, tenant, config, server)`` so a +repeated caller token skips the IdP round-trip and concurrent calls collapse to one exchange, reusing +the shared in-process cache + coordinator foundation. A rotated caller token hashes to a new key and +re-exchanges. Pure v2 apart from the shared RFC 6749 client-auth helper, which carries no v1 state. + +A missing/expired exchange is an error, never a fall-through to a weaker source (§1.5): the caller +presenting no token is the resolver arm's 401, and an IdP that does not return a usable token is an +``upstream_unavailable`` here. +""" + +from __future__ import annotations + +import hashlib +import time +from collections.abc import Awaitable, Callable +from typing import Literal, Protocol + +from typing_extensions import assert_never + +from litellm._logging import verbose_logger +from litellm.proxy._experimental.mcp_server.outbound_credentials.oauth_token_store import ( + InMemoryTokenCacheBackend, + InProcessRefreshCoordinator, + OAuthToken, + RefreshCoordinator, + TokenCacheBackend, +) +from litellm.proxy._experimental.mcp_server.outbound_credentials.result import ( + Error, + Ok, + Result, +) +from litellm.proxy._experimental.mcp_server.auth.token_endpoint_auth import ( + build_token_endpoint_client_auth, +) +from litellm.proxy._experimental.mcp_server.outbound_credentials.types import ( + CredError, + ServerSpec, + TokenExchangeConfig, +) + +# A token with no declared expiry is cached for this long; one with an expiry is cached until then +# minus the skew buffer, floored at the minimum. Values mirror v1's MCP_OAUTH2_* constants; the +# composition root injects the configured ones. +_DEFAULT_TTL_SECONDS = 3600.0 +_MIN_TTL_SECONDS = 10.0 +_EXPIRY_BUFFER_SECONDS = 60.0 + +_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:token-exchange" +# Microsoft Entra On-Behalf-Of speaks the RFC 7523 jwt-bearer grant, not RFC 8693, and gates delegation +# behind ``requested_token_use=on_behalf_of`` (a Microsoft extension present in neither RFC). +_JWT_BEARER_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer" +_REQUESTED_TOKEN_USE_OBO = "on_behalf_of" + +# RFC 8693 3 token-type URNs that are not usable as an upstream Bearer access token. token_type +# already rejects the common non-access case (N_A); this catches a malformed STS that mints one of +# these but still labels it Bearer. An access_token / jwt / absent / unknown type is accepted (lenient). +_NON_ACCESS_ISSUED_TOKEN_TYPES = frozenset( + { + "urn:ietf:params:oauth:token-type:refresh_token", + "urn:ietf:params:oauth:token-type:id_token", + "urn:ietf:params:oauth:token-type:saml1", + "urn:ietf:params:oauth:token-type:saml2", + } +) + +# The IdP returns an opaque JSON object; the post adapter hands it over untyped and the exchanger +# validates each field, so no Any leaks past this seam (None == any transport/HTTP failure). The +# second dict is the form body; the third is the client-auth headers (HTTP Basic for +# client_secret_basic, empty for client_secret_post). +ExchangeHttpPost = Callable[[str, "dict[str, str]", "dict[str, str]"], Awaitable["dict[str, object] | None"]] + + +class SubjectTokenRejected(Exception): + """The IdP refused to exchange the subject token (an RFC 8693 4xx, e.g. ``invalid_grant``). + + Distinct from a transport / IdP-availability failure, which the post adapter maps to ``None`` -> + ``upstream_unavailable`` -> 503 (retryable). A rejected subject is the caller's problem, not the + gateway's, so the arm surfaces it as a non-retryable 401 (the OBO challenge) instead. + ``claims`` is the IdP's step-up challenge blob (Entra Conditional Access / CAE) from the + rejection body; it threads into the 401 challenge so the client can satisfy the step-up and + retry. The ``error_description`` is never carried (it can leak IdP internals). + """ + + def __init__(self, detail: str, *, claims: str | None = None) -> None: + super().__init__(detail) + self.claims = claims + + +class TokenExchangeClientError(Exception): + """The IdP rejected the exchange for a reason that is the gateway's fault, not the caller's. + + RFC 6749 5.2 codes such as ``invalid_client`` (the gateway's own STS credentials are wrong), + ``unauthorized_client`` / ``unsupported_grant_type`` (the gateway is not permitted to exchange), + ``invalid_target`` / ``invalid_scope`` (the gateway's audience/scope config for this server is + wrong). The caller cannot fix these by re-authenticating, so the arm surfaces them as a 500 + (``misconfigured``), not the 401 OBO challenge. The IdP ``error_description`` is never carried. + """ + + +class TokenExchanger(Protocol): + """Exchanges a caller token for an upstream-bound one, per the server's token_exchange config.""" + + async def exchange( + self, subject_token: str, server: ServerSpec, config: TokenExchangeConfig, *, tenant_id: str = "" + ) -> Result[OAuthToken, CredError]: ... + + async def invalidate( + self, subject_token: str, server: ServerSpec, config: TokenExchangeConfig, *, tenant_id: str = "" + ) -> None: ... + + +def _cache_key(subject_token: str, tenant_id: str, config: TokenExchangeConfig) -> str: + """Bind the cache entry to the caller token, the tenant, AND the exchange config that minted it. + + A rotated caller token, a different tenant, profile, endpoint, audience, scope, client_id, secret, + auth method, or subject_token_type all change the key, so two tenants behind the same opaque token + never share an entry and a config change (including a profile flip that alters the wire form) + forces a fresh exchange instead of serving a token minted for the old config until TTL. Everything + is hashed, so no secret is held in the key. + """ + secret = config.client_secret.get_secret_value() if config.client_secret else "" + material = "\x00".join( + ( + subject_token, + tenant_id, + config.profile, + config.token_exchange_endpoint or "", + config.audience or "", + config.subject_token_type, + config.client_id or "", + secret, + config.token_endpoint_auth_method or "", + " ".join(config.scopes), + ) + ) + return hashlib.sha256(material.encode()).hexdigest() + + +def _parse_expires_in(raw: object) -> int | None: + if isinstance(raw, bool): + return None + if isinstance(raw, (int, float)): + return int(raw) + if isinstance(raw, str): + try: + return int(float(raw)) + except ValueError: + return None + return None + + +def _rfc8693_form( + *, + subject_token: str, + subject_token_type: str, + audience: str | None, + scopes: tuple[str, ...], +) -> dict[str, str]: + return { + "grant_type": _GRANT_TYPE, + "subject_token": subject_token, + "subject_token_type": subject_token_type, + **({"audience": audience} if audience else {}), + **({"scope": " ".join(scopes)} if scopes else {}), + } + + +def _entra_obo_form( + *, + subject_token: str, + scopes: tuple[str, ...], +) -> dict[str, str]: + # Microsoft Entra On-Behalf-Of (RFC 7523 jwt-bearer, not RFC 8693): the caller's inbound access + # token rides as ``assertion`` (its ``aud`` must be this gateway's ``client_id``); the target + # resource is carried in ``scope`` (e.g. api:///.default), since Entra has no audience + # parameter and ignores subject_token_type; ``requested_token_use=on_behalf_of`` is the Microsoft + # extension that turns the jwt-bearer grant into a delegation. ``scope`` is required, and the + # exchange precondition rejects an empty one, so it is always present here. Client authentication + # (client_id/client_secret via post, or Basic) is layered on by the caller through + # build_token_endpoint_client_auth, so it is not built into the form here. + return { + "grant_type": _JWT_BEARER_GRANT_TYPE, + "assertion": subject_token, + "scope": " ".join(scopes), + "requested_token_use": _REQUESTED_TOKEN_USE_OBO, + } + + +def _build_exchange_form( + *, + profile: Literal["rfc8693", "entra_obo"], + subject_token: str, + subject_token_type: str, + audience: str | None, + scopes: tuple[str, ...], +) -> dict[str, str]: + match profile: + case "rfc8693": + return _rfc8693_form( + subject_token=subject_token, + subject_token_type=subject_token_type, + audience=audience, + scopes=scopes, + ) + case "entra_obo": + return _entra_obo_form( + subject_token=subject_token, + scopes=scopes, + ) + assert_never(profile) + + +class OboTokenExchanger: + """``TokenExchanger`` that runs the profile's OBO grant once per caller token, then caches the result. + + The HTTP post is injected (``None`` on any IdP failure, mirroring v1: a failed exchange is a miss, + not a 500). The cache and single-flight coordinator default to the in-process foundation; a + deployment with no shared state needs nothing more (v1's exchanged-token cache is per-process too). + The clock is injected so TTL/expiry is deterministic in tests. + """ + + def __init__( + self, + http_post: ExchangeHttpPost, + *, + cache: TokenCacheBackend | None = None, + coordinator: RefreshCoordinator | None = None, + clock: Callable[[], float] = time.time, + default_ttl_seconds: float = _DEFAULT_TTL_SECONDS, + min_ttl_seconds: float = _MIN_TTL_SECONDS, + expiry_buffer_seconds: float = _EXPIRY_BUFFER_SECONDS, + ) -> None: + self._http_post = http_post + self._cache: TokenCacheBackend = cache or InMemoryTokenCacheBackend(clock=clock) + self._coordinator: RefreshCoordinator = coordinator or InProcessRefreshCoordinator() + self._clock = clock + self._default_ttl_seconds = default_ttl_seconds + self._min_ttl_seconds = min_ttl_seconds + self._expiry_buffer_seconds = expiry_buffer_seconds + + async def exchange( + self, subject_token: str, server: ServerSpec, config: TokenExchangeConfig, *, tenant_id: str = "" + ) -> Result[OAuthToken, CredError]: + endpoint = config.token_exchange_endpoint + client_id = config.client_id + client_secret = config.client_secret + if not endpoint: + # No endpoint configured and none discoverable: fail closed (412) rather than guess an IdP + # or fall back to a weaker source. The caller's token is never sent anywhere. + return Error( + CredError.of_precondition_required("token exchange endpoint is not configured for this server") + ) + if not client_id or client_secret is None: + return Error(CredError.of_misconfigured("token_exchange requires client_id and client_secret")) + if config.profile == "entra_obo" and not config.scopes: + # Entra carries the target resource in ``scope`` (api:///.default); with no scope the + # IdP cannot resolve an audience, so fail closed as misconfigured rather than POST a form the + # IdP will reject. + return Error( + CredError.of_misconfigured("entra_obo token exchange requires a scope (e.g. api:///.default)") + ) + + cache_key = _cache_key(subject_token, tenant_id, config) + server_id = server.server_id + cached = await self._cache.get(cache_key, server_id) + if cached is not None: + verbose_logger.debug("MCP token exchange cache hit for server %s", server_id) + return Ok(cached) + + client_auth = build_token_endpoint_client_auth( + auth_method=config.token_endpoint_auth_method, + client_id=client_id, + client_secret=client_secret.get_secret_value(), + ) + form = { + **_build_exchange_form( + profile=config.profile, + subject_token=subject_token, + subject_token_type=config.subject_token_type, + audience=config.audience, + scopes=config.scopes, + ), + **client_auth.body, + } + + async def run_exchange() -> OAuthToken | None: + fresh = await self._cache.get(cache_key, server_id) + if fresh is not None: + return fresh + verbose_logger.debug( + "Exchanging token for MCP server %s at %s (audience=%s)", server_id, endpoint, config.audience + ) + body = await self._http_post(endpoint, form, client_auth.headers) + if body is None: + return None + token = self._token_from_body(body) + if token is None: + return None + await self._cache.set(cache_key, server_id, token, self._ttl_seconds(token)) + verbose_logger.info("Token exchange succeeded for MCP server %s", server_id) + return token + + async def reread() -> OAuthToken | None: + return await self._cache.get(cache_key, server_id) + + try: + token = await self._coordinator.run(cache_key, server_id, refresh=run_exchange, reread=reread) + except SubjectTokenRejected as rejected: + # The IdP rejected the subject token (4xx). This is non-retryable: the caller must + # re-authenticate with the IdP, so it surfaces as a 401 (the OBO challenge), not a 503. + # A step-up rejection (Entra Conditional Access) carries the claims blob through so the + # edge's challenge tells the client how to satisfy it. + return Error( + CredError.of_unauthorized( + str(rejected) or "subject token rejected by the IdP", + claims=rejected.claims, + ) + ) + except TokenExchangeClientError: + # RFC 6749 5.2 gateway-fault code (invalid_client / invalid_target / ...): the caller can't + # fix it by re-authenticating, so surface a 500 rather than the OBO 401 challenge. The + # specific code is logged at the edge; the user-facing summary stays generic. + return Error( + CredError.of_misconfigured( + "token exchange configuration error: the gateway's credentials, audience, or scope " + "for this server were not accepted by the IdP" + ) + ) + if token is None: + return Error(CredError.of_upstream_unavailable("token exchange did not return a usable access token")) + return Ok(token) + + async def invalidate( + self, subject_token: str, server: ServerSpec, config: TokenExchangeConfig, *, tenant_id: str = "" + ) -> None: + """Drop the cached exchanged token so the next call re-exchanges (e.g. after an upstream 401).""" + await self._cache.delete(_cache_key(subject_token, tenant_id, config), server.server_id) + + def _token_from_body(self, body: dict[str, object]) -> OAuthToken | None: + access_token = body.get("access_token") + if not isinstance(access_token, str) or not access_token: + return None + # token_type is forwarded downstream as Bearer, so a present-but-non-Bearer type (e.g. N_A) + # must fail closed rather than be minted as a bogus Bearer; an absent type defaults to Bearer. + token_type = body.get("token_type") + if isinstance(token_type, str) and token_type.strip().lower() != "bearer": + verbose_logger.warning( + "MCP token exchange returned unusable token_type %r; refusing to forward it as Bearer", token_type + ) + return None + # issued_token_type says what representation was minted; reject a clearly-non-access type + # (refresh/id/saml) even if token_type claimed Bearer. access_token / jwt / absent / unknown pass. + issued_token_type = body.get("issued_token_type") + if isinstance(issued_token_type, str) and issued_token_type in _NON_ACCESS_ISSUED_TOKEN_TYPES: + return None + expires_in = _parse_expires_in(body.get("expires_in")) + expires_at = self._clock() + expires_in if expires_in is not None else None + return OAuthToken(access_token=access_token, expires_at=expires_at) + + def _ttl_seconds(self, token: OAuthToken) -> float: + if token.expires_at is None: + return self._default_ttl_seconds + lifetime = max(0.0, token.expires_at - self._clock()) + # Floor at min_ttl, but never cache past the token's own expiry: a token whose remaining + # lifetime is below the buffer (or even below min_ttl) must not be served stale upstream. + return min(max(lifetime - self._expiry_buffer_seconds, self._min_ttl_seconds), lifetime) diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/types.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/types.py index 671de63eabe..7e04be4f045 100644 --- a/litellm/proxy/_experimental/mcp_server/outbound_credentials/types.py +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/types.py @@ -39,6 +39,7 @@ from litellm.proxy._experimental.mcp_server.outbound_credentials.result import ( Ok, Result, ) +from litellm.types.mcp import DEFAULT_SUBJECT_TOKEN_TYPE class AuthSpecKind(str, Enum): @@ -67,11 +68,15 @@ class Unauthorized: ``detail`` is the human message; ``www_authenticate`` and ``body`` carry a scheme-specific challenge (e.g. BYOK's provisioning prompt) so the edge can reproduce it verbatim. + ``claims`` carries an IdP step-up challenge (e.g. Entra Conditional Access) so the edge can + fold it into the ``WWW-Authenticate`` it builds; the client replays the claims to the IdP to + satisfy the step-up, then retries with the fresh token. """ detail: str www_authenticate: str | None = None body: Mapping[str, str] | None = None + claims: str | None = None @tagged_union(frozen=True) @@ -104,8 +109,16 @@ class CredError: *, www_authenticate: str | None = None, body: Mapping[str, str] | None = None, + claims: str | None = None, ) -> CredError: - return CredError(unauthorized=Unauthorized(detail=detail, www_authenticate=www_authenticate, body=body)) + return CredError( + unauthorized=Unauthorized( + detail=detail, + www_authenticate=www_authenticate, + body=body, + claims=claims, + ) + ) @staticmethod def of_misconfigured(detail: str) -> CredError: @@ -182,18 +195,33 @@ class ClientCredentialsConfig(BaseModel): class TokenExchangeConfig(BaseModel): - """RFC 8693 OBO; swap the caller's live subject_token for a token bound to the upstream's - audience (`server.resource`, RFC 8707). The gateway authenticates to the exchange endpoint - as an OAuth client (`client_id`/`client_secret`); the inbound token is sent only to that - endpoint, never to the upstream. + """OBO: swap the caller's live inbound token for a token bound to the upstream's audience. The + gateway authenticates to the exchange endpoint as an OAuth client (`client_id`/`client_secret`); + the inbound token is sent only to that endpoint, never to the upstream. + + `profile` selects the wire dialect, since not every IdP speaks RFC 8693: + - `rfc8693` (default) is the standard token-exchange grant: the inbound token is the + `subject_token` (typed by `subject_token_type`), the target is the optional `audience`. + - `entra_obo` is Microsoft Entra On-Behalf-Of, which is the RFC 7523 `jwt-bearer` grant rather + than 8693: the inbound token rides as `assertion`, the target resource is carried in `scopes` + (`api:///.default`, since Entra has no audience parameter), and the Microsoft-only + `requested_token_use=on_behalf_of` extension makes the jwt-bearer grant a delegation. + `subject_token_type` and `audience` are unused in this profile. + + `audience` (rfc8693 only) is optional and sent only when the operator configured one, since both + `audience` and `resource` are optional in RFC 8693 and the authorization server applies its own + default when neither is sent (fabricating one risks `invalid_target`). """ model_config = ConfigDict(frozen=True) kind: Literal[AuthSpecKind.token_exchange] = AuthSpecKind.token_exchange - subject_token_type: str = "urn:ietf:params:oauth:token-type:access_token" + profile: Literal["rfc8693", "entra_obo"] = "rfc8693" + subject_token_type: str = DEFAULT_SUBJECT_TOKEN_TYPE token_exchange_endpoint: str | None = None + audience: str | None = None client_id: str | None = None client_secret: SecretStr | None = None + token_endpoint_auth_method: Literal["client_secret_basic", "client_secret_post"] | None = None scopes: tuple[str, ...] = () diff --git a/litellm/proxy/_experimental/mcp_server/rest_endpoints.py b/litellm/proxy/_experimental/mcp_server/rest_endpoints.py index d30d8af2af2..111fde86ea0 100644 --- a/litellm/proxy/_experimental/mcp_server/rest_endpoints.py +++ b/litellm/proxy/_experimental/mcp_server/rest_endpoints.py @@ -8,6 +8,7 @@ from typing import ( Dict, List, Literal, + Mapping, Optional, Set, Tuple, @@ -68,6 +69,7 @@ if MCP_AVAILABLE: from mcp.types import Tool as MCPTool from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( + _UPSTREAM_OAUTH_DISCOVERY_AUTH_TYPES, global_mcp_server_manager, ) from litellm.proxy._experimental.mcp_server.oauth_utils import ( @@ -77,6 +79,8 @@ if MCP_AVAILABLE: ListMCPToolsRestAPIResponseObject, MCPInfo, MCPServer, + _apply_toolset_scope, + _fire_mcp_tool_call_logging, _tool_name_matches, execute_mcp_tool, filter_tools_by_allowed_tools, @@ -84,6 +88,120 @@ if MCP_AVAILABLE: ######################################################## ############ MCP Server REST API Routes ################# + async def _safe_fire_mcp_tool_call_logging( + logging_obj: Optional[Any], + result: Any, + start_time: datetime, + end_time: datetime, + user_api_key_auth: Optional[UserAPIKeyAuth] = None, + request_data: Optional[Mapping[str, object]] = None, + ) -> None: + if logging_obj is None: + return + logging_results = await asyncio.gather( + _fire_mcp_tool_call_logging( + logging_obj, + result, + start_time, + end_time, + user_api_key_auth=user_api_key_auth, + request_data=request_data, + ), + return_exceptions=True, + ) + logging_error = logging_results[0] + if isinstance(logging_error, asyncio.CancelledError): + raise logging_error + if isinstance(logging_error, BaseException): + verbose_logger.warning("MCP tool call logging failed (continuing): %s", logging_error) + + def _relay_upstream_auth_http_exception(e: MCPUpstreamAuthError, request: Request) -> HTTPException: + """Convert a client-forwarded pass-through upstream 401 into an HTTPException that preserves the + upstream WWW-Authenticate, so a standards-compliant MCP client can run the upstream OAuth flow + instead of the generic 500 the endpoint catch-all would return.""" + return e.to_http_exception( + base_url=get_request_base_url(request), + request_path=request.scope.get("_original_path") or request.url.path, + ) + + async def _handle_virtual_mcp_tool( + request: Request, + data: Dict[str, Any], + tool_name: str, + user_api_key_dict: UserAPIKeyAuth, + ) -> Any: + """Handle the virtual ``mcp_tool_search`` / ``mcp_tool_call`` REST tools (gated on + ``mcp_tool_search_enabled``). Kept out of ``call_tool_rest_api`` so that endpoint stays a single + dispatch. An upstream 401 raised by the virtual ``mcp_tool_call`` propagates unhandled to the + caller's ``except MCPUpstreamAuthError`` relay, the same as the direct call path.""" + from litellm.proxy._experimental.mcp_server.auth.user_api_key_auth_mcp import ( + MCPRequestHandler, + ) + from litellm.proxy._experimental.mcp_server.tool_search import ( + MCP_TOOL_SEARCH_TOOL_NAME, + coerce_top_k, + handle_mcp_tool_call, + handle_mcp_tool_search, + ) + from litellm.proxy.common_request_processing import ProxyBaseLLMRequestProcessing + from litellm.proxy.proxy_server import general_settings, proxy_config, proxy_logging_obj + + if not getattr(getattr(user_api_key_dict, "object_permission", None), "mcp_tool_search_enabled", False): + raise HTTPException( + status_code=403, + detail={"error": "forbidden", "message": f"{tool_name} requires mcp_tool_search_enabled on the key"}, + ) + tool_arguments = data.get("arguments") or {} + rest_client_ip = IPAddressUtils.get_mcp_client_ip(request) + ( + virtual_mcp_auth_header, + virtual_mcp_server_auth_headers, + virtual_raw_headers, + ) = _extract_mcp_headers_from_request(request, MCPRequestHandler) + virtual_oauth2_headers = MCPRequestHandler._get_oauth2_headers_from_headers(request.headers) + if tool_name == MCP_TOOL_SEARCH_TOOL_NAME: + return await handle_mcp_tool_search( + query=tool_arguments.get("query", ""), + top_k=coerce_top_k(tool_arguments.get("top_k", 5)), + user_api_key_dict=user_api_key_dict, + client_ip=rest_client_ip, + mcp_auth_header=virtual_mcp_auth_header, + mcp_server_auth_headers=virtual_mcp_server_auth_headers, + oauth2_headers=virtual_oauth2_headers, + raw_headers=virtual_raw_headers, + ) + # MCP_TOOL_CALL_TOOL_NAME: run the same pre-call pipeline as the normal path so the tool + # execution is spend-logged and guardrail-checked. + (_, virtual_logging_obj) = await ProxyBaseLLMRequestProcessing(data=data).common_processing_pre_call_logic( + request=request, + user_api_key_dict=user_api_key_dict, + proxy_config=proxy_config, + route_type=CallTypes.call_mcp_tool.value, + proxy_logging_obj=proxy_logging_obj, + general_settings=general_settings, + ) + _tool_start_time = datetime.now() + result = await handle_mcp_tool_call( + tool_name=tool_arguments.get("tool_name", ""), + arguments=tool_arguments.get("arguments") or {}, + user_api_key_dict=user_api_key_dict, + client_ip=rest_client_ip, + mcp_auth_header=virtual_mcp_auth_header, + mcp_server_auth_headers=virtual_mcp_server_auth_headers, + oauth2_headers=virtual_oauth2_headers, + raw_headers=virtual_raw_headers, + litellm_logging_obj=virtual_logging_obj, + ) + await _safe_fire_mcp_tool_call_logging( + virtual_logging_obj, + result, + _tool_start_time, + datetime.now(), + user_api_key_auth=user_api_key_dict, + request_data=data, + ) + return result + def _get_server_auth_header( server, mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]], @@ -522,10 +640,37 @@ if MCP_AVAILABLE: "message": "Successfully retrieved tools", } + def _as_query_str(value: Any) -> Optional[str]: + """Coerce an Optional[str] Query param to str|None, dropping unresolved FastAPI defaults.""" + return value if isinstance(value, str) else None + + async def _resolve_toolset_scope( + toolset_name: Optional[str], + user_api_key_dict: UserAPIKeyAuth, + ) -> UserAPIKeyAuth: + """Resolve ``toolset_name`` to its scoped ``UserAPIKeyAuth``, or return unchanged.""" + if not toolset_name: + return user_api_key_dict + + from litellm.proxy.utils import get_prisma_client_or_throw + + prisma_client = get_prisma_client_or_throw("Database not available. Connect a database to your proxy") + toolset = await global_mcp_server_manager.get_toolset_by_name_cached(prisma_client, toolset_name) + if toolset is None: + raise HTTPException( + status_code=404, + detail=f"Toolset '{toolset_name}' not found", + ) + return await _apply_toolset_scope(user_api_key_dict, toolset.toolset_id) + @router.get("/tools/list", dependencies=[Depends(user_api_key_auth)]) async def list_tool_rest_api( request: Request, server_id: Optional[str] = Query(None, description="The server id to list tools for"), + mcp_server_name: Optional[str] = Query( + None, description="Filter tools to a single MCP server by name or alias" + ), + toolset_name: Optional[str] = Query(None, description="Filter tools to a single toolset by name"), include_disabled_tools: bool = Query( False, description=( @@ -563,12 +708,40 @@ if MCP_AVAILABLE: ) try: + mcp_server_name = _as_query_str(mcp_server_name) + toolset_name = _as_query_str(toolset_name) + # The full catalog (allowlist filter skipped) is admin-only so the # REST endpoint can't be used to enumerate deliberately-disabled tools. apply_tool_filters = not ( include_disabled_tools and user_api_key_dict.user_role == LitellmUserRoles.PROXY_ADMIN ) + user_api_key_dict = await _resolve_toolset_scope(toolset_name, user_api_key_dict) + + if server_id is None: + server_id = mcp_server_name + + if ( + apply_tool_filters + and server_id is None + and toolset_name is None + and getattr( + getattr(user_api_key_dict, "object_permission", None), + "mcp_tool_search_enabled", + False, + ) + ): + from litellm.proxy._experimental.mcp_server.tool_search import ( + get_virtual_tool_definitions, + ) + + return { + "tools": get_virtual_tool_definitions(), + "error": None, + "message": "Successfully retrieved tools", + } + # Extract auth headers from request headers = request.headers raw_headers_from_request = dict(headers) @@ -685,6 +858,8 @@ if MCP_AVAILABLE: request_path=request.scope.get("_original_path") or request.url.path, ) except HTTPException as http_exc: + if http_exc.status_code == status.HTTP_404_NOT_FOUND: + raise # Internal access/IP 403s keep the legacy error-dict response shape # so the existing contract stays intact. verbose_logger.exception("HTTPException in list_tool_rest_api: %s", str(http_exc)) @@ -727,6 +902,17 @@ if MCP_AVAILABLE: try: data = await request.json() + tool_name = data.get("name") + tool_arguments = data.get("arguments") or {} + + from litellm.proxy._experimental.mcp_server.tool_search import ( + MCP_TOOL_CALL_TOOL_NAME, + MCP_TOOL_SEARCH_TOOL_NAME, + ) + + if tool_name in (MCP_TOOL_SEARCH_TOOL_NAME, MCP_TOOL_CALL_TOOL_NAME): + return await _handle_virtual_mcp_tool(request, data, tool_name, user_api_key_dict) + # Validate required parameters early server_id = data.get("server_id") if not server_id: @@ -738,7 +924,6 @@ if MCP_AVAILABLE: }, ) - tool_name = data.get("name") if not tool_name: raise HTTPException( status_code=400, @@ -748,8 +933,6 @@ if MCP_AVAILABLE: }, ) - tool_arguments = data.get("arguments") or {} - proxy_base_llm_response_processor = ProxyBaseLLMRequestProcessing(data=data) ( data, @@ -796,11 +979,12 @@ if MCP_AVAILABLE: user_oauth_extra_headers = await _get_user_oauth_extra_headers(target_server, user_api_key_dict) # Call execute_mcp_tool directly (permission checks already done) + _tool_start_time = datetime.now() result = await execute_mcp_tool( name=tool_name, arguments=tool_arguments, allowed_mcp_servers=allowed_mcp_servers, - start_time=datetime.now(), + start_time=_tool_start_time, user_api_key_auth=data.get("user_api_key_auth"), mcp_auth_header=data.get("mcp_auth_header"), mcp_server_auth_headers=data.get("mcp_server_auth_headers"), @@ -809,6 +993,14 @@ if MCP_AVAILABLE: litellm_logging_obj=data.get("litellm_logging_obj"), requested_server_id=canonical_server_id, ) + await _safe_fire_mcp_tool_call_logging( + logging_obj, + result, + _tool_start_time, + datetime.now(), + user_api_key_auth=user_api_key_dict, + request_data=data, + ) return result except MCPMissingUserEnvVarsError as e: verbose_logger.info( @@ -848,8 +1040,16 @@ if MCP_AVAILABLE: "guardrail_name": getattr(e, "guardrail_name", None), }, ) + except MCPUpstreamAuthError as e: + # A client-forwarded pass-through upstream 401 from either the direct or the virtual call + # branch. Relay it as a 401 + WWW-Authenticate so the MCP client can re-run upstream OAuth, + # and log at info: an expected caller-must-reauth signal, not an operator-actionable error. + verbose_logger.info(f"MCP tool call relaying upstream HTTP {e.status_code}") + raise _relay_upstream_auth_http_exception(e, request) except HTTPException as e: - # Re-raise HTTPException as-is to preserve status code and detail + # Locally generated denials (tool/server permission, IP filtering, BYOK) stay at error level + # so restriction probing keeps full monitoring visibility; the relayed upstream 401 above is + # the only status demoted to info. verbose_logger.error(f"HTTPException in MCP tool call: {str(e)}") raise e except Exception as e: @@ -975,11 +1175,6 @@ if MCP_AVAILABLE: forwarded_authorization = ( effective_oauth2_headers.get("Authorization") if effective_oauth2_headers else None ) - is_interactive_authz_code = ( - server_model.auth_type == MCPAuth.oauth2 - and forwarded_authorization is not None - and to_server_spec(server_model) is not None - ) preview_cred_provider = ( UpstreamCredentialProvider( oauth_token_store=PresentedOAuthTokenStore( @@ -990,7 +1185,11 @@ if MCP_AVAILABLE: ) ) ) - if is_interactive_authz_code + if ( + server_model.auth_type == MCPAuth.oauth2 + and forwarded_authorization is not None + and to_server_spec(server_model) is not None + ) else None ) @@ -1151,8 +1350,13 @@ if MCP_AVAILABLE: if isinstance(credentials, dict): mcp_auth_header = credentials.get("auth_value") + # Authorization doubles as the admission fallback (LITELLM_API_KEY_HEADER_NAME_SECONDARY): + # when the primary x-litellm-api-key header is absent, the Authorization value is the + # caller's LiteLLM key, not an upstream token, and must never be forwarded upstream. oauth2_headers: Optional[Dict[str, str]] = None - if new_mcp_server_request.auth_type == MCPAuth.oauth2: + if new_mcp_server_request.auth_type in _UPSTREAM_OAUTH_DISCOVERY_AUTH_TYPES and headers.get( + MCPRequestHandler.LITELLM_API_KEY_HEADER_NAME_PRIMARY + ): oauth2_headers = MCPRequestHandler._get_oauth2_headers_from_headers(headers) async def _list_tools_operation(client): diff --git a/litellm/proxy/_experimental/mcp_server/semantic_tool_filter.py b/litellm/proxy/_experimental/mcp_server/semantic_tool_filter.py index f24d5715e83..e12c6cdbd56 100644 --- a/litellm/proxy/_experimental/mcp_server/semantic_tool_filter.py +++ b/litellm/proxy/_experimental/mcp_server/semantic_tool_filter.py @@ -7,6 +7,8 @@ Filters MCP tools semantically for /chat/completions and /responses endpoints. from typing import TYPE_CHECKING, Any, Dict, List, Optional from litellm._logging import verbose_logger +from litellm.exceptions import ContextWindowExceededError +from litellm.litellm_core_utils.exception_mapping_utils import ExceptionCheckers from litellm.proxy._experimental.mcp_server.utils import MCP_TOOL_PREFIX_SEPARATOR if TYPE_CHECKING: @@ -15,6 +17,36 @@ if TYPE_CHECKING: from litellm.router import Router +class SemanticToolFilterContextWindowError(Exception): + """Raised when the embedding model exceeds its context window, so semantic filtering cannot run.""" + + def __init__(self, embedding_model: str, stage: str, original_error: str): + self.embedding_model = embedding_model + self.stage = stage + self.original_error = original_error + super().__init__( + f"MCP semantic tool filtering could not run: embedding model '{embedding_model}' " + f"exceeded its context window while embedding {stage}. " + f"The request was blocked instead of silently passing all tools through. " + f"Switch to an embedding model with a larger context window, or disable " + f"semantic tool filtering." + ) + + +def _is_context_window_error(error: Optional[BaseException], max_depth: int = 5) -> bool: + """Detect a context-window overflow anywhere in an exception's cause chain.""" + current = error + for _ in range(max_depth): + if current is None: + return False + if isinstance(current, ContextWindowExceededError): + return True + if ExceptionCheckers.is_error_str_context_window_exceeded(str(current)): + return True + current = current.__cause__ or current.__context__ + return False + + class SemanticMCPToolFilter: """Filters MCP tools using semantic similarity to reduce context window size.""" @@ -42,6 +74,7 @@ class SemanticMCPToolFilter: self.embedding_model = embedding_model self.router_instance = litellm_router_instance self.tool_router: Optional["SemanticRouter"] = None + self.context_window_error: Optional[str] = None self._tool_map: Dict[str, Any] = {} # MCPTool objects or OpenAI function dicts async def build_router_from_mcp_registry(self) -> None: @@ -111,6 +144,7 @@ class SemanticMCPToolFilter: return try: + self.context_window_error = None # Convert tools to routes routes = [] self._tool_map = {} @@ -143,6 +177,9 @@ class SemanticMCPToolFilter: except Exception as e: verbose_logger.error(f"Failed to build semantic router: {e}") self.tool_router = None + if _is_context_window_error(e): + self.context_window_error = str(e) + return raise async def filter_tools( @@ -169,6 +206,13 @@ class SemanticMCPToolFilter: if not available_tools: return available_tools + if self.context_window_error is not None: + raise SemanticToolFilterContextWindowError( + embedding_model=self.embedding_model, + stage="the MCP tool descriptions during semantic router build", + original_error=self.context_window_error, + ) + if not query or not query.strip(): return available_tools @@ -189,6 +233,16 @@ class SemanticMCPToolFilter: return self._get_tools_by_names(matched_tool_names, available_tools) except Exception as e: + if _is_context_window_error(e): + verbose_logger.error( + f"Semantic tool filter embedding exceeded its context window: {e}", + exc_info=True, + ) + raise SemanticToolFilterContextWindowError( + embedding_model=self.embedding_model, + stage="the user query", + original_error=str(e), + ) from e verbose_logger.error(f"Semantic tool filter failed: {e}", exc_info=True) return available_tools diff --git a/litellm/proxy/_experimental/mcp_server/server.py b/litellm/proxy/_experimental/mcp_server/server.py index 4b55510a629..5090aa7d7d5 100644 --- a/litellm/proxy/_experimental/mcp_server/server.py +++ b/litellm/proxy/_experimental/mcp_server/server.py @@ -10,8 +10,8 @@ import contextvars import hashlib import json import time -import types import traceback +import types import uuid from datetime import datetime from typing import ( @@ -20,12 +20,14 @@ from typing import ( Callable, Dict, List, + Mapping, Optional, Set, Tuple, Union, cast, ) +from urllib.parse import urlsplit, urlunsplit import httpx from fastapi import FastAPI, HTTPException @@ -37,13 +39,20 @@ from starlette.types import Message, Receive, Scope, Send from litellm._logging import verbose_logger from litellm.constants import MAXIMUM_TRACEBACK_LINES_TO_LOG from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj +from litellm.llms.custom_httpx.http_handler import ( + get_async_httpx_client, + httpxSpecialProvider, +) from litellm.proxy._experimental.mcp_server.auth.user_api_key_auth_mcp import ( MCPRequestHandler, ) -from litellm.proxy._experimental.mcp_server.exceptions import MCPUpstreamAuthError from litellm.proxy._experimental.mcp_server.discoverable_endpoints import ( get_request_base_url, ) +from litellm.proxy._experimental.mcp_server.exceptions import ( + MCPToolResultError, + MCPUpstreamAuthError, +) from litellm.proxy._experimental.mcp_server.mcp_context import ( _mcp_active_toolset_id, _mcp_gateway_initialize_instructions, @@ -56,13 +65,10 @@ from litellm.proxy._experimental.mcp_server.utils import ( LITELLM_MCP_SERVER_VERSION, MCPMissingUserEnvVarsError, add_server_prefix_to_name, + extract_mcp_tool_result_error_message, get_server_prefix, iter_known_server_prefixes, ) -from litellm.llms.custom_httpx.http_handler import ( - get_async_httpx_client, - httpxSpecialProvider, -) from litellm.proxy._types import ( ProxyException, SpecialMCPServerNames, @@ -100,6 +106,27 @@ _MAX_STATEFUL_SESSIONS_PER_OWNER = 100 _MCP_ROUTING_PEEK_MAX_BYTES = 4096 +def _redact_mcp_resource_url(url: Optional[str]) -> Optional[str]: + """Reduce an MCP server URL to its origin (scheme + host + port) for logging. + + Everything else is dropped: userinfo (``user:pass@``), the query string, the + fragment, and the path, because hosted MCP servers routinely embed the + credential in the path (e.g. ``/mcp/s/``) and this value is persisted + in spend-log metadata that a caller who can invoke the tool can read back. + Returns None when the URL has no host to identify (nothing safe to log). + """ + if not isinstance(url, str) or not url: + return None + try: + parts = urlsplit(url) + except ValueError: + return None + if not parts.hostname: + return None + netloc = f"{parts.hostname}:{parts.port}" if parts.port else parts.hostname + return urlunsplit((parts.scheme, netloc, "", "", "")) or None + + def _invalidate_byok_cred_cache(user_id: str, server_id: str) -> None: """Remove a (user_id, server_id) entry from the BYOK credential cache. @@ -122,9 +149,12 @@ def _write_byok_cred_cache(user_id: str, server_id: str, credential: Optional[st # TODO: Make this a util function for litellm client usage MCP_AVAILABLE: bool = True try: + import weakref + from mcp import ReadResourceResult, Resource from mcp.server import Server from mcp.server.lowlevel.helper_types import ReadResourceContents + from mcp.server.session import ServerSession as _McpServerSession from mcp.types import ( BlobResourceContents, GetPromptResult, @@ -132,8 +162,6 @@ try: TextResourceContents, Tool, ) - from mcp.server.session import ServerSession as _McpServerSession - import weakref # Robust auth lookup keyed by session_object. _session_obj_auth_storage: "weakref.WeakKeyDictionary[Any, MCPAuthenticatedUser]" = weakref.WeakKeyDictionary() @@ -229,6 +257,56 @@ def _jsonrpc_text_has_top_level_method(text: str) -> bool: return False +def _mcp_meta_trace_carrier(req_ctx: object) -> Optional[dict[str, str]]: + """The W3C trace context (``traceparent``/``tracestate``) the MCP client + propagated in the request's ``params._meta`` (SEP-414), or ``None``. + + Per the OTel MCP semconv the MCP span parents to this propagated context rather + than to the HTTP/session transport (which is recorded as a link instead), so a + streamable-HTTP session that multiplexes many messages does not glue every + message under the session's first request. The client's W3C Baggage is + deliberately excluded: it is caller-controlled, and the otel baggage processor + stamps allowlisted baggage keys (``litellm.team.id``, ``litellm.metadata.*``, + ...) onto the span, so honoring remote baggage would let a client spoof a + span's identity attribution. + """ + meta = getattr(req_ctx, "meta", None) + extra = getattr(meta, "model_extra", None) + if not isinstance(extra, dict): + return None + carrier = {key: extra[key] for key in ("traceparent", "tracestate") if isinstance(extra.get(key), str)} + return carrier or None + + +def _otel_set_mcp_trace_carrier(carrier: Optional[dict[str, str]]) -> object: + """Stash ``carrier`` for the otel_v2 MCP span and return a reset token, or + ``None`` when otel_v2 is unavailable. Lazily imported so opentelemetry stays an + optional dependency.""" + try: + from litellm.integrations.otel.plumbing.context import ( + set_mcp_message_trace_carrier, + ) + + return set_mcp_message_trace_carrier(carrier) + except ImportError: + return None + + +def _otel_reset_mcp_trace_carrier(token: object) -> None: + """Clear the per-message trace carrier so it never leaks to the next message on + the same session task. Paired with ``_otel_set_mcp_trace_carrier``.""" + if token is None: + return + try: + from litellm.integrations.otel.plumbing.context import ( + reset_mcp_message_trace_carrier, + ) + + reset_mcp_message_trace_carrier(token) + except ImportError: + return + + def _proxy_exception_to_http_exception(exc: ProxyException) -> HTTPException: """Map a ``ProxyException`` to an ``HTTPException`` that preserves its real status code and headers. @@ -253,14 +331,14 @@ def _proxy_exception_to_http_exception(exc: ProxyException) -> HTTPException: if MCP_AVAILABLE: from mcp.server import Server - from mcp.server.lowlevel.server import NotificationOptions - from mcp.server.models import InitializationOptions # Import auth context variables and middleware from mcp.server.auth.middleware.auth_context import ( AuthContextMiddleware, auth_context_var, ) + from mcp.server.lowlevel.server import NotificationOptions + from mcp.server.models import InitializationOptions try: from mcp.server.streamable_http_manager import StreamableHTTPSessionManager @@ -280,6 +358,8 @@ if MCP_AVAILABLE: ) from litellm.proxy._experimental.mcp_server.mcp_server_manager import ( MCPServerManager, + _caller_authorization_fans_out, + _client_forwarded_authorization_headers, _should_strip_caller_authorization, _without_authorization, global_mcp_server_manager, @@ -595,8 +675,10 @@ if MCP_AVAILABLE: _session_reset_token = None if req_ctx: _session_reset_token = active_mcp_session_var.set(req_ctx.session) + _trace_token = None try: + _trace_token = _otel_set_mcp_trace_carrier(_mcp_meta_trace_carrier(req_ctx)) # Get user authentication from context variable ( user_api_key_auth, @@ -612,6 +694,19 @@ if MCP_AVAILABLE: verbose_logger.debug( f"MCP list_tools - MCP server auth headers: {list(mcp_server_auth_headers.keys()) if mcp_server_auth_headers else None}" ) + if getattr( + getattr(user_api_key_auth, "object_permission", None), + "mcp_tool_search_enabled", + False, + ): + from mcp.types import Tool + + from litellm.proxy._experimental.mcp_server.tool_search import ( + get_virtual_tool_definitions, + ) + + return [Tool(**d) for d in get_virtual_tool_definitions()] + # Get mcp_servers from context variable verbose_logger.debug("MCP list_tools - Calling _list_mcp_tools") tools = await _list_mcp_tools( @@ -632,9 +727,154 @@ if MCP_AVAILABLE: # This prevents the HTTP stream from failing and allows the client to get a response return [] finally: + _otel_reset_mcp_trace_carrier(_trace_token) if _session_reset_token is not None: active_mcp_session_var.reset(_session_reset_token) + def _capture_host_progress_callback(host_server) -> Optional[Callable]: + """Return a progress-forwarding callback bound to the host MCP session. + + Returns ``None`` when the host did not supply a progress token. + """ + try: + host_ctx = host_server.request_context + except Exception as e: + verbose_logger.warning(f"Could not capture host progress context: {e}") + return None + + if not (host_ctx and hasattr(host_ctx, "meta") and host_ctx.meta): + return None + host_token = getattr(host_ctx.meta, "progressToken", None) + if host_token is None or not (hasattr(host_ctx, "session") and host_ctx.session): + return None + host_session = host_ctx.session + + async def forward_progress(progress: float, total: Optional[float]): + """Forward progress notifications from external MCP to Host""" + try: + await host_session.send_progress_notification( + progress_token=host_token, + progress=progress, + total=total, + ) + verbose_logger.debug(f"Forwarded progress {progress}/{total} to Host") + except Exception as e: + verbose_logger.error(f"Failed to forward progress to Host: {e}") + + verbose_logger.debug(f"Host progressToken captured: {str(host_token)[:8]}...") + return forward_progress + + async def _build_virtual_call_logging_obj( + name: str, + arguments: dict[str, Any], + user_api_key_auth: UserAPIKeyAuth, + ) -> Optional[LiteLLMLoggingObj]: + """Run the pre-call pipeline (guardrails + logging setup) for a virtual + mcp_tool_call so the SSE path spend-logs like the REST path.""" + from fastapi import Request + + from litellm.proxy.common_request_processing import ( + ProxyBaseLLMRequestProcessing, + ) + from litellm.proxy.proxy_server import ( + general_settings, + proxy_config, + proxy_logging_obj, + ) + + request = Request( + scope={ + "type": "http", + "method": "POST", + "path": "/mcp/tools/call", + "headers": [(b"content-type", b"application/json")], + } + ) + _, virtual_logging_obj = await ProxyBaseLLMRequestProcessing( + data={"name": name, "arguments": arguments} + ).common_processing_pre_call_logic( + request=request, + user_api_key_dict=user_api_key_auth, + proxy_config=proxy_config, + route_type=CallTypes.call_mcp_tool.value, + proxy_logging_obj=proxy_logging_obj, + general_settings=general_settings, + ) + return virtual_logging_obj + + async def _dispatch_virtual_mcp_tool( + name: str, + arguments: Optional[dict[str, Any]], + user_api_key_auth: Optional[UserAPIKeyAuth], + client_ip: Optional[str], + mcp_servers: Optional[list[str]] = None, + mcp_auth_header: Optional[str] = None, + mcp_server_auth_headers: Optional[dict[str, dict[str, str]]] = None, + oauth2_headers: Optional[dict[str, str]] = None, + raw_headers: Optional[dict[str, str]] = None, + ) -> Optional[CallToolResult]: + """Handle the mcp_tool_search / mcp_tool_call virtual tools. + + Returns a CallToolResult when ``name`` is a virtual tool, else ``None`` so + the caller falls through to normal tool routing. + """ + from litellm.proxy._experimental.mcp_server.tool_search import ( + MCP_TOOL_CALL_TOOL_NAME, + MCP_TOOL_SEARCH_TOOL_NAME, + coerce_top_k, + handle_mcp_tool_call, + handle_mcp_tool_search, + ) + + if name not in (MCP_TOOL_SEARCH_TOOL_NAME, MCP_TOOL_CALL_TOOL_NAME): + return None + + if not getattr( + getattr(user_api_key_auth, "object_permission", None), + "mcp_tool_search_enabled", + False, + ): + return CallToolResult( + content=[ + TextContent( + type="text", + text=f"Tool {name} requires mcp_tool_search_enabled on the key", + ) + ], + isError=True, + ) + + args = arguments or {} + if name == MCP_TOOL_SEARCH_TOOL_NAME: + return await handle_mcp_tool_search( + query=args.get("query", ""), + top_k=coerce_top_k(args.get("top_k", 5)), + user_api_key_dict=user_api_key_auth, + client_ip=client_ip, + mcp_servers=mcp_servers, + mcp_auth_header=mcp_auth_header, + mcp_server_auth_headers=mcp_server_auth_headers, + oauth2_headers=oauth2_headers, + raw_headers=raw_headers, + ) + + assert user_api_key_auth is not None # guaranteed by the flag check above + virtual_logging_obj = await _build_virtual_call_logging_obj( + name=name, arguments=args, user_api_key_auth=user_api_key_auth + ) + return await handle_mcp_tool_call( + tool_name=args.get("tool_name", ""), + arguments=args.get("arguments") or {}, + user_api_key_dict=user_api_key_auth, + client_ip=client_ip, + mcp_servers=mcp_servers, + mcp_auth_header=mcp_auth_header, + mcp_server_auth_headers=mcp_server_auth_headers, + oauth2_headers=oauth2_headers, + raw_headers=raw_headers, + litellm_logging_obj=virtual_logging_obj, + ) + @server.call_tool() async def mcp_server_tool_call(name: str, arguments: Dict[str, Any] | None) -> CallToolResult: """ @@ -648,18 +888,21 @@ if MCP_AVAILABLE: HTTPException: If tool not found or arguments missing """ from fastapi import Request + from mcp.server.lowlevel.server import request_ctx + from mcp.types import CallToolResult + from litellm.exceptions import BlockedPiiEntityError, GuardrailRaisedException from litellm.proxy.litellm_pre_call_utils import add_litellm_data_to_request from litellm.proxy.proxy_server import proxy_config - from mcp.types import CallToolResult - from mcp.server.lowlevel.server import request_ctx req_ctx = request_ctx.get(None) _session_reset_token = None if req_ctx: _session_reset_token = active_mcp_session_var.set(req_ctx.session) + _trace_token = None try: + _trace_token = _otel_set_mcp_trace_carrier(_mcp_meta_trace_carrier(req_ctx)) # Validate arguments ( user_api_key_auth, @@ -675,31 +918,25 @@ if MCP_AVAILABLE: ) verbose_logger.debug(f"MCP mcp_server_tool_call - User API Key Auth from context: {user_api_key_auth}") - host_progress_callback = None - try: - host_ctx = server.request_context - if host_ctx and hasattr(host_ctx, "meta") and host_ctx.meta: - host_token = getattr(host_ctx.meta, "progressToken", None) - if host_token and hasattr(host_ctx, "session") and host_ctx.session: - host_session = host_ctx.session - async def forward_progress(progress: float, total: Optional[float]): - """Forward progress notifications from external MCP to Host""" - try: - await host_session.send_progress_notification( - progress_token=host_token, - progress=progress, - total=total, - ) - verbose_logger.debug(f"Forwarded progress {progress}/{total} to Host") - except Exception as e: - verbose_logger.error(f"Failed to forward progress to Host: {e}") - - host_progress_callback = forward_progress - verbose_logger.debug(f"Host progressToken captured: {host_token[:8]}...") - except Exception as e: - verbose_logger.warning(f"Could not capture host progress context: {e}") try: + # Inside this try so virtual-tool errors convert to isError + # CallToolResult instead of raising out of the protocol handler. + virtual_tool_result = await _dispatch_virtual_mcp_tool( + name=name, + arguments=arguments, + user_api_key_auth=user_api_key_auth, + client_ip=_client_ip, + mcp_servers=mcp_servers, + mcp_auth_header=mcp_auth_header, + mcp_server_auth_headers=mcp_server_auth_headers, + oauth2_headers=oauth2_headers, + raw_headers=raw_headers, + ) + if virtual_tool_result is not None: + return virtual_tool_result + + host_progress_callback = _capture_host_progress_callback(server) # Create a body date for logging body_data = {"name": name, "arguments": arguments} # Set trace/session id from raw_headers so spend logs and logging_obj stay consistent (same as A2A) @@ -769,6 +1006,22 @@ if MCP_AVAILABLE: content=[TextContent(text=f"Error: {str(e.detail)}", type="text")], isError=True, ) + except MCPUpstreamAuthError as e: + # The MCP session manager serializes handler exceptions as JSON-RPC errors, so a + # mid-session tool call cannot emit a raw 401 + WWW-Authenticate the way the REST + # call path and the connect-time preemptive check do. Return an explicit isError + # naming the upstream status (at info level, not a traceback) so the client still + # learns it must re-authenticate upstream and expected pass-through 401s don't spam. + verbose_logger.info(f"Upstream auth failure calling MCP tool: HTTP {e.status_code}") + return CallToolResult( + content=[ + TextContent( + text=f"Error: upstream authentication required (HTTP {e.status_code})", + type="text", + ) + ], + isError=True, + ) except Exception as e: verbose_logger.exception(f"MCP mcp_server_tool_call - error: {e}") return CallToolResult( @@ -778,6 +1031,7 @@ if MCP_AVAILABLE: return response finally: + _otel_reset_mcp_trace_carrier(_trace_token) if _session_reset_token is not None: active_mcp_session_var.reset(_session_reset_token) @@ -1218,18 +1472,8 @@ if MCP_AVAILABLE: for allowed_mcp_server_id in allowed_mcp_server_ids: mcp_server = global_mcp_server_manager.get_mcp_server_by_id(allowed_mcp_server_id) if mcp_server is not None: - # Apply oauth2_flow resolution for legacy DB rows where it may be NULL - resolved_flow = MCPServerManager._resolve_oauth2_flow( - auth_type=mcp_server.auth_type, - oauth2_flow=mcp_server.oauth2_flow, - token_url=mcp_server.token_url, - authorization_url=mcp_server.authorization_url, - client_id=mcp_server.client_id, - client_secret=mcp_server.client_secret, - ) - if resolved_flow and resolved_flow != mcp_server.oauth2_flow: - # Create a new instance with the resolved flow for this request - mcp_server = mcp_server.model_copy(update={"oauth2_flow": resolved_flow}) + # Apply the request-time oauth2_flow backstop for legacy null rows. + mcp_server = MCPServerManager.resolve_oauth2_flow_for_request(mcp_server) allowed_mcp_servers.append(mcp_server) if mcp_servers is not None: @@ -1240,6 +1484,35 @@ if MCP_AVAILABLE: return allowed_mcp_servers + def _client_has_per_server_auth_header( + server: MCPServer, + mcp_server_auth_headers: Optional[Dict[str, Dict[str, str]]], + ) -> bool: + """True if the request carries a per-server ``x-mcp-{alias}-authorization`` + header for this server. This is the multi-server binding: it names one + upstream, so it is unambiguously the caller's upstream token regardless of + auth mode (never the LiteLLM admission credential). + + Resolves through the same ``lookup_mcp_server_auth_in_headers`` egress uses, so + the connect gate and egress agree on which per-server header names match: a + dashboard client sends ``x-mcp-{sanitize_mcp_alias_for_header(alias)}-authorization``, + and matching only the raw alias here would 401 a token egress would forward. + """ + if not mcp_server_auth_headers: + return False + from litellm.proxy._experimental.mcp_server.utils import ( + lookup_mcp_server_auth_in_headers, + ) + + server_headers = lookup_mcp_server_auth_in_headers( + mcp_server_auth_headers, alias=server.alias, server_name=server.server_name + ) + if isinstance(server_headers, str): + return bool(server_headers.strip()) + if isinstance(server_headers, dict): + return any(isinstance(hk, str) and hk.lower() == "authorization" for hk in server_headers) + return False + def _client_has_passthrough_authorization( server: MCPServer, oauth2_headers: Optional[Dict[str, str]], @@ -1257,24 +1530,7 @@ if MCP_AVAILABLE: for k in oauth2_headers.keys(): if k.lower() == "authorization": return True - if mcp_server_auth_headers: - for key in (server.alias, server.server_name, server.name): - if not key: - continue - server_headers = None - for k, v in mcp_server_auth_headers.items(): - if k.lower() == key.lower(): - server_headers = v - break - if server_headers is None: - continue - if isinstance(server_headers, str) and server_headers.strip(): - return True - if isinstance(server_headers, dict): - for hk in server_headers.keys(): - if hk.lower() == "authorization": - return True - return False + return _client_has_per_server_auth_header(server, mcp_server_auth_headers) async def _get_user_oauth_extra_headers_from_db( server: MCPServer, @@ -1329,8 +1585,16 @@ if MCP_AVAILABLE: oauth2_headers: Optional[Dict[str, str]], raw_headers: Optional[Dict[str, str]], user_api_key_auth: Optional[UserAPIKeyAuth] = None, + scope_servers: Optional[list[MCPServer]] = None, ) -> Tuple[Optional[Union[Dict[str, str], str]], Optional[Dict[str, str]]]: - """Build auth and extra headers for a server.""" + """Build auth and extra headers for a server. + + ``scope_servers`` is the full server list a fan-out handler iterates. Passing it lets the + client-forwarded token modes withhold the caller's request-wide ``Authorization`` when + another server in the scope would also receive it (``_caller_authorization_fans_out``); + explicitly-addressed operations leave it None. Per-server ``x-mcp-{alias}-authorization`` + headers are unaffected — they bind one token to one server and are the multi-server shape. + """ server_auth_header: Optional[Union[Dict[str, str], str]] = None if mcp_server_auth_headers: from litellm.proxy._experimental.mcp_server.utils import ( @@ -1344,6 +1608,16 @@ if MCP_AVAILABLE: ) extra_headers: Optional[Dict[str, str]] = None + is_client_forwarded_mode = server.is_true_passthrough or server.is_oauth_delegate + # In a multi-server listing scope the request-wide Authorization can only carry one token, + # so it is withheld from a client-forwarded server when another server in scope also consumes + # it (RFC 9700 cross-resource replay); such scopes must bind per-server via + # x-mcp-{alias}-authorization. The decision is computed once so BOTH the forwarding branch and + # the extra_headers copy loop below honor it — otherwise a server that lists Authorization in + # extra_headers would re-copy the withheld bearer from raw_headers and replay it anyway. + withhold_forwarded_authorization = is_client_forwarded_mode and _caller_authorization_fans_out( + server, scope_servers + ) if server.auth_type == MCPAuth.oauth2: # For OAuth2 M2M servers, upstream Authorization must come from # client_credentials token fetch, never from caller headers. @@ -1362,6 +1636,14 @@ if MCP_AVAILABLE: user_api_key_auth=user_api_key_auth, ): extra_headers = _without_authorization(extra_headers) + elif is_client_forwarded_mode: + if not withhold_forwarded_authorization: + extra_headers = _client_forwarded_authorization_headers( + mcp_server=server, + oauth2_headers=oauth2_headers, + raw_headers=raw_headers, + user_api_key_auth=user_api_key_auth, + ) if server.extra_headers and raw_headers: if extra_headers is None: @@ -1382,7 +1664,9 @@ if MCP_AVAILABLE: for header in server.extra_headers: if not isinstance(header, str): continue - if header.lower() == "authorization" and strip_caller_authorization: + if header.lower() == "authorization" and ( + strip_caller_authorization or withhold_forwarded_authorization + ): continue header_value = normalized_raw_headers.get(header.lower()) if header_value is None: @@ -1472,6 +1756,8 @@ if MCP_AVAILABLE: log_list_tools_to_spendlogs: bool = False, list_tools_log_source: Optional[str] = None, litellm_trace_id: Optional[str] = None, + request_tags: Optional[list[str]] = None, + client_ip: Optional[str] = None, ) -> List[MCPTool]: """ Helper method to fetch tools from MCP servers based on server filtering criteria. @@ -1514,6 +1800,7 @@ if MCP_AVAILABLE: "litellm_trace_id": effective_litellm_trace_id, "metadata": { "spend_logs_metadata": spend_logs_metadata, + **({"tags": request_tags} if request_tags else {}), }, # Provide a small input payload for standard logging "input": [ @@ -1559,6 +1846,7 @@ if MCP_AVAILABLE: allowed_mcp_servers = await _get_allowed_mcp_servers( user_api_key_auth=user_api_key_auth, mcp_servers=mcp_servers, + client_ip=client_ip, ) # Pre-fetch OAuth credentials only when at least one server uses OAuth2, @@ -1582,6 +1870,7 @@ if MCP_AVAILABLE: oauth2_headers=oauth2_headers, raw_headers=raw_headers, user_api_key_auth=user_api_key_auth, + scope_servers=allowed_mcp_servers, ) # Prefer server-stored per-user OAuth when configured, so a stale @@ -1625,6 +1914,7 @@ if MCP_AVAILABLE: add_prefix=True, # Always add server prefix raw_headers=raw_headers, user_api_key_auth=user_api_key_auth, + oauth2_headers=oauth2_headers, ) filtered_tools = filter_tools_by_allowed_tools(tools, server) @@ -1643,12 +1933,14 @@ if MCP_AVAILABLE: ) return filtered_tools except MCPUpstreamAuthError: - # Surface upstream 401/403 to the outer handler so the - # client receives a proper WWW-Authenticate challenge - # instead of a silently empty tool list. Without this - # re-raise the broad ``except Exception`` below would - # swallow the auth error. - raise + # Absorb so one unauthenticated server does not empty every other server's + # tools. Surfacing the upstream 401 to the client as a re-auth challenge is + # intentionally not done here: raising from this list handler cannot produce a + # 401 + WWW-Authenticate (the MCP session manager serializes it as a JSON-RPC + # error). Single-server routes surface it via the request-scope preemptive + # check in _raise_preemptive_401_for_unauthenticated_servers instead. + verbose_logger.debug(f"MCP list_tools: omitting {server.name}; it needs upstream auth") + return [] except Exception as e: verbose_logger.exception(f"Error getting tools from server {server.name}: {str(e)}") return [] @@ -1687,7 +1979,9 @@ if MCP_AVAILABLE: end_time = datetime.now() try: await litellm_logging_obj.async_success_handler( - result=all_tools, + result=[ + tool.model_dump(mode="json") if isinstance(tool, MCPTool) else tool for tool in all_tools + ], start_time=list_tools_start_time, end_time=end_time, ) @@ -1763,6 +2057,7 @@ if MCP_AVAILABLE: oauth2_headers=oauth2_headers, raw_headers=raw_headers, user_api_key_auth=user_api_key_auth, + scope_servers=allowed_mcp_servers, ) try: @@ -1815,6 +2110,7 @@ if MCP_AVAILABLE: oauth2_headers=oauth2_headers, raw_headers=raw_headers, user_api_key_auth=user_api_key_auth, + scope_servers=allowed_mcp_servers, ) try: @@ -1865,6 +2161,7 @@ if MCP_AVAILABLE: oauth2_headers=oauth2_headers, raw_headers=raw_headers, user_api_key_auth=user_api_key_auth, + scope_servers=allowed_mcp_servers, ) try: @@ -1967,6 +2264,7 @@ if MCP_AVAILABLE: raw_headers: Optional[Dict[str, str]] = None, log_list_tools_to_spendlogs: bool = False, list_tools_log_source: Optional[str] = None, + client_ip: Optional[str] = None, ) -> List[MCPTool]: """ List all available MCP tools. @@ -1976,6 +2274,7 @@ if MCP_AVAILABLE: mcp_auth_header: Optional auth header for MCP server (deprecated) mcp_servers: Optional list of server names/aliases to filter by mcp_server_auth_headers: Optional dict of server-specific auth headers {server_alias: auth_value} + client_ip: Client IP for IP-based server access control Returns: List[MCPTool]: Combined list of tools from all accessible servers @@ -1999,6 +2298,7 @@ if MCP_AVAILABLE: raw_headers=raw_headers, log_list_tools_to_spendlogs=log_list_tools_to_spendlogs, list_tools_log_source=list_tools_log_source, + client_ip=client_ip, ) verbose_logger.debug(f"Successfully fetched {len(managed_tools)} tools from managed MCP servers") except Exception as e: @@ -2473,12 +2773,18 @@ if MCP_AVAILABLE: # Forward named client headers to OpenAPI tool upstream requests. # MCPServer.extra_headers lists header names to copy from raw_headers. - # OAuth2 M2M: never take Authorization from the caller (matches - # _prepare_mcp_server_headers for managed MCP). + # The strip decision is centralized in _should_strip_caller_authorization so this + # OpenAPI/local path agrees with the managed paths: M2M and the resolver-owned modes + # (token_exchange's raw subject token, authorization_code's stored token) must never + # have the caller's Authorization forwarded verbatim upstream. forwarded_headers: Optional[Dict[str, str]] = None if mcp_server and mcp_server.extra_headers and raw_headers: normalized_raw = {str(k).lower(): v for k, v in raw_headers.items() if isinstance(k, str)} - skip_caller_authorization = bool(mcp_server.has_client_credentials) + skip_caller_authorization = _should_strip_caller_authorization( + mcp_server=mcp_server, + raw_headers=raw_headers, + user_api_key_auth=user_api_key_auth, + ) for header_name in mcp_server.extra_headers: if not isinstance(header_name, str): continue @@ -2526,6 +2832,74 @@ if MCP_AVAILABLE: return response + _MCP_CREDENTIAL_REQUEST_FIELDS = frozenset( + { + "raw_headers", + "mcp_auth_header", + "mcp_server_auth_headers", + "oauth2_headers", + "user_api_key_auth", + } + ) + + async def _fire_mcp_tool_call_logging( + logging_obj: LiteLLMLoggingObj, + result: Any, + start_time: datetime, + end_time: datetime, + user_api_key_auth: Optional[UserAPIKeyAuth] = None, + request_data: Optional[Mapping[str, object]] = None, + ) -> None: + """Fire post-call logging for an executed MCP tool call. + + A result with ``isError=True`` is logged as a failure (``status="failure"`` + payload, so OTel marks the span ERROR) while the HTTP wire behavior stays + 200 + ``isError: true`` per the MCP spec. The error check runs after + ``async_post_mcp_tool_call_hook`` because guardrails may flip the result + to ``isError=True`` in that hook. Raised exceptions never reach here (the + ``@client`` wrapper and ``call_mcp_tool``'s except path log those), so + this cannot double-log a failure. + + ``request_data`` may carry credential-bearing fields (the REST path puts + ``raw_headers``, ``mcp_auth_header``, ``mcp_server_auth_headers``, and + ``oauth2_headers`` at the top level of its data dict), so those are + stripped before the dict is handed to ``post_call_failure_hook`` + callbacks. + """ + logging_obj.post_call(original_response=result) + await logging_obj.async_post_mcp_tool_call_hook( + kwargs=logging_obj.model_call_details, + response_obj=result, + start_time=start_time, + end_time=end_time, + ) + logging_obj.call_type = CallTypes.call_mcp_tool.value + error_message = extract_mcp_tool_result_error_message(result) + if error_message is None: + await logging_obj.async_success_handler(result=result, start_time=start_time, end_time=end_time) + return + + logging_obj.has_run_logging(event_type="sync_success") + logging_obj.has_run_logging(event_type="async_success") + tool_error = MCPToolResultError(error_message) + logging_obj.failure_handler(tool_error, "", start_time, end_time) + await logging_obj.async_failure_handler(tool_error, "", start_time, end_time) + + if user_api_key_auth is None: + return + from litellm.proxy.proxy_server import proxy_logging_obj + + if proxy_logging_obj: + sanitized_request_data = { + key: value for key, value in (request_data or {}).items() if key not in _MCP_CREDENTIAL_REQUEST_FIELDS + } + await proxy_logging_obj.post_call_failure_hook( + request_data=sanitized_request_data, + original_exception=tool_error, + user_api_key_dict=user_api_key_auth, + route="/mcp/call_tool", + ) + @client async def call_mcp_tool( name: str, @@ -2557,6 +2931,9 @@ if MCP_AVAILABLE: for allowed_mcp_server_id in allowed_mcp_server_ids: allowed_server = global_mcp_server_manager.get_mcp_server_by_id(allowed_mcp_server_id) if allowed_server is not None: + # Same request-time oauth2_flow backstop the listing path applies, + # so a null-flow M2M-shape row is treated as M2M on tool calls too. + allowed_server = MCPServerManager.resolve_oauth2_flow_for_request(allowed_server) allowed_mcp_servers.append(allowed_server) allowed_mcp_servers = await _get_allowed_mcp_servers_from_mcp_server_names( @@ -2582,6 +2959,14 @@ if MCP_AVAILABLE: raw_headers=raw_headers, **kwargs, ) + except MCPUpstreamAuthError: + # A client-forwarded pass-through upstream 401 is an expected caller-must-reauth signal, so + # re-raise it without post_call_failure_hook, which fires the proxy's llm_exceptions alert. + # mcp_server_tool_call then downgrades it to an informational isError result for the + # streamable client. Note: this function is @client-decorated, so the decorator's standard + # failure logging still records the event (spend log / OTel); only the extra alert sink is + # skipped here. + raise except Exception as e: traceback_str = traceback.format_exc(limit=MAXIMUM_TRACEBACK_LINES_TO_LOG) from litellm.proxy.proxy_server import proxy_logging_obj @@ -2597,16 +2982,14 @@ if MCP_AVAILABLE: raise if litellm_logging_obj: - litellm_logging_obj.post_call(original_response=response) - end_time = datetime.now() - await litellm_logging_obj.async_post_mcp_tool_call_hook( - kwargs=litellm_logging_obj.model_call_details, - response_obj=response, + await _fire_mcp_tool_call_logging( + logging_obj=litellm_logging_obj, + result=response, start_time=start_time, - end_time=end_time, + end_time=datetime.now(), + user_api_key_auth=user_api_key_auth, + request_data=kwargs, ) - litellm_logging_obj.call_type = CallTypes.call_mcp_tool.value - await litellm_logging_obj.async_success_handler(result=response, start_time=start_time, end_time=end_time) return response async def mcp_get_prompt( @@ -2727,6 +3110,8 @@ if MCP_AVAILABLE: mcp_server_logo_url=mcp_info.get("logo_url"), namespaced_tool_name=namespaced_tool_name, mcp_session_id=session_id, + mcp_auth_mode=mcp_server.auth_type, + mcp_server_resource=_redact_mcp_resource_url(mcp_server.url), ) else: return StandardLoggingMCPToolCall( @@ -3240,6 +3625,36 @@ if MCP_AVAILABLE: headers={"www-authenticate": authorization_uri}, ) + # token_exchange (OBO): the caller supplied no subject token. Challenge at connect + # (transport level, where WWW-Authenticate survives) with the RFC 9728 resource_metadata + # so the client discovers the IdP, SSOs, and retries with a subject token, which LiteLLM + # then exchanges. A tool-call-time 401 would be wrapped into a JSON-RPC error and the + # header lost, so the discovery flow needs this pre-emptive challenge. + if server and server.auth_type == MCPAuth.oauth2_token_exchange and not oauth2_headers: + from litellm.proxy._experimental.mcp_server.outbound_credentials.adapter import ( # noqa: PLC0415 + raise_token_exchange_challenge, + ) + from litellm.proxy.utils import get_server_root_path # noqa: PLC0415 + + raise_token_exchange_challenge(server, root_path=get_server_root_path()) + + # token_exchange (OBO) with a subject present: run the exchange here at the transport + # edge, so a rejected subject raises the RFC 9728 challenge (and a gateway fault its + # public status) instead of the session opening and list_tools masking the failure as + # an empty tool list. Gated to single-server routes; the multi-server aggregate keeps + # absorbing per-server auth failures so one bad server cannot 401 the whole connect. + if ( + server + and server.auth_type == MCPAuth.oauth2_token_exchange + and oauth2_headers + and len(mcp_servers or []) == 1 + ): + await global_mcp_server_manager.preflight_token_exchange( + server=server, + oauth2_headers=oauth2_headers, + user_api_key_auth=user_api_key_auth, + ) + # Pass-through OAuth: when the admin has opted a server into # forwarding the client's bearer token (is_oauth_passthrough) and # the client hasn't supplied one, fail fast with 401 and point @@ -3261,6 +3676,52 @@ if MCP_AVAILABLE: headers={"www-authenticate": www_authenticate}, ) + if ( + server + and server.is_oauth_delegate + and len(mcp_servers or []) == 1 + and _get_forwarded_auth_from_scope(scope) is None + and not _client_has_per_server_auth_header(server, mcp_server_auth_headers) + ): + www_authenticate = _get_passthrough_www_authenticate( + scope=scope, + server_name=server_name, + ) + raise HTTPException( + status_code=401, + detail="Unauthorized", + headers={"www-authenticate": www_authenticate}, + ) + + if ( + server + and server.is_true_passthrough + and len(mcp_servers or []) == 1 + and not _scope_has_authorization_header(scope) + and not _client_has_per_server_auth_header(server, mcp_server_auth_headers) + ): + if server.is_dcr_bridge: + raise HTTPException( + status_code=401, + detail="Unauthorized", + headers={ + "www-authenticate": _get_passthrough_www_authenticate( + scope=scope, + server_name=server_name, + ) + }, + ) + upstream_status, upstream_www_authenticate = await _probe_upstream_auth(server.url or "", "") + if upstream_status == 401 and upstream_www_authenticate: + raise HTTPException( + status_code=401, + detail="Unauthorized", + headers={"www-authenticate": upstream_www_authenticate}, + ) + + def _scope_has_authorization_header(scope: Scope) -> bool: + return any(key.lower() == b"authorization" for key, _ in scope.get("headers", [])) + def _get_forwarded_auth_from_scope(scope: Scope) -> Optional[str]: """Return the upstream-bound ``Authorization`` header value, or None. @@ -3288,7 +3749,7 @@ if MCP_AVAILABLE: url: str, auth_header: str, timeout: float = 5.0, - ) -> tuple: + ) -> tuple[int, Optional[str]]: """JSON-RPC initialize-probe the upstream URL to check whether the token is accepted. Uses POST so StreamableHTTP MCP servers run the same auth path as a @@ -3318,8 +3779,8 @@ if MCP_AVAILABLE: }, } probe_headers = { - "Authorization": auth_header, "Accept": "application/json, text/event-stream", + **({"Authorization": auth_header} if auth_header else {}), } try: resp = await client.post( diff --git a/litellm/proxy/_experimental/mcp_server/tool_search.py b/litellm/proxy/_experimental/mcp_server/tool_search.py new file mode 100644 index 00000000000..fa57a2b3eb2 --- /dev/null +++ b/litellm/proxy/_experimental/mcp_server/tool_search.py @@ -0,0 +1,157 @@ +from __future__ import annotations + +import json +from datetime import datetime +from typing import TYPE_CHECKING, Any, Optional + +if TYPE_CHECKING: + from mcp.types import CallToolResult + + from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj + from litellm.proxy._types import UserAPIKeyAuth + +MCP_TOOL_SEARCH_TOOL_NAME: str = "mcp_tool_search" +MCP_TOOL_CALL_TOOL_NAME: str = "mcp_tool_call" + + +def coerce_top_k(value: Any, default: int = 5) -> int: + try: + return int(value) + except (TypeError, ValueError): + return default + + +def search_tools(query: str, tools: list[dict[str, Any]], top_k: int = 5) -> list[dict[str, Any]]: + if not query: + return [] + tokens = query.lower().split() + + def _score(tool: dict[str, Any]) -> int: + haystack = (tool.get("name", "") + " " + tool.get("description", "")).lower() + return sum(1 for t in tokens if t in haystack) + + scored = ((s, tool) for tool in tools if (s := _score(tool)) > 0) + return [tool for _, tool in sorted(scored, key=lambda x: x[0], reverse=True)[:top_k]] + + +def get_virtual_tool_definitions() -> list[dict[str, Any]]: + return [ + { + "name": MCP_TOOL_SEARCH_TOOL_NAME, + "description": "Search for MCP tools by keyword. Returns top matching tools with names, descriptions, and input schemas.", + "inputSchema": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "Keywords to search for in tool names and descriptions.", + }, + "top_k": { + "type": "integer", + "description": "Maximum number of results to return.", + "default": 5, + }, + }, + "required": ["query"], + }, + }, + { + "name": MCP_TOOL_CALL_TOOL_NAME, + "description": "Call an MCP tool by name with the given arguments.", + "inputSchema": { + "type": "object", + "properties": { + "tool_name": { + "type": "string", + "description": "The exact name of the MCP tool to call.", + }, + "arguments": { + "type": "object", + "description": "Arguments to pass to the tool.", + }, + }, + "required": ["tool_name"], + }, + }, + ] + + +async def handle_mcp_tool_search( + query: str, + top_k: int, + user_api_key_dict: UserAPIKeyAuth, + client_ip: Optional[str] = None, + mcp_servers: Optional[list[str]] = None, + mcp_auth_header: Optional[str] = None, + mcp_server_auth_headers: Optional[dict[str, dict[str, str]]] = None, + oauth2_headers: Optional[dict[str, str]] = None, + raw_headers: Optional[dict[str, str]] = None, +) -> CallToolResult: + from mcp.types import CallToolResult, TextContent + + from litellm.proxy._experimental.mcp_server.server import _list_mcp_tools + + mcp_tools = await _list_mcp_tools( + user_api_key_auth=user_api_key_dict, + mcp_servers=mcp_servers, + client_ip=client_ip, + mcp_auth_header=mcp_auth_header, + mcp_server_auth_headers=mcp_server_auth_headers, + oauth2_headers=oauth2_headers, + raw_headers=raw_headers, + ) + tools = [ + { + "name": t.name, + "description": t.description or "", + "inputSchema": t.inputSchema, + } + for t in mcp_tools + ] + results = search_tools(query, tools, top_k) + return CallToolResult(content=[TextContent(type="text", text=json.dumps(results))], isError=False) + + +async def handle_mcp_tool_call( + tool_name: str, + arguments: dict[str, Any], + user_api_key_dict: UserAPIKeyAuth, + client_ip: Optional[str] = None, + mcp_servers: Optional[list[str]] = None, + mcp_auth_header: Optional[str] = None, + mcp_server_auth_headers: Optional[dict[str, dict[str, str]]] = None, + oauth2_headers: Optional[dict[str, str]] = None, + raw_headers: Optional[dict[str, str]] = None, + litellm_logging_obj: Optional[LiteLLMLoggingObj] = None, +) -> CallToolResult: + from litellm.proxy._experimental.mcp_server.server import ( + _get_allowed_mcp_servers, + execute_mcp_tool, + ) + + allowed_mcp_servers = await _get_allowed_mcp_servers( + user_api_key_auth=user_api_key_dict, + mcp_servers=mcp_servers, + client_ip=client_ip, + ) + + # Reject before dispatch when the key has no accessible servers; otherwise an + # unprefixed local tool name would fall through to the local registry in + # execute_mcp_tool, which has no server permission check. + if not allowed_mcp_servers: + from fastapi import HTTPException + + raise HTTPException(status_code=403, detail="User not allowed to call this tool.") + + return await execute_mcp_tool( + name=tool_name, + arguments=arguments, + allowed_mcp_servers=allowed_mcp_servers, + start_time=datetime.now(), + user_api_key_auth=user_api_key_dict, + mcp_auth_header=mcp_auth_header, + mcp_server_auth_headers=mcp_server_auth_headers, + oauth2_headers=oauth2_headers, + raw_headers=raw_headers, + litellm_logging_obj=litellm_logging_obj, + ) diff --git a/litellm/proxy/_experimental/mcp_server/utils.py b/litellm/proxy/_experimental/mcp_server/utils.py index 9cb6d404b01..80a469b8c1a 100644 --- a/litellm/proxy/_experimental/mcp_server/utils.py +++ b/litellm/proxy/_experimental/mcp_server/utils.py @@ -214,12 +214,14 @@ def server_applies_tool_allowlist(mcp_server: Any) -> bool: def validate_and_normalize_mcp_server_payload(payload: Any) -> None: """ - Validate and normalize MCP server payload fields (server_name and alias). + Validate and normalize MCP server payload fields (server_name, alias, and + tool_name_to_display_name). This function: 1. Validates that server_name and alias don't contain the MCP_TOOL_PREFIX_SEPARATOR - 2. Normalizes alias by replacing spaces with underscores - 3. Sets default alias if not provided (using server_name as base) + 2. Validates that tool_name_to_display_name values satisfy Bedrock's tool-name pattern + 3. Normalizes alias by replacing spaces with underscores + 4. Sets default alias if not provided (using server_name as base) Args: payload: The payload object containing server_name and alias fields @@ -235,6 +237,10 @@ def validate_and_normalize_mcp_server_payload(payload: Any) -> None: if hasattr(payload, "alias") and payload.alias: validate_mcp_server_name(payload.alias, raise_http_exception=True) + # Tool display name validation: must satisfy Bedrock's tool-name pattern + if hasattr(payload, "tool_name_to_display_name") and payload.tool_name_to_display_name: + validate_tool_display_names(payload.tool_name_to_display_name) + # Alias normalization and defaulting alias = getattr(payload, "alias", None) server_name = getattr(payload, "server_name", None) @@ -409,6 +415,61 @@ def validate_mcp_server_name(server_name: str, raise_http_exception: bool = Fals raise Exception(error_message) +def extract_mcp_tool_result_error_message(result: object) -> Optional[str]: + """The first text content of an ``isError=True`` tool result, or ``None`` + when the result is not an error. + + Accepts both ``mcp.types.CallToolResult`` objects and their dict + equivalents, duck-typed so the ``mcp`` package is not required. + """ + is_error: object = result.get("isError") if isinstance(result, Mapping) else getattr(result, "isError", None) + if is_error is not True: + return None + content: object = result.get("content") if isinstance(result, Mapping) else getattr(result, "content", None) + if isinstance(content, (list, tuple)): + for item in content: + text: object = item.get("text") if isinstance(item, Mapping) else getattr(item, "text", None) + if isinstance(text, str) and text: + return text + return "MCP tool call returned isError=true" + + +TOOL_DISPLAY_NAME_PATTERN = re.compile(r"^[a-zA-Z0-9_-]+$") + + +def validate_tool_display_names(tool_name_to_display_name: Optional[Mapping[str, str]]) -> None: + """ + Validate tool display name overrides against Bedrock's tool-name constraint. + + A display name replaces the tool name sent to the LLM provider, so it must + satisfy the strictest provider requirement in use (Bedrock's + ``[a-zA-Z0-9_-]+``); a name with spaces or other characters saves + successfully but fails every subsequent Bedrock tool call. + + Raises: + HTTPException: If any display name fails the pattern. + """ + if not tool_name_to_display_name: + return + + for original_name, display_name in tool_name_to_display_name.items(): + if display_name and not TOOL_DISPLAY_NAME_PATTERN.match(display_name): + from fastapi import HTTPException + from starlette import status + + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail={ + "error": ( + f"Invalid display name '{display_name}' for tool '{original_name}'. " + "Display names may only contain letters, digits, underscores, and " + "hyphens (no spaces or other special characters), since they replace " + "the tool name sent to the LLM provider." + ) + }, + ) + + class MCPMissingUserEnvVarsError(Exception): """Raised when an MCP request can't be built because the calling user has not supplied one or more required per-user environment variables. diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html new file mode 100644 index 00000000000..4009a7f4b95 --- /dev/null +++ b/litellm/proxy/_experimental/out/404.html @@ -0,0 +1 @@ +404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

\ No newline at end of file diff --git a/litellm/proxy/_experimental/out/404/index.html b/litellm/proxy/_experimental/out/404/index.html new file mode 100644 index 00000000000..4009a7f4b95 --- /dev/null +++ b/litellm/proxy/_experimental/out/404/index.html @@ -0,0 +1 @@ +404: This page could not be found.LiteLLM Dashboard

404

This page could not be found.

\ No newline at end of file diff --git a/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.__PAGE__.txt b/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.__PAGE__.txt new file mode 100644 index 00000000000..6aa34991087 --- /dev/null +++ b/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.__PAGE__.txt @@ -0,0 +1,9 @@ +1:"$Sreact.fragment" +2:I[347257,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"ClientPageRoot"] +3:I[871135,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js","/litellm-asset-prefix/_next/static/chunks/0uuigwiz-in3~.js","/litellm-asset-prefix/_next/static/chunks/0-0c4mv4-mc9n.js","/litellm-asset-prefix/_next/static/chunks/0lg.6rbfsd-l9.js","/litellm-asset-prefix/_next/static/chunks/0p3v32gvsxp6h.js","/litellm-asset-prefix/_next/static/chunks/0x09ws363q4_0.js","/litellm-asset-prefix/_next/static/chunks/08o64zaid_juv.js","/litellm-asset-prefix/_next/static/chunks/043q3g5-5-aju.js","/litellm-asset-prefix/_next/static/chunks/0g9k1~ppf2hw3.js","/litellm-asset-prefix/_next/static/chunks/151r-5htw45m~.js","/litellm-asset-prefix/_next/static/chunks/0v85l0arelm41.js","/litellm-asset-prefix/_next/static/chunks/0zbgu4ogb6mba.js","/litellm-asset-prefix/_next/static/chunks/0ae3np_qb52e-.js","/litellm-asset-prefix/_next/static/chunks/0zam.8alu6_vj.js","/litellm-asset-prefix/_next/static/chunks/0uu6lckpr0s15.js","/litellm-asset-prefix/_next/static/chunks/0.bx44y-6~tug.js","/litellm-asset-prefix/_next/static/chunks/0l7em-5kjv49e.js","/litellm-asset-prefix/_next/static/chunks/0el08tticy_20.js","/litellm-asset-prefix/_next/static/chunks/0-s2am3eulbyd.js","/litellm-asset-prefix/_next/static/chunks/0sx3mu2_l9g_y.js","/litellm-asset-prefix/_next/static/chunks/0.w8~sa9q0n_s.js","/litellm-asset-prefix/_next/static/chunks/00q4mtjboprhm.js","/litellm-asset-prefix/_next/static/chunks/0zrbitbm~0koh.js","/litellm-asset-prefix/_next/static/chunks/0c4pfjjue0uc-.js","/litellm-asset-prefix/_next/static/chunks/0efmbzvj03niy.js","/litellm-asset-prefix/_next/static/chunks/055egae-ggkjh.js","/litellm-asset-prefix/_next/static/chunks/0hwip5a7qsmis.js","/litellm-asset-prefix/_next/static/chunks/0q6~n4y84cejn.js","/litellm-asset-prefix/_next/static/chunks/0mh1wnrvmv_y7.js"],"default"] +6:I[897367,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"OutletBoundary"] +7:"$Sreact.suspense" +0:{"rsc":["$","$1","c",{"children":[["$","$L2",null,{"Component":"$3","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@4","$@5"]}}],[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/0ae3np_qb52e-.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/0zam.8alu6_vj.js","async":true}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/0uu6lckpr0s15.js","async":true}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/0.bx44y-6~tug.js","async":true}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/0l7em-5kjv49e.js","async":true}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/0el08tticy_20.js","async":true}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/0-s2am3eulbyd.js","async":true}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/0sx3mu2_l9g_y.js","async":true}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/0.w8~sa9q0n_s.js","async":true}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/00q4mtjboprhm.js","async":true}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/0zrbitbm~0koh.js","async":true}],["$","script","script-11",{"src":"/litellm-asset-prefix/_next/static/chunks/0c4pfjjue0uc-.js","async":true}],["$","script","script-12",{"src":"/litellm-asset-prefix/_next/static/chunks/0efmbzvj03niy.js","async":true}],["$","script","script-13",{"src":"/litellm-asset-prefix/_next/static/chunks/055egae-ggkjh.js","async":true}],["$","script","script-14",{"src":"/litellm-asset-prefix/_next/static/chunks/0hwip5a7qsmis.js","async":true}],["$","script","script-15",{"src":"/litellm-asset-prefix/_next/static/chunks/0q6~n4y84cejn.js","async":true}],["$","script","script-16",{"src":"/litellm-asset-prefix/_next/static/chunks/0mh1wnrvmv_y7.js","async":true}]],["$","$L6",null,{"children":["$","$7",null,{"name":"Next.MetadataOutlet","children":"$@8"}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"KYqiq5stbD-H4YcZ-6OuP"} +4:{} +5:"$0:rsc:props:children:0:props:serverProvidedParams:params" +8:null diff --git a/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.txt b/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.txt new file mode 100644 index 00000000000..b52b61e168b --- /dev/null +++ b/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.txt @@ -0,0 +1,7 @@ +1:"$Sreact.fragment" +2:I[92825,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"ClientSegmentRoot"] +3:I[216370,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js","/litellm-asset-prefix/_next/static/chunks/0uuigwiz-in3~.js","/litellm-asset-prefix/_next/static/chunks/0-0c4mv4-mc9n.js","/litellm-asset-prefix/_next/static/chunks/0lg.6rbfsd-l9.js","/litellm-asset-prefix/_next/static/chunks/0p3v32gvsxp6h.js","/litellm-asset-prefix/_next/static/chunks/0x09ws363q4_0.js","/litellm-asset-prefix/_next/static/chunks/08o64zaid_juv.js","/litellm-asset-prefix/_next/static/chunks/043q3g5-5-aju.js","/litellm-asset-prefix/_next/static/chunks/0g9k1~ppf2hw3.js","/litellm-asset-prefix/_next/static/chunks/151r-5htw45m~.js","/litellm-asset-prefix/_next/static/chunks/0v85l0arelm41.js","/litellm-asset-prefix/_next/static/chunks/0zbgu4ogb6mba.js"],"default"] +4:I[339756,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"default"] +5:I[837457,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"default"] +0:{"rsc":["$","$1","c",{"children":[[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/0uuigwiz-in3~.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/0-0c4mv4-mc9n.js","async":true}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/0lg.6rbfsd-l9.js","async":true}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/0p3v32gvsxp6h.js","async":true}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/0x09ws363q4_0.js","async":true}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/08o64zaid_juv.js","async":true}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/043q3g5-5-aju.js","async":true}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/0g9k1~ppf2hw3.js","async":true}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/151r-5htw45m~.js","async":true}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/0v85l0arelm41.js","async":true}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/0zbgu4ogb6mba.js","async":true}]],["$","$L2",null,{"Component":"$3","slots":{"children":["$","$L4",null,{"parallelRouterKey":"children","template":["$","$L5",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."}]}]]}]}]],[]]}]},"serverProvidedParams":{"params":{},"promises":["$@6"]}}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"KYqiq5stbD-H4YcZ-6OuP"} +6:"$0:rsc:props:children:1:props:serverProvidedParams:params" diff --git a/litellm/proxy/_experimental/out/__next._full.txt b/litellm/proxy/_experimental/out/__next._full.txt new file mode 100644 index 00000000000..bb67fb01bc2 --- /dev/null +++ b/litellm/proxy/_experimental/out/__next._full.txt @@ -0,0 +1,30 @@ +1:"$Sreact.fragment" +2:I[867271,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"default"] +3:I[71195,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"default"] +4:I[557951,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"AuthProvider"] +5:I[339756,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"default"] +6:I[837457,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"default"] +7:I[92825,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"ClientSegmentRoot"] +8:I[216370,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js","/litellm-asset-prefix/_next/static/chunks/0uuigwiz-in3~.js","/litellm-asset-prefix/_next/static/chunks/0-0c4mv4-mc9n.js","/litellm-asset-prefix/_next/static/chunks/0lg.6rbfsd-l9.js","/litellm-asset-prefix/_next/static/chunks/0p3v32gvsxp6h.js","/litellm-asset-prefix/_next/static/chunks/0x09ws363q4_0.js","/litellm-asset-prefix/_next/static/chunks/08o64zaid_juv.js","/litellm-asset-prefix/_next/static/chunks/043q3g5-5-aju.js","/litellm-asset-prefix/_next/static/chunks/0g9k1~ppf2hw3.js","/litellm-asset-prefix/_next/static/chunks/151r-5htw45m~.js","/litellm-asset-prefix/_next/static/chunks/0v85l0arelm41.js","/litellm-asset-prefix/_next/static/chunks/0zbgu4ogb6mba.js"],"default"] +c:I[168027,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"default",1] +:HL["/litellm-asset-prefix/_next/static/chunks/05qmwjqau64bz.css","style"] +:HL["/litellm-asset-prefix/_next/static/chunks/075sund.-mh4~.css","style"] +:HL["/litellm-asset-prefix/_next/static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2","font",{"crossOrigin":"","type":"font/woff2"}] +0:{"P":null,"c":["",""],"q":"","i":false,"f":[[["",{"children":["(dashboard)",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",16],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/05qmwjqau64bz.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/075sund.-mh4~.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"inter_5972bc34-module__OU16Qa__className","children":["$","$L2",null,{"children":["$","$L3",null,{"children":["$","$L4",null,{"children":["$","$L5",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L6",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","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."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]}]}]]}],{"children":[["$","$1","c",{"children":[[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/0uuigwiz-in3~.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/0-0c4mv4-mc9n.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/0lg.6rbfsd-l9.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/0p3v32gvsxp6h.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/0x09ws363q4_0.js","async":true,"nonce":"$undefined"}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/08o64zaid_juv.js","async":true,"nonce":"$undefined"}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/043q3g5-5-aju.js","async":true,"nonce":"$undefined"}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/0g9k1~ppf2hw3.js","async":true,"nonce":"$undefined"}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/151r-5htw45m~.js","async":true,"nonce":"$undefined"}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/0v85l0arelm41.js","async":true,"nonce":"$undefined"}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/0zbgu4ogb6mba.js","async":true,"nonce":"$undefined"}]],["$","$L7",null,{"Component":"$8","slots":{"children":["$","$L5",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L6",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:props:notFound:0:1:props:style","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":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style","children":404}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style","children":["$","h2",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style","children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]},"serverProvidedParams":{"params":{},"promises":["$@9"]}}]]}],{"children":["$La",{},null,false,null]},null,false,null]},null,false,null],"$Lb",false]],"m":"$undefined","G":["$c",["$Ld","$Le"]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"KYqiq5stbD-H4YcZ-6OuP"} +f:I[347257,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"ClientPageRoot"] +10:I[871135,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js","/litellm-asset-prefix/_next/static/chunks/0uuigwiz-in3~.js","/litellm-asset-prefix/_next/static/chunks/0-0c4mv4-mc9n.js","/litellm-asset-prefix/_next/static/chunks/0lg.6rbfsd-l9.js","/litellm-asset-prefix/_next/static/chunks/0p3v32gvsxp6h.js","/litellm-asset-prefix/_next/static/chunks/0x09ws363q4_0.js","/litellm-asset-prefix/_next/static/chunks/08o64zaid_juv.js","/litellm-asset-prefix/_next/static/chunks/043q3g5-5-aju.js","/litellm-asset-prefix/_next/static/chunks/0g9k1~ppf2hw3.js","/litellm-asset-prefix/_next/static/chunks/151r-5htw45m~.js","/litellm-asset-prefix/_next/static/chunks/0v85l0arelm41.js","/litellm-asset-prefix/_next/static/chunks/0zbgu4ogb6mba.js","/litellm-asset-prefix/_next/static/chunks/0ae3np_qb52e-.js","/litellm-asset-prefix/_next/static/chunks/0zam.8alu6_vj.js","/litellm-asset-prefix/_next/static/chunks/0uu6lckpr0s15.js","/litellm-asset-prefix/_next/static/chunks/0.bx44y-6~tug.js","/litellm-asset-prefix/_next/static/chunks/0l7em-5kjv49e.js","/litellm-asset-prefix/_next/static/chunks/0el08tticy_20.js","/litellm-asset-prefix/_next/static/chunks/0-s2am3eulbyd.js","/litellm-asset-prefix/_next/static/chunks/0sx3mu2_l9g_y.js","/litellm-asset-prefix/_next/static/chunks/0.w8~sa9q0n_s.js","/litellm-asset-prefix/_next/static/chunks/00q4mtjboprhm.js","/litellm-asset-prefix/_next/static/chunks/0zrbitbm~0koh.js","/litellm-asset-prefix/_next/static/chunks/0c4pfjjue0uc-.js","/litellm-asset-prefix/_next/static/chunks/0efmbzvj03niy.js","/litellm-asset-prefix/_next/static/chunks/055egae-ggkjh.js","/litellm-asset-prefix/_next/static/chunks/0hwip5a7qsmis.js","/litellm-asset-prefix/_next/static/chunks/0q6~n4y84cejn.js","/litellm-asset-prefix/_next/static/chunks/0mh1wnrvmv_y7.js"],"default"] +13:I[897367,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"OutletBoundary"] +14:"$Sreact.suspense" +16:I[897367,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"ViewportBoundary"] +18:I[897367,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"MetadataBoundary"] +a:["$","$1","c",{"children":[["$","$Lf",null,{"Component":"$10","serverProvidedParams":{"searchParams":{},"params":"$0:f:0:1:1:children:0:props:children:1:props:serverProvidedParams:params","promises":["$@11","$@12"]}}],[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/0ae3np_qb52e-.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/0zam.8alu6_vj.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/0uu6lckpr0s15.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/0.bx44y-6~tug.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/0l7em-5kjv49e.js","async":true,"nonce":"$undefined"}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/0el08tticy_20.js","async":true,"nonce":"$undefined"}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/0-s2am3eulbyd.js","async":true,"nonce":"$undefined"}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/0sx3mu2_l9g_y.js","async":true,"nonce":"$undefined"}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/0.w8~sa9q0n_s.js","async":true,"nonce":"$undefined"}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/00q4mtjboprhm.js","async":true,"nonce":"$undefined"}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/0zrbitbm~0koh.js","async":true,"nonce":"$undefined"}],["$","script","script-11",{"src":"/litellm-asset-prefix/_next/static/chunks/0c4pfjjue0uc-.js","async":true,"nonce":"$undefined"}],["$","script","script-12",{"src":"/litellm-asset-prefix/_next/static/chunks/0efmbzvj03niy.js","async":true,"nonce":"$undefined"}],["$","script","script-13",{"src":"/litellm-asset-prefix/_next/static/chunks/055egae-ggkjh.js","async":true,"nonce":"$undefined"}],["$","script","script-14",{"src":"/litellm-asset-prefix/_next/static/chunks/0hwip5a7qsmis.js","async":true,"nonce":"$undefined"}],["$","script","script-15",{"src":"/litellm-asset-prefix/_next/static/chunks/0q6~n4y84cejn.js","async":true,"nonce":"$undefined"}],["$","script","script-16",{"src":"/litellm-asset-prefix/_next/static/chunks/0mh1wnrvmv_y7.js","async":true,"nonce":"$undefined"}]],["$","$L13",null,{"children":["$","$14",null,{"name":"Next.MetadataOutlet","children":"$@15"}]}]]}] +b:["$","$1","h",{"children":[null,["$","$L16",null,{"children":"$L17"}],["$","div",null,{"hidden":true,"children":["$","$L18",null,{"children":["$","$14",null,{"name":"Next.Metadata","children":"$L19"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}] +d:["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/05qmwjqau64bz.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}] +e:["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/075sund.-mh4~.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}] +9:"$0:f:0:1:1:children:0:props:children:1:props:serverProvidedParams:params" +11:{} +12:"$0:f:0:1:1:children:0:props:children:1:props:serverProvidedParams:params" +17:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]] +1a:I[27201,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"IconMark"] +15:null +19:[["$","title","0",{"children":"LiteLLM Dashboard"}],["$","meta","1",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","2",{"rel":"icon","href":"/favicon.ico?favicon.0~dgapwhi~75y.ico","sizes":"48x48","type":"image/x-icon"}],["$","link","3",{"rel":"icon","href":"/get_favicon"}],["$","$L1a","4",{}]] diff --git a/litellm/proxy/_experimental/out/__next._head.txt b/litellm/proxy/_experimental/out/__next._head.txt new file mode 100644 index 00000000000..c896283665a --- /dev/null +++ b/litellm/proxy/_experimental/out/__next._head.txt @@ -0,0 +1,6 @@ +1:"$Sreact.fragment" +2:I[897367,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"ViewportBoundary"] +3:I[897367,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"MetadataBoundary"] +4:"$Sreact.suspense" +5:I[27201,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"IconMark"] +0:{"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.0~dgapwhi~75y.ico","sizes":"48x48","type":"image/x-icon"}],["$","link","3",{"rel":"icon","href":"/get_favicon"}],["$","$L5","4",{}]]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"KYqiq5stbD-H4YcZ-6OuP"} diff --git a/litellm/proxy/_experimental/out/__next._index.txt b/litellm/proxy/_experimental/out/__next._index.txt new file mode 100644 index 00000000000..e21c0fe74b8 --- /dev/null +++ b/litellm/proxy/_experimental/out/__next._index.txt @@ -0,0 +1,9 @@ +1:"$Sreact.fragment" +2:I[867271,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"default"] +3:I[71195,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"default"] +4:I[557951,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"AuthProvider"] +5:I[339756,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"default"] +6:I[837457,["/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js"],"default"] +:HL["/litellm-asset-prefix/_next/static/chunks/05qmwjqau64bz.css","style"] +:HL["/litellm-asset-prefix/_next/static/chunks/075sund.-mh4~.css","style"] +0:{"rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/05qmwjqau64bz.css","precedence":"next"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/075sund.-mh4~.css","precedence":"next"}],["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/08yy42xvwaak6.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/0e9hs7onyj28m.js","async":true}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/0pidya1qvuvx8.js","async":true}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"inter_5972bc34-module__OU16Qa__className","children":["$","$L2",null,{"children":["$","$L3",null,{"children":["$","$L4",null,{"children":["$","$L5",null,{"parallelRouterKey":"children","template":["$","$L6",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."}]}]]}]}]],[]]}]}]}]}]}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"KYqiq5stbD-H4YcZ-6OuP"} diff --git a/litellm/proxy/_experimental/out/__next._tree.txt b/litellm/proxy/_experimental/out/__next._tree.txt new file mode 100644 index 00000000000..843f0806214 --- /dev/null +++ b/litellm/proxy/_experimental/out/__next._tree.txt @@ -0,0 +1,4 @@ +:HL["/litellm-asset-prefix/_next/static/chunks/05qmwjqau64bz.css","style"] +:HL["/litellm-asset-prefix/_next/static/chunks/075sund.-mh4~.css","style"] +:HL["/litellm-asset-prefix/_next/static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2","font",{"crossOrigin":"","type":"font/woff2"}] +0:{"tree":{"name":"","param":null,"prefetchHints":16,"slots":{"children":{"name":"(dashboard)","param":null,"prefetchHints":0,"slots":{"children":{"name":"__PAGE__","param":null,"prefetchHints":0,"slots":null}}}}},"staleTime":300,"buildId":"KYqiq5stbD-H4YcZ-6OuP"} diff --git a/litellm/proxy/_experimental/out/_next/static/KYqiq5stbD-H4YcZ-6OuP/_buildManifest.js b/litellm/proxy/_experimental/out/_next/static/KYqiq5stbD-H4YcZ-6OuP/_buildManifest.js new file mode 100644 index 00000000000..d74e1661bbe --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/KYqiq5stbD-H4YcZ-6OuP/_buildManifest.js @@ -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() \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/KYqiq5stbD-H4YcZ-6OuP/_clientMiddlewareManifest.js b/litellm/proxy/_experimental/out/_next/static/KYqiq5stbD-H4YcZ-6OuP/_clientMiddlewareManifest.js new file mode 100644 index 00000000000..a8acaffa33a --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/KYqiq5stbD-H4YcZ-6OuP/_clientMiddlewareManifest.js @@ -0,0 +1 @@ +self.__MIDDLEWARE_MATCHERS = [];self.__MIDDLEWARE_MATCHERS_CB && self.__MIDDLEWARE_MATCHERS_CB() \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/KYqiq5stbD-H4YcZ-6OuP/_ssgManifest.js b/litellm/proxy/_experimental/out/_next/static/KYqiq5stbD-H4YcZ-6OuP/_ssgManifest.js new file mode 100644 index 00000000000..5b3ff592fd4 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/KYqiq5stbD-H4YcZ-6OuP/_ssgManifest.js @@ -0,0 +1 @@ +self.__SSG_MANIFEST=new Set([]);self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB() \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0-.xiiczht-vh.js b/litellm/proxy/_experimental/out/_next/static/chunks/0-.xiiczht-vh.js new file mode 100644 index 00000000000..9d2f975ff66 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/0-.xiiczht-vh.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,728889,e=>{"use strict";var r=e.i(290571),t=e.i(271645),a=e.i(829087),o=e.i(480731),l=e.i(444755),d=e.i(673706),s=e.i(95779);let n={xs:{paddingX:"px-1.5",paddingY:"py-1.5"},sm:{paddingX:"px-1.5",paddingY:"py-1.5"},md:{paddingX:"px-2",paddingY:"py-2"},lg:{paddingX:"px-2",paddingY:"py-2"},xl:{paddingX:"px-2.5",paddingY:"py-2.5"}},i={xs:{height:"h-3",width:"w-3"},sm:{height:"h-5",width:"w-5"},md:{height:"h-5",width:"w-5"},lg:{height:"h-7",width:"w-7"},xl:{height:"h-9",width:"w-9"}},m={simple:{rounded:"",border:"",ring:"",shadow:""},light:{rounded:"rounded-tremor-default",border:"",ring:"",shadow:""},shadow:{rounded:"rounded-tremor-default",border:"border",ring:"",shadow:"shadow-tremor-card dark:shadow-dark-tremor-card"},solid:{rounded:"rounded-tremor-default",border:"border-2",ring:"ring-1",shadow:""},outlined:{rounded:"rounded-tremor-default",border:"border",ring:"ring-2",shadow:""}},c=(0,d.makeClassName)("Icon"),g=t.default.forwardRef((e,g)=>{let{icon:u,variant:b="simple",tooltip:f,size:h=o.Sizes.SM,color:w,className:C}=e,k=(0,r.__rest)(e,["icon","variant","tooltip","size","color","className"]),p=((e,r)=>{switch(e){case"simple":return{textColor:r?(0,d.getColorClassNames)(r,s.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:"",borderColor:"",ringColor:""};case"light":return{textColor:r?(0,d.getColorClassNames)(r,s.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:r?(0,l.tremorTwMerge)((0,d.getColorClassNames)(r,s.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-brand-muted dark:bg-dark-tremor-brand-muted",borderColor:"",ringColor:""};case"shadow":return{textColor:r?(0,d.getColorClassNames)(r,s.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:r?(0,l.tremorTwMerge)((0,d.getColorClassNames)(r,s.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:"border-tremor-border dark:border-dark-tremor-border",ringColor:""};case"solid":return{textColor:r?(0,d.getColorClassNames)(r,s.colorPalette.text).textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:r?(0,l.tremorTwMerge)((0,d.getColorClassNames)(r,s.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-brand dark:bg-dark-tremor-brand",borderColor:"border-tremor-brand-inverted dark:border-dark-tremor-brand-inverted",ringColor:"ring-tremor-ring dark:ring-dark-tremor-ring"};case"outlined":return{textColor:r?(0,d.getColorClassNames)(r,s.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:r?(0,l.tremorTwMerge)((0,d.getColorClassNames)(r,s.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:r?(0,d.getColorClassNames)(r,s.colorPalette.ring).borderColor:"border-tremor-brand-subtle dark:border-dark-tremor-brand-subtle",ringColor:r?(0,l.tremorTwMerge)((0,d.getColorClassNames)(r,s.colorPalette.ring).ringColor,"ring-opacity-40"):"ring-tremor-brand-muted dark:ring-dark-tremor-brand-muted"}}})(b,w),{tooltipProps:x,getReferenceProps:N}=(0,a.useTooltip)();return t.default.createElement("span",Object.assign({ref:(0,d.mergeRefs)([g,x.refs.setReference]),className:(0,l.tremorTwMerge)(c("root"),"inline-flex shrink-0 items-center justify-center",p.bgColor,p.textColor,p.borderColor,p.ringColor,m[b].rounded,m[b].border,m[b].shadow,m[b].ring,n[h].paddingX,n[h].paddingY,C)},N,k),t.default.createElement(a.default,Object.assign({text:f},x)),t.default.createElement(u,{className:(0,l.tremorTwMerge)(c("icon"),"shrink-0",i[h].height,i[h].width)}))});g.displayName="Icon",e.s(["default",0,g],728889)},752978,e=>{"use strict";var r=e.i(728889);e.s(["Icon",()=>r.default])},871943,e=>{"use strict";var r=e.i(271645);let t=r.forwardRef(function(e,t){return r.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),r.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"}))});e.s(["ChevronDownIcon",0,t],871943)},360820,e=>{"use strict";var r=e.i(271645);let t=r.forwardRef(function(e,t){return r.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),r.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 15l7-7 7 7"}))});e.s(["ChevronUpIcon",0,t],360820)},269200,e=>{"use strict";var r=e.i(290571),t=e.i(271645),a=e.i(444755);let o=(0,e.i(673706).makeClassName)("Table"),l=t.default.forwardRef((e,l)=>{let{children:d,className:s}=e,n=(0,r.__rest)(e,["children","className"]);return t.default.createElement("div",{className:(0,a.tremorTwMerge)(o("root"),"overflow-auto",s)},t.default.createElement("table",Object.assign({ref:l,className:(0,a.tremorTwMerge)(o("table"),"w-full text-tremor-default","text-tremor-content","dark:text-dark-tremor-content")},n),d))});l.displayName="Table",e.s(["Table",0,l],269200)},427612,e=>{"use strict";var r=e.i(290571),t=e.i(271645),a=e.i(444755);let o=(0,e.i(673706).makeClassName)("TableHead"),l=t.default.forwardRef((e,l)=>{let{children:d,className:s}=e,n=(0,r.__rest)(e,["children","className"]);return t.default.createElement(t.default.Fragment,null,t.default.createElement("thead",Object.assign({ref:l,className:(0,a.tremorTwMerge)(o("root"),"text-left","text-tremor-content","dark:text-dark-tremor-content",s)},n),d))});l.displayName="TableHead",e.s(["TableHead",0,l],427612)},64848,e=>{"use strict";var r=e.i(290571),t=e.i(271645),a=e.i(444755);let o=(0,e.i(673706).makeClassName)("TableHeaderCell"),l=t.default.forwardRef((e,l)=>{let{children:d,className:s}=e,n=(0,r.__rest)(e,["children","className"]);return t.default.createElement(t.default.Fragment,null,t.default.createElement("th",Object.assign({ref:l,className:(0,a.tremorTwMerge)(o("root"),"whitespace-nowrap text-left font-semibold top-0 px-4 py-3.5","text-tremor-content-strong","dark:text-dark-tremor-content-strong",s)},n),d))});l.displayName="TableHeaderCell",e.s(["TableHeaderCell",0,l],64848)},942232,e=>{"use strict";var r=e.i(290571),t=e.i(271645),a=e.i(444755);let o=(0,e.i(673706).makeClassName)("TableBody"),l=t.default.forwardRef((e,l)=>{let{children:d,className:s}=e,n=(0,r.__rest)(e,["children","className"]);return t.default.createElement(t.default.Fragment,null,t.default.createElement("tbody",Object.assign({ref:l,className:(0,a.tremorTwMerge)(o("root"),"align-top divide-y","divide-tremor-border","dark:divide-dark-tremor-border",s)},n),d))});l.displayName="TableBody",e.s(["TableBody",0,l],942232)},496020,e=>{"use strict";var r=e.i(290571),t=e.i(271645),a=e.i(444755);let o=(0,e.i(673706).makeClassName)("TableRow"),l=t.default.forwardRef((e,l)=>{let{children:d,className:s}=e,n=(0,r.__rest)(e,["children","className"]);return t.default.createElement(t.default.Fragment,null,t.default.createElement("tr",Object.assign({ref:l,className:(0,a.tremorTwMerge)(o("row"),s)},n),d))});l.displayName="TableRow",e.s(["TableRow",0,l],496020)},977572,e=>{"use strict";var r=e.i(290571),t=e.i(271645),a=e.i(444755);let o=(0,e.i(673706).makeClassName)("TableCell"),l=t.default.forwardRef((e,l)=>{let{children:d,className:s}=e,n=(0,r.__rest)(e,["children","className"]);return t.default.createElement(t.default.Fragment,null,t.default.createElement("td",Object.assign({ref:l,className:(0,a.tremorTwMerge)(o("root"),"align-middle whitespace-nowrap text-left p-4",s)},n),d))});l.displayName="TableCell",e.s(["TableCell",0,l],977572)},68155,e=>{"use strict";var r=e.i(271645);let t=r.forwardRef(function(e,t){return r.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),r.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"}))});e.s(["TrashIcon",0,t],68155)},278587,e=>{"use strict";var r=e.i(271645);let t=r.forwardRef(function(e,t){return r.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),r.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"}))});e.s(["RefreshIcon",0,t],278587)},973095,e=>{"use strict";var r=e.i(843476),t=e.i(502501),a=e.i(135214),o=e.i(936578),l=e.i(271645);function d(){let{isLoading:e,isAuthorized:l}=(0,a.default)();return e||!l?(0,r.jsx)(o.default,{}):(0,r.jsx)(t.default,{})}e.s(["default",0,function(){return(0,r.jsx)(l.Suspense,{fallback:(0,r.jsx)(o.default,{}),children:(0,r.jsx)(d,{})})}])}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0-0c4mv4-mc9n.js b/litellm/proxy/_experimental/out/_next/static/chunks/0-0c4mv4-mc9n.js new file mode 100644 index 00000000000..8f16e50edb1 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/0-0c4mv4-mc9n.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,186312,e=>{"use strict";var t=new WeakMap,r=new WeakMap,n={},s=0,o=function(e){return e&&(e.host||o(e.parentNode))},i=function(e,i,a,l){var u=(Array.isArray(e)?e:[e]).map(function(e){if(i.contains(e))return e;var t=o(e);return t&&i.contains(t)?t:(console.error("aria-hidden",e,"in not contained inside",i,". Doing nothing"),null)}).filter(function(e){return!!e});n[a]||(n[a]=new WeakMap);var c=n[a],d=[],h=new Set,p=new Set(u),f=function(e){!e||h.has(e)||(h.add(e),f(e.parentNode))};u.forEach(f);var m=function(e){!e||p.has(e)||Array.prototype.forEach.call(e.children,function(e){if(h.has(e))m(e);else try{var n=e.getAttribute(l),s=null!==n&&"false"!==n,o=(t.get(e)||0)+1,i=(c.get(e)||0)+1;t.set(e,o),c.set(e,i),d.push(e),1===o&&s&&r.set(e,!0),1===i&&e.setAttribute(a,"true"),s||e.setAttribute(l,"true")}catch(t){console.error("aria-hidden: cannot operate on ",e,t)}})};return m(i),h.clear(),s++,function(){d.forEach(function(e){var n=t.get(e)-1,s=c.get(e)-1;t.set(e,n),c.set(e,s),n||(r.has(e)||e.removeAttribute(l),r.delete(e)),s||e.removeAttribute(a)}),--s||(t=new WeakMap,t=new WeakMap,r=new WeakMap,n={})}};e.s(["hideOthers",0,function(e,t,r){void 0===r&&(r="data-aria-hidden");var n=Array.from(Array.isArray(e)?e:[e]),s=t||("u"{t.exports=e.r(976562)},266027,869230,469637,e=>{"use strict";let t;var r=e.i(175555),n=e.i(273911),s=e.i(540143),o=e.i(286491),i=e.i(915823),a=e.i(793803),l=e.i(619273),u=e.i(180166),c=class extends i.Subscribable{constructor(e,t){super(),this.options=t,this.#e=e,this.#t=null,this.#r=(0,a.pendingThenable)(),this.bindMethods(),this.setOptions(t)}#e;#n=void 0;#s=void 0;#o=void 0;#i;#a;#r;#t;#l;#u;#c;#d;#h;#p;#f=new Set;bindMethods(){this.refetch=this.refetch.bind(this)}onSubscribe(){1===this.listeners.size&&(this.#n.addObserver(this),d(this.#n,this.options)?this.#m():this.updateResult(),this.#g())}onUnsubscribe(){this.hasListeners()||this.destroy()}shouldFetchOnReconnect(){return h(this.#n,this.options,this.options.refetchOnReconnect)}shouldFetchOnWindowFocus(){return h(this.#n,this.options,this.options.refetchOnWindowFocus)}destroy(){this.listeners=new Set,this.#y(),this.#b(),this.#n.removeObserver(this)}setOptions(e){let t=this.options,r=this.#n;if(this.options=this.#e.defaultQueryOptions(e),void 0!==this.options.enabled&&"boolean"!=typeof this.options.enabled&&"function"!=typeof this.options.enabled&&"boolean"!=typeof(0,l.resolveQueryBoolean)(this.options.enabled,this.#n))throw Error("Expected enabled to be a boolean or a callback that returns a boolean");this.#v(),this.#n.setOptions(this.options),t._defaulted&&!(0,l.shallowEqualObjects)(this.options,t)&&this.#e.getQueryCache().notify({type:"observerOptionsUpdated",query:this.#n,observer:this});let n=this.hasListeners();n&&p(this.#n,r,this.options,t)&&this.#m(),this.updateResult(),n&&(this.#n!==r||(0,l.resolveQueryBoolean)(this.options.enabled,this.#n)!==(0,l.resolveQueryBoolean)(t.enabled,this.#n)||(0,l.resolveStaleTime)(this.options.staleTime,this.#n)!==(0,l.resolveStaleTime)(t.staleTime,this.#n))&&this.#C();let s=this.#R();n&&(this.#n!==r||(0,l.resolveQueryBoolean)(this.options.enabled,this.#n)!==(0,l.resolveQueryBoolean)(t.enabled,this.#n)||s!==this.#p)&&this.#S(s)}getOptimisticResult(e){var t,r;let n=this.#e.getQueryCache().build(this.#e,e),s=this.createResult(n,e);return t=this,r=s,(0,l.shallowEqualObjects)(t.getCurrentResult(),r)||(this.#o=s,this.#a=this.options,this.#i=this.#n.state),s}getCurrentResult(){return this.#o}trackResult(e,t){return new Proxy(e,{get:(e,r)=>(this.trackProp(r),t?.(r),"promise"===r&&(this.trackProp("data"),this.options.experimental_prefetchInRender||"pending"!==this.#r.status||this.#r.reject(Error("experimental_prefetchInRender feature flag is not enabled"))),Reflect.get(e,r))})}trackProp(e){this.#f.add(e)}getCurrentQuery(){return this.#n}refetch({...e}={}){return this.fetch({...e})}fetchOptimistic(e){let t=this.#e.defaultQueryOptions(e),r=this.#e.getQueryCache().build(this.#e,t);return r.fetch().then(()=>this.createResult(r,t))}fetch(e){return this.#m({...e,cancelRefetch:e.cancelRefetch??!0}).then(()=>(this.updateResult(),this.#o))}#m(e){this.#v();let t=this.#n.fetch(this.options,e);return e?.throwOnError||(t=t.catch(l.noop)),t}#C(){this.#y();let e=(0,l.resolveStaleTime)(this.options.staleTime,this.#n);if(n.environmentManager.isServer()||this.#o.isStale||!(0,l.isValidTimeout)(e))return;let t=(0,l.timeUntilStale)(this.#o.dataUpdatedAt,e);this.#d=u.timeoutManager.setTimeout(()=>{this.#o.isStale||this.updateResult()},t+1)}#R(){return("function"==typeof this.options.refetchInterval?this.options.refetchInterval(this.#n):this.options.refetchInterval)??!1}#S(e){this.#b(),this.#p=e,!n.environmentManager.isServer()&&!1!==(0,l.resolveQueryBoolean)(this.options.enabled,this.#n)&&(0,l.isValidTimeout)(this.#p)&&0!==this.#p&&(this.#h=u.timeoutManager.setInterval(()=>{(this.options.refetchIntervalInBackground||r.focusManager.isFocused())&&this.#m()},this.#p))}#g(){this.#C(),this.#S(this.#R())}#y(){void 0!==this.#d&&(u.timeoutManager.clearTimeout(this.#d),this.#d=void 0)}#b(){void 0!==this.#h&&(u.timeoutManager.clearInterval(this.#h),this.#h=void 0)}createResult(e,t){let r,n=this.#n,s=this.options,i=this.#o,u=this.#i,c=this.#a,h=e!==n?e.state:this.#s,{state:m}=e,g={...m},y=!1;if(t._optimisticResults){let r=this.hasListeners(),i=!r&&d(e,t),a=r&&p(e,n,t,s);(i||a)&&(g={...g,...(0,o.fetchState)(m.data,e.options)}),"isRestoring"===t._optimisticResults&&(g.fetchStatus="idle")}let{error:b,errorUpdatedAt:v,status:C}=g;r=g.data;let R=!1;if(void 0!==t.placeholderData&&void 0===r&&"pending"===C){let e;i?.isPlaceholderData&&t.placeholderData===c?.placeholderData?(e=i.data,R=!0):e="function"==typeof t.placeholderData?t.placeholderData(this.#c?.state.data,this.#c):t.placeholderData,void 0!==e&&(C="success",r=(0,l.replaceData)(i?.data,e,t),y=!0)}if(t.select&&void 0!==r&&!R)if(i&&r===u?.data&&t.select===this.#l)r=this.#u;else try{this.#l=t.select,r=t.select(r),r=(0,l.replaceData)(i?.data,r,t),this.#u=r,this.#t=null}catch(e){this.#t=e}this.#t&&(b=this.#t,r=this.#u,v=Date.now(),C="error");let S="fetching"===g.fetchStatus,O="pending"===C,w="error"===C,k=O&&S,I=void 0!==r,x={status:C,fetchStatus:g.fetchStatus,isPending:O,isSuccess:"success"===C,isError:w,isInitialLoading:k,isLoading:k,data:r,dataUpdatedAt:g.dataUpdatedAt,error:b,errorUpdatedAt:v,failureCount:g.fetchFailureCount,failureReason:g.fetchFailureReason,errorUpdateCount:g.errorUpdateCount,isFetched:e.isFetched(),isFetchedAfterMount:g.dataUpdateCount>h.dataUpdateCount||g.errorUpdateCount>h.errorUpdateCount,isFetching:S,isRefetching:S&&!O,isLoadingError:w&&!I,isPaused:"paused"===g.fetchStatus,isPlaceholderData:y,isRefetchError:w&&I,isStale:f(e,t),refetch:this.refetch,promise:this.#r,isEnabled:!1!==(0,l.resolveQueryBoolean)(t.enabled,e)};if(this.options.experimental_prefetchInRender){let t=void 0!==x.data,r="error"===x.status&&!t,s=e=>{r?e.reject(x.error):t&&e.resolve(x.data)},o=()=>{s(this.#r=x.promise=(0,a.pendingThenable)())},i=this.#r;switch(i.status){case"pending":e.queryHash===n.queryHash&&s(i);break;case"fulfilled":(r||x.data!==i.value)&&o();break;case"rejected":r&&x.error===i.reason||o()}}return x}updateResult(){let e=this.#o,t=this.createResult(this.#n,this.options);if(this.#i=this.#n.state,this.#a=this.options,void 0!==this.#i.data&&(this.#c=this.#n),(0,l.shallowEqualObjects)(t,e))return;this.#o=t;let r=()=>{if(!e)return!0;let{notifyOnChangeProps:t}=this.options,r="function"==typeof t?t():t;if("all"===r||!r&&!this.#f.size)return!0;let n=new Set(r??this.#f);return this.options.throwOnError&&n.add("error"),Object.keys(this.#o).some(t=>this.#o[t]!==e[t]&&n.has(t))};this.#O({listeners:r()})}#v(){let e=this.#e.getQueryCache().build(this.#e,this.options);if(e===this.#n)return;let t=this.#n;this.#n=e,this.#s=e.state,this.hasListeners()&&(t?.removeObserver(this),e.addObserver(this))}onQueryUpdate(){this.updateResult(),this.hasListeners()&&this.#g()}#O(e){s.notifyManager.batch(()=>{e.listeners&&this.listeners.forEach(e=>{e(this.#o)}),this.#e.getQueryCache().notify({query:this.#n,type:"observerResultsUpdated"})})}};function d(e,t){return!1!==(0,l.resolveQueryBoolean)(t.enabled,e)&&void 0===e.state.data&&("error"!==e.state.status||!1!==(0,l.resolveQueryBoolean)(t.retryOnMount,e))||void 0!==e.state.data&&h(e,t,t.refetchOnMount)}function h(e,t,r){if(!1!==(0,l.resolveQueryBoolean)(t.enabled,e)&&"static"!==(0,l.resolveStaleTime)(t.staleTime,e)){let n="function"==typeof r?r(e):r;return"always"===n||!1!==n&&f(e,t)}return!1}function p(e,t,r,n){return(e!==t||!1===(0,l.resolveQueryBoolean)(n.enabled,e))&&(!r.suspense||"error"!==e.state.status)&&f(e,r)}function f(e,t){return!1!==(0,l.resolveQueryBoolean)(t.enabled,e)&&e.isStaleByTime((0,l.resolveStaleTime)(t.staleTime,e))}e.s(["QueryObserver",0,c],869230),e.i(247167);var m=e.i(271645),g=e.i(912598);e.i(843476);var y=m.createContext((t=!1,{clearReset:()=>{t=!1},reset:()=>{t=!0},isReset:()=>t})),b=m.createContext(!1);b.Provider;var v=(e,t,r)=>t.fetchOptimistic(e).catch(()=>{r.clearReset()});function C(e,t,r){let o,i=m.useContext(b),a=m.useContext(y),u=(0,g.useQueryClient)(r),c=u.defaultQueryOptions(e);u.getDefaultOptions().queries?._experimental_beforeQuery?.(c);let d=u.getQueryCache().get(c.queryHash);if(c._optimisticResults=i?"isRestoring":"optimistic",c.suspense){let e=e=>"static"===e?e:Math.max(e??1e3,1e3),t=c.staleTime;c.staleTime="function"==typeof t?(...r)=>e(t(...r)):e(t),"number"==typeof c.gcTime&&(c.gcTime=Math.max(c.gcTime,1e3))}o=d?.state.error&&"function"==typeof c.throwOnError?(0,l.shouldThrowError)(c.throwOnError,[d.state.error,d]):c.throwOnError,(c.suspense||c.experimental_prefetchInRender||o)&&!a.isReset()&&(c.retryOnMount=!1),m.useEffect(()=>{a.clearReset()},[a]);let h=!u.getQueryCache().get(c.queryHash),[p]=m.useState(()=>new t(u,c)),f=p.getOptimisticResult(c),C=!i&&!1!==e.subscribed;if(m.useSyncExternalStore(m.useCallback(e=>{let t=C?p.subscribe(s.notifyManager.batchCalls(e)):l.noop;return p.updateResult(),t},[p,C]),()=>p.getCurrentResult(),()=>p.getCurrentResult()),m.useEffect(()=>{p.setOptions(c)},[c,p]),c?.suspense&&f.isPending)throw v(c,p,a);if((({result:e,errorResetBoundary:t,throwOnError:r,query:n,suspense:s})=>e.isError&&!t.isReset()&&!e.isFetching&&n&&(s&&void 0===e.data||(0,l.shouldThrowError)(r,[e.error,n])))({result:f,errorResetBoundary:a,throwOnError:c.throwOnError,query:d,suspense:c.suspense}))throw f.error;if(u.getDefaultOptions().queries?._experimental_afterQuery?.(c,f),c.experimental_prefetchInRender&&!n.environmentManager.isServer()&&f.isLoading&&f.isFetching&&!i){let e=h?v(c,p,a):d?.promise;e?.catch(l.noop).finally(()=>{p.updateResult()})}return c.notifyOnChangeProps?f:p.trackResult(f)}e.s(["useBaseQuery",0,C],469637),e.s(["useQuery",0,function(e,t){return C(e,c,t)}],266027)},612256,243652,e=>{"use strict";var t=e.i(602869),r=e.i(266027);function n(e){let t=[e];return{all:t,lists:()=>[...t,"list"],list:e=>[...t,"list",{params:e}],details:()=>[...t,"detail"],detail:e=>[...t,"detail",e]}}e.s(["createQueryKeys",0,n],243652);let s=n("uiConfig");e.s(["useUIConfig",0,()=>(0,r.useQuery)({queryKey:s.list({}),queryFn:async()=>await (0,t.getUiConfig)(),staleTime:864e5,gcTime:864e5})],612256)},321836,e=>{"use strict";let t="litellm_return_url",r="redirect_to";function n(){return window.location.href}function s(){if("u"typeof document&&(document.cookie=`${t}=; path=/; max-age=0`)}catch(e){console.error("Failed to clear return URL cookie:",e)}}function i(){return new URLSearchParams(window.location.search).get(r)}function a(){let e=window.location.hostname;return"localhost"===e||"127.0.0.1"===e||"::1"===e||e.startsWith("127.")||e.endsWith(".local")}function l(e){if(!e)return!1;if(e.startsWith("/")&&!e.startsWith("//"))return!0;try{let t=new URL(e),r=window.location.hostname;if(t.hostname!==r)return!1;if(a())return!0;return t.origin===window.location.origin}catch{return!1}}e.s(["buildLoginUrlWithReturn",0,function(e,t){let s=t||n();if(!s||s.includes("/login"))return e;let o=e.includes("?")?"&":"?";return`${e}${o}${r}=${encodeURIComponent(s)}`},"clearStoredReturnUrl",0,o,"consumeReturnUrl",0,function(){let e=i();if(e){if(l(e))return o(),e;a()&&console.warn("[returnUrlUtils] Invalid return URL in params rejected:",e)}let t=s();if(t){if(l(t))return o(),t;a()&&console.warn("[returnUrlUtils] Invalid return URL in cookie rejected:",t)}return null},"getReturnUrl",0,function(){let e=i();if(e)return e;let t=s();return t||null},"isValidReturnUrl",0,l,"normalizeUrlForCompare",0,function(e){try{let t=new URL(e,window.location.origin),r=t.pathname;r.length>1&&r.endsWith("/")&&(r=r.slice(0,-1));let n=new URLSearchParams(t.search),s=new URLSearchParams;Array.from(n.entries()).sort(([e],[t])=>e.localeCompare(t)).forEach(([e,t])=>{s.append(e,t)});let o=s.toString(),i=t.hash||"";return`${t.origin}${r}${o?`?${o}`:""}${i}`}catch{return e}},"storeReturnUrl",0,function(){let e=n();e&&function(e,t,r=300){if("u"{"use strict";var t=e.i(602869),r=e.i(268004),n=e.i(161281),s=e.i(321836),o=e.i(618566),i=e.i(271645),a=e.i(708347),l=e.i(612256);e.s(["default",0,()=>{let e=(0,o.useRouter)(),{data:u,isLoading:c}=(0,l.useUIConfig)(),d="u">typeof document?(0,r.getCookie)("token"):null,h=(0,i.useMemo)(()=>(0,n.decodeToken)(d),[d]),p=(0,i.useMemo)(()=>(0,n.checkTokenValidity)(d),[d])&&!u?.admin_ui_disabled,f=(0,i.useCallback)(()=>{(0,s.storeReturnUrl)();let r=`${(0,t.getProxyBaseUrl)()}/ui/login`,n=(0,s.buildLoginUrlWithReturn)(r);e.replace(n)},[e]);return(0,i.useEffect)(()=>{!c&&(p||(d&&(0,r.clearTokenCookies)(),f()))},[c,p,d,f]),{isLoading:c,isAuthorized:p,token:p?d:null,accessToken:h?.key??null,userId:h?.user_id??null,userEmail:h?.user_email??null,userRole:(0,a.formatUserRole)(h?.user_role),premiumUser:h?.premium_user??null,disabledPersonalKeyCreation:h?.disabled_non_admin_personal_key_creation??null,showSSOBanner:h?.login_method==="username_password"}}])},95779,e=>{"use strict";var t=e.i(480731);let r=[t.BaseColors.Blue,t.BaseColors.Cyan,t.BaseColors.Sky,t.BaseColors.Indigo,t.BaseColors.Violet,t.BaseColors.Purple,t.BaseColors.Fuchsia,t.BaseColors.Slate,t.BaseColors.Gray,t.BaseColors.Zinc,t.BaseColors.Neutral,t.BaseColors.Stone,t.BaseColors.Red,t.BaseColors.Orange,t.BaseColors.Amber,t.BaseColors.Yellow,t.BaseColors.Lime,t.BaseColors.Green,t.BaseColors.Emerald,t.BaseColors.Teal,t.BaseColors.Pink,t.BaseColors.Rose];e.s(["colorPalette",0,{canvasBackground:50,lightBackground:100,background:500,darkBackground:600,darkestBackground:800,lightBorder:200,border:500,darkBorder:700,lightRing:200,ring:300,iconRing:500,lightText:400,text:500,iconText:600,darkText:700,darkestText:900,icon:500},"themeColorRange",0,r])},563113,887719,e=>{"use strict";var t=e.i(271645),r=e.i(864517),n=e.i(244009),s=e.i(408850),o=e.i(87414);let i=function(...e){let t={};return e.forEach(e=>{e&&Object.keys(e).forEach(r=>{void 0!==e[r]&&(t[r]=e[r])})}),t};function a(e){let{closable:r,closeIcon:n}=e||{};return t.default.useMemo(()=>{if(!r&&(!1===r||!1===n||null===n))return!1;if(void 0===r&&void 0===n)return null;let e={closeIcon:"boolean"!=typeof n&&null!==n?n:void 0};return r&&"object"==typeof r&&(e=Object.assign(Object.assign({},e),r)),e},[r,n])}e.s(["default",0,i],887719);let l={};e.s(["pickClosable",0,function(e){if(!e)return;let{closable:t,closeIcon:r}=e;return{closable:t,closeIcon:r}},"useClosable",0,(e,u,c=l)=>{let d=a(e),h=a(u),[p]=(0,s.useLocale)("global",o.default.global),f="boolean"!=typeof d&&!!(null==d?void 0:d.disabled),m=t.default.useMemo(()=>Object.assign({closeIcon:t.default.createElement(r.default,null)},c),[c]),g=t.default.useMemo(()=>!1!==d&&(d?i(m,h,d):!1!==h&&(h?i(m,h):!!m.closable&&m)),[d,h,m]);return t.default.useMemo(()=>{var e,r;if(!1===g)return[!1,null,f,{}];let{closeIconRender:s}=m,{closeIcon:o}=g,i=o,a=(0,n.default)(g,!0);return null!=i&&(s&&(i=s(o)),i=t.default.isValidElement(i)?t.default.cloneElement(i,Object.assign(Object.assign(Object.assign({},i.props),{"aria-label":null!=(r=null==(e=i.props)?void 0:e["aria-label"])?r:p.close}),a)):t.default.createElement("span",Object.assign({"aria-label":p.close},a),i)),[!0,i,f,a]},[f,p.close,g,m])}],563113)},801312,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"}}]},name:"left",theme:"outlined"};var s=e.i(9583),o=r.forwardRef(function(e,o){return r.createElement(s.default,(0,t.default)({},e,{ref:o,icon:n}))});e.s(["default",0,o],801312)},38243,908286,e=>{"use strict";e.i(247167);var t=e.i(271645),r=e.i(343794),n=e.i(876556);function s(e){return["small","middle","large"].includes(e)}function o(e){return!!e&&"number"==typeof e&&!Number.isNaN(e)}e.s(["isPresetSize",0,s,"isValidGapNumber",0,o],908286);var i=e.i(242064),a=e.i(249616),l=e.i(372409),u=e.i(246422);let c=(0,u.genStyleHooks)(["Space","Addon"],e=>[(e=>{let{componentCls:t,borderRadius:r,paddingSM:n,colorBorder:s,paddingXS:o,fontSizeLG:i,fontSizeSM:a,borderRadiusLG:u,borderRadiusSM:c,colorBgContainerDisabled:d,lineWidth:h}=e;return{[t]:[{display:"inline-flex",alignItems:"center",gap:0,paddingInline:n,margin:0,background:d,borderWidth:h,borderStyle:"solid",borderColor:s,borderRadius:r,"&-large":{fontSize:i,borderRadius:u},"&-small":{paddingInline:o,borderRadius:c,fontSize:a},"&-compact-last-item":{borderEndStartRadius:0,borderStartStartRadius:0},"&-compact-first-item":{borderEndEndRadius:0,borderStartEndRadius:0},"&-compact-item:not(:first-child):not(:last-child)":{borderRadius:0},"&-compact-item:not(:last-child)":{borderInlineEndWidth:0}},(0,l.genCompactItemStyle)(e,{focus:!1})]}})(e)]);var d=function(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&0>t.indexOf(n)&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var s=0,n=Object.getOwnPropertySymbols(e);st.indexOf(n[s])&&Object.prototype.propertyIsEnumerable.call(e,n[s])&&(r[n[s]]=e[n[s]]);return r};let h=t.default.forwardRef((e,n)=>{let{className:s,children:o,style:l,prefixCls:u}=e,h=d(e,["className","children","style","prefixCls"]),{getPrefixCls:p,direction:f}=t.default.useContext(i.ConfigContext),m=p("space-addon",u),[g,y,b]=c(m),{compactItemClassnames:v,compactSize:C}=(0,a.useCompactItemContext)(m,f),R=(0,r.default)(m,y,v,b,{[`${m}-${C}`]:C},s);return g(t.default.createElement("div",Object.assign({ref:n,className:R,style:l},h),o))}),p=t.default.createContext({latestIndex:0}),f=p.Provider,m=({className:e,index:r,children:n,split:s,style:o})=>{let{latestIndex:i}=t.useContext(p);return null==n?null:t.createElement(t.Fragment,null,t.createElement("div",{className:e,style:o},n),r{let t=(0,g.mergeToken)(e,{spaceGapSmallSize:e.paddingXS,spaceGapMiddleSize:e.padding,spaceGapLargeSize:e.paddingLG});return[(e=>{let{componentCls:t,antCls:r}=e;return{[t]:{display:"inline-flex","&-rtl":{direction:"rtl"},"&-vertical":{flexDirection:"column"},"&-align":{flexDirection:"column","&-center":{alignItems:"center"},"&-start":{alignItems:"flex-start"},"&-end":{alignItems:"flex-end"},"&-baseline":{alignItems:"baseline"}},[`${t}-item:empty`]:{display:"none"},[`${t}-item > ${r}-badge-not-a-wrapper:only-child`]:{display:"block"}}}})(t),(e=>{let{componentCls:t}=e;return{[t]:{"&-gap-row-small":{rowGap:e.spaceGapSmallSize},"&-gap-row-middle":{rowGap:e.spaceGapMiddleSize},"&-gap-row-large":{rowGap:e.spaceGapLargeSize},"&-gap-col-small":{columnGap:e.spaceGapSmallSize},"&-gap-col-middle":{columnGap:e.spaceGapMiddleSize},"&-gap-col-large":{columnGap:e.spaceGapLargeSize}}}})(t)]},()=>({}),{resetStyle:!1});var b=function(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&0>t.indexOf(n)&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var s=0,n=Object.getOwnPropertySymbols(e);st.indexOf(n[s])&&Object.prototype.propertyIsEnumerable.call(e,n[s])&&(r[n[s]]=e[n[s]]);return r};let v=t.forwardRef((e,a)=>{var l;let{getPrefixCls:u,direction:c,size:d,className:h,style:p,classNames:g,styles:v}=(0,i.useComponentConfig)("space"),{size:C=null!=d?d:"small",align:R,className:S,rootClassName:O,children:w,direction:k="horizontal",prefixCls:I,split:x,style:E,wrap:Q=!1,classNames:T,styles:$}=e,B=b(e,["size","align","className","rootClassName","children","direction","prefixCls","split","style","wrap","classNames","styles"]),[j,U]=Array.isArray(C)?C:[C,C],P=s(U),M=s(j),L=o(U),A=o(j),N=(0,n.default)(w,{keepEmpty:!0}),F=void 0===R&&"horizontal"===k?"center":R,_=u("space",I),[z,W,D]=y(_),G=(0,r.default)(_,h,W,`${_}-${k}`,{[`${_}-rtl`]:"rtl"===c,[`${_}-align-${F}`]:F,[`${_}-gap-row-${U}`]:P,[`${_}-gap-col-${j}`]:M},S,O,D),q=(0,r.default)(`${_}-item`,null!=(l=null==T?void 0:T.item)?l:g.item),H=Object.assign(Object.assign({},v.item),null==$?void 0:$.item),V=N.map((e,r)=>{let n=(null==e?void 0:e.key)||`${q}-${r}`;return t.createElement(m,{className:q,key:n,index:r,split:x,style:H},e)}),K=t.useMemo(()=>({latestIndex:N.reduce((e,t,r)=>null!=t?r:e,0)}),[N]);if(0===N.length)return null;let Z={};return Q&&(Z.flexWrap="wrap"),!M&&A&&(Z.columnGap=j),!P&&L&&(Z.rowGap=U),z(t.createElement("div",Object.assign({ref:a,className:G,style:Object.assign(Object.assign(Object.assign({},Z),p),E)},B),t.createElement(f,{value:K},V)))});v.Compact=a.default,v.Addon=h,e.s(["default",0,v],38243)},475254,e=>{"use strict";var t=e.i(271645);let r=e=>{let t=e.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,t,r)=>r?r.toUpperCase():t.toLowerCase());return t.charAt(0).toUpperCase()+t.slice(1)},n=(...e)=>e.filter((e,t,r)=>!!e&&""!==e.trim()&&r.indexOf(e)===t).join(" ").trim();var s={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};let o=(0,t.forwardRef)(({color:e="currentColor",size:r=24,strokeWidth:o=2,absoluteStrokeWidth:i,className:a="",children:l,iconNode:u,...c},d)=>(0,t.createElement)("svg",{ref:d,...s,width:r,height:r,stroke:e,strokeWidth:i?24*Number(o)/Number(r):o,className:n("lucide",a),...!l&&!(e=>{for(let t in e)if(t.startsWith("aria-")||"role"===t||"title"===t)return!0})(c)&&{"aria-hidden":"true"},...c},[...u.map(([e,r])=>(0,t.createElement)(e,r)),...Array.isArray(l)?l:[l]]));e.s(["default",0,(e,s)=>{let i=(0,t.forwardRef)(({className:i,...a},l)=>(0,t.createElement)(o,{ref:l,iconNode:s,className:n(`lucide-${r(e).replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()}`,`lucide-${e}`,i),...a}));return i.displayName=r(e),i}],475254)},262218,e=>{"use strict";e.i(247167);var t=e.i(271645),r=e.i(343794),n=e.i(529681),s=e.i(702779),o=e.i(563113),i=e.i(763731),a=e.i(121872),l=e.i(242064);e.i(296059);var u=e.i(915654),c=e.i(135551),d=e.i(183293),h=e.i(246422),p=e.i(838378);let f=e=>{let{lineWidth:t,fontSizeIcon:r,calc:n}=e,s=e.fontSizeSM;return(0,p.mergeToken)(e,{tagFontSize:s,tagLineHeight:(0,u.unit)(n(e.lineHeightSM).mul(s).equal()),tagIconSize:n(r).sub(n(t).mul(2)).equal(),tagPaddingHorizontal:8,tagBorderlessBg:e.defaultBg})},m=e=>({defaultBg:new c.FastColor(e.colorFillQuaternary).onBackground(e.colorBgContainer).toHexString(),defaultColor:e.colorText}),g=(0,h.genStyleHooks)("Tag",e=>(e=>{let{paddingXXS:t,lineWidth:r,tagPaddingHorizontal:n,componentCls:s,calc:o}=e,i=o(n).sub(r).equal(),a=o(t).sub(r).equal();return{[s]:Object.assign(Object.assign({},(0,d.resetComponent)(e)),{display:"inline-block",height:"auto",marginInlineEnd:e.marginXS,paddingInline:i,fontSize:e.tagFontSize,lineHeight:e.tagLineHeight,whiteSpace:"nowrap",background:e.defaultBg,border:`${(0,u.unit)(e.lineWidth)} ${e.lineType} ${e.colorBorder}`,borderRadius:e.borderRadiusSM,opacity:1,transition:`all ${e.motionDurationMid}`,textAlign:"start",position:"relative",[`&${s}-rtl`]:{direction:"rtl"},"&, a, a:hover":{color:e.defaultColor},[`${s}-close-icon`]:{marginInlineStart:a,fontSize:e.tagIconSize,color:e.colorIcon,cursor:"pointer",transition:`all ${e.motionDurationMid}`,"&:hover":{color:e.colorTextHeading}},[`&${s}-has-color`]:{borderColor:"transparent",[`&, a, a:hover, ${e.iconCls}-close, ${e.iconCls}-close:hover`]:{color:e.colorTextLightSolid}},"&-checkable":{backgroundColor:"transparent",borderColor:"transparent",cursor:"pointer",[`&:not(${s}-checkable-checked):hover`]:{color:e.colorPrimary,backgroundColor:e.colorFillSecondary},"&:active, &-checked":{color:e.colorTextLightSolid},"&-checked":{backgroundColor:e.colorPrimary,"&:hover":{backgroundColor:e.colorPrimaryHover}},"&:active":{backgroundColor:e.colorPrimaryActive}},"&-hidden":{display:"none"},[`> ${e.iconCls} + span, > span + ${e.iconCls}`]:{marginInlineStart:i}}),[`${s}-borderless`]:{borderColor:"transparent",background:e.tagBorderlessBg}}})(f(e)),m);var y=function(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&0>t.indexOf(n)&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var s=0,n=Object.getOwnPropertySymbols(e);st.indexOf(n[s])&&Object.prototype.propertyIsEnumerable.call(e,n[s])&&(r[n[s]]=e[n[s]]);return r};let b=t.forwardRef((e,n)=>{let{prefixCls:s,style:o,className:i,checked:a,children:u,icon:c,onChange:d,onClick:h}=e,p=y(e,["prefixCls","style","className","checked","children","icon","onChange","onClick"]),{getPrefixCls:f,tag:m}=t.useContext(l.ConfigContext),b=f("tag",s),[v,C,R]=g(b),S=(0,r.default)(b,`${b}-checkable`,{[`${b}-checkable-checked`]:a},null==m?void 0:m.className,i,C,R);return v(t.createElement("span",Object.assign({},p,{ref:n,style:Object.assign(Object.assign({},o),null==m?void 0:m.style),className:S,onClick:e=>{null==d||d(!a),null==h||h(e)}}),c,t.createElement("span",null,u)))});var v=e.i(403541);let C=(0,h.genSubStyleComponent)(["Tag","preset"],e=>{let t;return t=f(e),(0,v.genPresetColor)(t,(e,{textColor:r,lightBorderColor:n,lightColor:s,darkColor:o})=>({[`${t.componentCls}${t.componentCls}-${e}`]:{color:r,background:s,borderColor:n,"&-inverse":{color:t.colorTextLightSolid,background:o,borderColor:o},[`&${t.componentCls}-borderless`]:{borderColor:"transparent"}}}))},m),R=(e,t,r)=>{let n="string"!=typeof r?r:r.charAt(0).toUpperCase()+r.slice(1);return{[`${e.componentCls}${e.componentCls}-${t}`]:{color:e[`color${r}`],background:e[`color${n}Bg`],borderColor:e[`color${n}Border`],[`&${e.componentCls}-borderless`]:{borderColor:"transparent"}}}},S=(0,h.genSubStyleComponent)(["Tag","status"],e=>{let t=f(e);return[R(t,"success","Success"),R(t,"processing","Info"),R(t,"error","Error"),R(t,"warning","Warning")]},m);var O=function(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&0>t.indexOf(n)&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var s=0,n=Object.getOwnPropertySymbols(e);st.indexOf(n[s])&&Object.prototype.propertyIsEnumerable.call(e,n[s])&&(r[n[s]]=e[n[s]]);return r};let w=t.forwardRef((e,u)=>{let{prefixCls:c,className:d,rootClassName:h,style:p,children:f,icon:m,color:y,onClose:b,bordered:v=!0,visible:R}=e,w=O(e,["prefixCls","className","rootClassName","style","children","icon","color","onClose","bordered","visible"]),{getPrefixCls:k,direction:I,tag:x}=t.useContext(l.ConfigContext),[E,Q]=t.useState(!0),T=(0,n.default)(w,["closeIcon","closable"]);t.useEffect(()=>{void 0!==R&&Q(R)},[R]);let $=(0,s.isPresetColor)(y),B=(0,s.isPresetStatusColor)(y),j=$||B,U=Object.assign(Object.assign({backgroundColor:y&&!j?y:void 0},null==x?void 0:x.style),p),P=k("tag",c),[M,L,A]=g(P),N=(0,r.default)(P,null==x?void 0:x.className,{[`${P}-${y}`]:j,[`${P}-has-color`]:y&&!j,[`${P}-hidden`]:!E,[`${P}-rtl`]:"rtl"===I,[`${P}-borderless`]:!v},d,h,L,A),F=e=>{e.stopPropagation(),null==b||b(e),e.defaultPrevented||Q(!1)},[,_]=(0,o.useClosable)((0,o.pickClosable)(e),(0,o.pickClosable)(x),{closable:!1,closeIconRender:e=>{let n=t.createElement("span",{className:`${P}-close-icon`,onClick:F},e);return(0,i.replaceElement)(e,n,e=>({onClick:t=>{var r;null==(r=null==e?void 0:e.onClick)||r.call(e,t),F(t)},className:(0,r.default)(null==e?void 0:e.className,`${P}-close-icon`)}))}}),z="function"==typeof w.onClick||f&&"a"===f.type,W=m||null,D=W?t.createElement(t.Fragment,null,W,f&&t.createElement("span",null,f)):f,G=t.createElement("span",Object.assign({},T,{ref:u,className:N,style:U}),D,_,$&&t.createElement(C,{key:"preset",prefixCls:P}),B&&t.createElement(S,{key:"status",prefixCls:P}));return M(z?t.createElement(a.default,{component:"Tag"},G):G)});w.CheckableTag=b,e.s(["Tag",0,w],262218)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0-s2am3eulbyd.js b/litellm/proxy/_experimental/out/_next/static/chunks/0-s2am3eulbyd.js new file mode 100644 index 00000000000..d5b9e0099b9 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/0-s2am3eulbyd.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,250980,e=>{"use strict";var t=e.i(271645);let l=t.forwardRef(function(e,l){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:l},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z"}))});e.s(["PlusCircleIcon",0,l],250980)},309426,e=>{"use strict";var t=e.i(290571),l=e.i(444755),s=e.i(673706),r=e.i(271645),a=e.i(46757);let n=(0,s.makeClassName)("Col"),i=r.default.forwardRef((e,s)=>{let i,o,c,d,{numColSpan:u=1,numColSpanSm:m,numColSpanMd:g,numColSpanLg:p,children:h,className:x}=e,f=(0,t.__rest)(e,["numColSpan","numColSpanSm","numColSpanMd","numColSpanLg","children","className"]),y=(e,t)=>e&&Object.keys(t).includes(String(e))?t[e]:"";return r.default.createElement("div",Object.assign({ref:s,className:(0,l.tremorTwMerge)(n("root"),(i=y(u,a.colSpan),o=y(m,a.colSpanSm),c=y(g,a.colSpanMd),d=y(p,a.colSpanLg),(0,l.tremorTwMerge)(i,o,c,d)),x)},f),h)});i.displayName="Col",e.s(["Col",0,i],309426)},435451,e=>{"use strict";var t=e.i(843476),l=e.i(290571),s=e.i(271645);let r=e=>{var t=(0,l.__rest)(e,[]);return s.default.createElement("svg",Object.assign({},t,{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:"2.5"}),s.default.createElement("path",{d:"M12 4v16m8-8H4"}))},a=e=>{var t=(0,l.__rest)(e,[]);return s.default.createElement("svg",Object.assign({},t,{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:"2.5"}),s.default.createElement("path",{d:"M20 12H4"}))};var n=e.i(444755),i=e.i(673706),o=e.i(677955);let c="flex mx-auto text-tremor-content-subtle dark:text-dark-tremor-content-subtle",d="cursor-pointer hover:text-tremor-content dark:hover:text-dark-tremor-content",u=s.default.forwardRef((e,t)=>{let{onSubmit:u,enableStepper:m=!0,disabled:g,onValueChange:p,onChange:h}=e,x=(0,l.__rest)(e,["onSubmit","enableStepper","disabled","onValueChange","onChange"]),f=(0,s.useRef)(null),[y,b]=s.default.useState(!1),v=s.default.useCallback(()=>{b(!0)},[]),w=s.default.useCallback(()=>{b(!1)},[]),[j,N]=s.default.useState(!1),S=s.default.useCallback(()=>{N(!0)},[]),k=s.default.useCallback(()=>{N(!1)},[]);return s.default.createElement(o.default,Object.assign({type:"number",ref:(0,i.mergeRefs)([f,t]),disabled:g,makeInputClassName:(0,i.makeClassName)("NumberInput"),onKeyDown:e=>{var t;if("Enter"===e.key&&!e.ctrlKey&&!e.altKey&&!e.shiftKey){let e=null==(t=f.current)?void 0:t.value;null==u||u(parseFloat(null!=e?e:""))}"ArrowDown"===e.key&&v(),"ArrowUp"===e.key&&S()},onKeyUp:e=>{"ArrowDown"===e.key&&w(),"ArrowUp"===e.key&&k()},onChange:e=>{g||(null==p||p(parseFloat(e.target.value)),null==h||h(e))},stepper:m?s.default.createElement("div",{className:(0,n.tremorTwMerge)("flex justify-center align-middle")},s.default.createElement("div",{tabIndex:-1,onClick:e=>e.preventDefault(),onMouseDown:e=>e.preventDefault(),onTouchStart:e=>{e.cancelable&&e.preventDefault()},onMouseUp:()=>{var e,t;g||(null==(e=f.current)||e.stepDown(),null==(t=f.current)||t.dispatchEvent(new Event("input",{bubbles:!0})))},className:(0,n.tremorTwMerge)(!g&&d,c,"group py-[10px] px-2.5 border-l border-tremor-border dark:border-dark-tremor-border")},s.default.createElement(a,{"data-testid":"step-down",className:(y?"scale-95":"")+" h-4 w-4 duration-75 transition group-active:scale-95"})),s.default.createElement("div",{tabIndex:-1,onClick:e=>e.preventDefault(),onMouseDown:e=>e.preventDefault(),onTouchStart:e=>{e.cancelable&&e.preventDefault()},onMouseUp:()=>{var e,t;g||(null==(e=f.current)||e.stepUp(),null==(t=f.current)||t.dispatchEvent(new Event("input",{bubbles:!0})))},className:(0,n.tremorTwMerge)(!g&&d,c,"group py-[10px] px-2.5 border-l border-tremor-border dark:border-dark-tremor-border")},s.default.createElement(r,{"data-testid":"step-up",className:(j?"scale-95":"")+" h-4 w-4 duration-75 transition group-active:scale-95"}))):null},x))});u.displayName="NumberInput",e.s(["default",0,({step:e=.01,style:l={width:"100%"},placeholder:s="Enter a numerical value",min:r,max:a,onChange:n,...i})=>(0,t.jsx)(u,{onWheel:e=>e.currentTarget.blur(),step:e,style:l,placeholder:s,min:r,max:a,onChange:n,...i})],435451)},860585,e=>{"use strict";var t=e.i(843476),l=e.i(199133);let{Option:s}=l.Select;e.s(["default",0,({value:e,onChange:r,className:a="",style:n={}})=>(0,t.jsxs)(l.Select,{style:{width:"100%",...n},value:e||void 0,onChange:r,className:a,placeholder:"n/a",allowClear:!0,children:[(0,t.jsx)(s,{value:"1h",children:"hourly"}),(0,t.jsx)(s,{value:"24h",children:"daily"}),(0,t.jsx)(s,{value:"7d",children:"weekly"}),(0,t.jsx)(s,{value:"30d",children:"monthly"})]}),"getBudgetDurationLabel",0,e=>e?({"1h":"hourly","24h":"daily","7d":"weekly","30d":"monthly"})[e]||e:"Not set"])},213205,e=>{"use strict";e.i(247167);var t=e.i(931067),l=e.i(271645);let s={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M678.3 642.4c24.2-13 51.9-20.4 81.4-20.4h.1c3 0 4.4-3.6 2.2-5.6a371.67 371.67 0 00-103.7-65.8c-.4-.2-.8-.3-1.2-.5C719.2 505 759.6 431.7 759.6 349c0-137-110.8-248-247.5-248S264.7 212 264.7 349c0 82.7 40.4 156 102.6 201.1-.4.2-.8.3-1.2.5-44.7 18.9-84.8 46-119.3 80.6a373.42 373.42 0 00-80.4 119.5A373.6 373.6 0 00137 888.8a8 8 0 008 8.2h59.9c4.3 0 7.9-3.5 8-7.8 2-77.2 32.9-149.5 87.6-204.3C357 628.2 432.2 597 512.2 597c56.7 0 111.1 15.7 158 45.1a8.1 8.1 0 008.1.3zM512.2 521c-45.8 0-88.9-17.9-121.4-50.4A171.2 171.2 0 01340.5 349c0-45.9 17.9-89.1 50.3-121.6S466.3 177 512.2 177s88.9 17.9 121.4 50.4A171.2 171.2 0 01683.9 349c0 45.9-17.9 89.1-50.3 121.6C601.1 503.1 558 521 512.2 521zM880 759h-84v-84c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v84h-84c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h84v84c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-84h84c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8z"}}]},name:"user-add",theme:"outlined"};var r=e.i(9583),a=l.forwardRef(function(e,a){return l.createElement(r.default,(0,t.default)({},e,{ref:a,icon:s}))});e.s(["UserAddOutlined",0,a],213205)},355619,e=>{"use strict";var t=e.i(602869);let l=async(e,l,s)=>{try{if(null===e||null===l)return;if(null!==s){let r=(await (0,t.modelAvailableCall)(s,e,l,!0,null,!0)).data.map(e=>e.id),a=[],n=[];return r.forEach(e=>{e.endsWith("/*")?a.push(e):n.push(e)}),[...a,...n]}}catch(e){console.error("Error fetching user models:",e)}};e.s(["fetchAvailableModelsForTeamOrKey",0,l,"getModelDisplayName",0,e=>{if("all-proxy-models"===e)return"All Proxy Models";if(e.endsWith("/*")){let t=e.replace("/*","");return`All ${t} models`}return e},"unfurlWildcardModelsInList",0,(e,t)=>{let l=[],s=[];return e.forEach(e=>{if(e.endsWith("/*")){let r=e.replace("/*",""),a=t.filter(e=>e.startsWith(r+"/"));s.push(...a),l.push(e)}else s.push(e)}),[...l,...s].filter((e,t,l)=>l.indexOf(e)===t)}])},350967,46757,e=>{"use strict";var t=e.i(290571),l=e.i(444755),s=e.i(673706),r=e.i(271645);let a={0:"grid-cols-none",1:"grid-cols-1",2:"grid-cols-2",3:"grid-cols-3",4:"grid-cols-4",5:"grid-cols-5",6:"grid-cols-6",7:"grid-cols-7",8:"grid-cols-8",9:"grid-cols-9",10:"grid-cols-10",11:"grid-cols-11",12:"grid-cols-12"},n={0:"sm:grid-cols-none",1:"sm:grid-cols-1",2:"sm:grid-cols-2",3:"sm:grid-cols-3",4:"sm:grid-cols-4",5:"sm:grid-cols-5",6:"sm:grid-cols-6",7:"sm:grid-cols-7",8:"sm:grid-cols-8",9:"sm:grid-cols-9",10:"sm:grid-cols-10",11:"sm:grid-cols-11",12:"sm:grid-cols-12"},i={0:"md:grid-cols-none",1:"md:grid-cols-1",2:"md:grid-cols-2",3:"md:grid-cols-3",4:"md:grid-cols-4",5:"md:grid-cols-5",6:"md:grid-cols-6",7:"md:grid-cols-7",8:"md:grid-cols-8",9:"md:grid-cols-9",10:"md:grid-cols-10",11:"md:grid-cols-11",12:"md:grid-cols-12"},o={0:"lg:grid-cols-none",1:"lg:grid-cols-1",2:"lg:grid-cols-2",3:"lg:grid-cols-3",4:"lg:grid-cols-4",5:"lg:grid-cols-5",6:"lg:grid-cols-6",7:"lg:grid-cols-7",8:"lg:grid-cols-8",9:"lg:grid-cols-9",10:"lg:grid-cols-10",11:"lg:grid-cols-11",12:"lg:grid-cols-12"};e.s(["colSpan",0,{1:"col-span-1",2:"col-span-2",3:"col-span-3",4:"col-span-4",5:"col-span-5",6:"col-span-6",7:"col-span-7",8:"col-span-8",9:"col-span-9",10:"col-span-10",11:"col-span-11",12:"col-span-12",13:"col-span-13"},"colSpanLg",0,{1:"lg:col-span-1",2:"lg:col-span-2",3:"lg:col-span-3",4:"lg:col-span-4",5:"lg:col-span-5",6:"lg:col-span-6",7:"lg:col-span-7",8:"lg:col-span-8",9:"lg:col-span-9",10:"lg:col-span-10",11:"lg:col-span-11",12:"lg:col-span-12",13:"lg:col-span-13"},"colSpanMd",0,{1:"md:col-span-1",2:"md:col-span-2",3:"md:col-span-3",4:"md:col-span-4",5:"md:col-span-5",6:"md:col-span-6",7:"md:col-span-7",8:"md:col-span-8",9:"md:col-span-9",10:"md:col-span-10",11:"md:col-span-11",12:"md:col-span-12",13:"md:col-span-13"},"colSpanSm",0,{1:"sm:col-span-1",2:"sm:col-span-2",3:"sm:col-span-3",4:"sm:col-span-4",5:"sm:col-span-5",6:"sm:col-span-6",7:"sm:col-span-7",8:"sm:col-span-8",9:"sm:col-span-9",10:"sm:col-span-10",11:"sm:col-span-11",12:"sm:col-span-12",13:"sm:col-span-13"},"gridCols",0,a,"gridColsLg",0,o,"gridColsMd",0,i,"gridColsSm",0,n],46757);let c=(0,s.makeClassName)("Grid"),d=(e,t)=>e&&Object.keys(t).includes(String(e))?t[e]:"",u=r.default.forwardRef((e,s)=>{let{numItems:u=1,numItemsSm:m,numItemsMd:g,numItemsLg:p,children:h,className:x}=e,f=(0,t.__rest)(e,["numItems","numItemsSm","numItemsMd","numItemsLg","children","className"]),y=d(u,a),b=d(m,n),v=d(g,i),w=d(p,o),j=(0,l.tremorTwMerge)(y,b,v,w);return r.default.createElement("div",Object.assign({ref:s,className:(0,l.tremorTwMerge)(c("root"),"grid",j,x)},f),h)});u.displayName="Grid",e.s(["Grid",0,u],350967)},981339,e=>{"use strict";var t=e.i(185793);e.s(["Skeleton",()=>t.default])},500727,e=>{"use strict";var t=e.i(266027),l=e.i(243652),s=e.i(602869),r=e.i(135214);let a=(0,l.createQueryKeys)("mcpServers");e.s(["useMCPServers",0,e=>{let{accessToken:l}=(0,r.default)();return(0,t.useQuery)({queryKey:a.list(e?{filters:{teamId:e}}:void 0),queryFn:async()=>await (0,s.fetchMCPServers)(l,e),enabled:!!l})}])},699857,e=>{"use strict";var t=e.i(266027),l=e.i(243652),s=e.i(602869),r=e.i(135214);let a=(0,l.createQueryKeys)("mcpToolsets");e.s(["useMCPToolsets",0,()=>{let{accessToken:e}=(0,r.default)();return(0,t.useQuery)({queryKey:a.list(),queryFn:async()=>await (0,s.fetchMCPToolsets)(e),enabled:!!e})}])},916940,e=>{"use strict";var t=e.i(843476),l=e.i(271645),s=e.i(199133),r=e.i(602869);e.s(["default",0,({onChange:e,value:a,className:n,accessToken:i,placeholder:o="Select vector stores",disabled:c=!1})=>{let[d,u]=(0,l.useState)([]),[m,g]=(0,l.useState)(!1);return(0,l.useEffect)(()=>{(async()=>{if(i){g(!0);try{let e=await (0,r.vectorStoreListCall)(i);e.data&&u(e.data)}catch(e){console.error("Error fetching vector stores:",e)}finally{g(!1)}}})()},[i]),(0,t.jsx)("div",{children:(0,t.jsx)(s.Select,{mode:"multiple",placeholder:o,onChange:e,value:a,loading:m,className:n,allowClear:!0,options:d.map(e=>({label:`${e.vector_store_name||e.vector_store_id} (${e.vector_store_id})`,value:e.vector_store_id,title:e.vector_store_description||e.vector_store_id})),optionFilterProp:"label",showSearch:!0,style:{width:"100%"},disabled:c})})}])},75921,e=>{"use strict";var t=e.i(843476),l=e.i(266027),s=e.i(243652),r=e.i(602869),a=e.i(135214);let n=(0,s.createQueryKeys)("mcpAccessGroups");var i=e.i(500727),o=e.i(699857),c=e.i(199133),d=e.i(234713);let u="toolset:";e.s(["default",0,({onChange:e,value:s,className:m,accessToken:g,placeholder:p="Select MCP servers",disabled:h=!1,teamId:x,allowNoMcpServers:f=!1,allowAllProxyMcpServers:y=!1})=>{let{data:b=[],isLoading:v}=(0,i.useMCPServers)(x),{data:w=[],isLoading:j}=(()=>{let{accessToken:e}=(0,a.default)();return(0,l.useQuery)({queryKey:n.list({}),queryFn:async()=>await (0,r.fetchMCPAccessGroups)(e),enabled:!!e})})(),{data:N=[],isLoading:S}=(0,o.useMCPToolsets)(),k=new Set(w),C=[...w.map(e=>({label:e,value:e,type:"accessGroup",searchText:`${e} Access Group`})),...b.map(e=>({label:`${e.server_name||e.server_id} (${e.server_id})`,value:e.server_id,type:"server",searchText:`${e.server_name||e.server_id} ${e.server_id} MCP Server`})),...N.map(e=>({label:e.toolset_name,value:`${u}${e.toolset_id}`,type:"toolset",searchText:`${e.toolset_name} ${e.toolset_id} Toolset`}))],_={accessGroup:"#52c41a",server:"#1890ff",toolset:"#722ed1"},M={accessGroup:"Access Group",server:"MCP Server",toolset:"Toolset"},E=[...s?.servers||[],...s?.accessGroups||[],...(s?.toolsets||[]).map(e=>`${u}${e}`)],L=f&&E.includes(d.NO_MCP_SERVERS_SENTINEL),R=E.includes(d.ALL_PROXY_MCP_SERVERS_SENTINEL);return(0,t.jsx)("div",{children:(0,t.jsxs)(c.Select,{mode:"multiple",placeholder:p,onChange:t=>{if(y&&t.includes(d.ALL_PROXY_MCP_SERVERS_SENTINEL))return void e({servers:[d.ALL_PROXY_MCP_SERVERS_SENTINEL],accessGroups:[],toolsets:[]});if(f&&t.includes(d.NO_MCP_SERVERS_SENTINEL))return void e({servers:[d.NO_MCP_SERVERS_SENTINEL],accessGroups:[],toolsets:[]});let l=t.filter(e=>e.startsWith(u)).map(e=>e.slice(u.length)),s=t.filter(e=>!e.startsWith(u));e({servers:s.filter(e=>!k.has(e)),accessGroups:s.filter(e=>k.has(e)),toolsets:l})},value:E,loading:v||j||S,className:m,allowClear:!0,showSearch:!0,style:{width:"100%"},disabled:h,filterOption:(e,t)=>t?.value===d.NO_MCP_SERVERS_SENTINEL||t?.value===d.ALL_PROXY_MCP_SERVERS_SENTINEL||(C.find(e=>e.value===t?.value)?.searchText||"").toLowerCase().includes(e.toLowerCase()),children:[(y||R)&&(0,t.jsx)(c.Select.Option,{value:d.ALL_PROXY_MCP_SERVERS_SENTINEL,label:"All Proxy MCP Servers",children:(0,t.jsx)("span",{style:{color:"#1890ff",fontWeight:500},children:"All Proxy MCP Servers"})},d.ALL_PROXY_MCP_SERVERS_SENTINEL),f&&(0,t.jsx)(c.Select.Option,{value:d.NO_MCP_SERVERS_SENTINEL,label:"No MCP Servers",children:(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[(0,t.jsx)("span",{style:{flex:1},children:"No MCP Servers"}),(0,t.jsx)("span",{style:{color:"#8c8c8c",fontSize:"12px",fontWeight:500,opacity:.8},children:"Block all"})]})},d.NO_MCP_SERVERS_SENTINEL),C.map(e=>(0,t.jsx)(c.Select.Option,{value:e.value,label:e.label,disabled:L||R,children:(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[(0,t.jsx)("span",{style:{display:"inline-block",width:8,height:8,borderRadius:"50%",background:_[e.type],flexShrink:0}}),(0,t.jsx)("span",{style:{flex:1},children:e.label}),(0,t.jsx)("span",{style:{color:_[e.type],fontSize:"12px",fontWeight:500,opacity:.8},children:M[e.type]})]})},e.value))]})})}],75921)},988297,e=>{"use strict";var t=e.i(271645);let l=t.forwardRef(function(e,l){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:l},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 4v16m8-8H4"}))});e.s(["PlusIcon",0,l],988297)},246349,e=>{"use strict";let t=(0,e.i(475254).default)("chevron-right",[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]]);e.s(["default",0,t])},797672,e=>{"use strict";var t=e.i(271645);let l=t.forwardRef(function(e,l){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:l},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"}))});e.s(["PencilIcon",0,l],797672)},992619,e=>{"use strict";var t=e.i(843476),l=e.i(271645),s=e.i(779241),r=e.i(599724),a=e.i(199133),n=e.i(983561),i=e.i(695411);e.s(["default",0,({accessToken:e,value:o,placeholder:c="Select a Model",onChange:d,disabled:u=!1,style:m,className:g,showLabel:p=!0,labelText:h="Select Model"})=>{let[x,f]=(0,l.useState)(o),[y,b]=(0,l.useState)(!1),[v,w]=(0,l.useState)([]),j=(0,l.useRef)(null);return(0,l.useEffect)(()=>{f(o)},[o]),(0,l.useEffect)(()=>{e&&(async()=>{try{let t=await (0,i.fetchAvailableModels)(e);t.length>0&&w(t)}catch(e){console.error("Error fetching model info:",e)}})()},[e]),(0,t.jsxs)("div",{children:[p&&(0,t.jsxs)(r.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,t.jsx)(n.RobotOutlined,{className:"mr-2"})," ",h]}),(0,t.jsx)(a.Select,{value:x,placeholder:c,onChange:e=>{"custom"===e?(b(!0),f(void 0)):(b(!1),f(e),d&&d(e))},options:[...Array.from(new Set(v.map(e=>e.model_group))).map((e,t)=>({value:e,label:e,key:t})),{value:"custom",label:"Enter custom model",key:"custom"}],style:{width:"100%",...m},showSearch:!0,className:`rounded-md ${g||""}`,disabled:u}),y&&(0,t.jsx)(s.TextInput,{className:"mt-2",placeholder:"Enter custom model name",onValueChange:e=>{j.current&&clearTimeout(j.current),j.current=setTimeout(()=>{f(e),d&&d(e)},500)},disabled:u})]})}])},361653,e=>{"use strict";let t=(0,e.i(475254).default)("circle-alert",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]]);e.s(["default",0,t])},409797,e=>{"use strict";var t=e.i(631171);e.s(["ChevronDownIcon",()=>t.default])},531516,696609,e=>{"use strict";var t=e.i(843476),l=e.i(271645),s=e.i(536916),r=e.i(599724),a=e.i(409797),n=e.i(246349),n=n;let i=/\b(delete|remove|destroy|purge|drop|erase|unlink)\b/i,o=/\b(create|add|insert|new|post|submit|register|make|generate|write|upload)\b/i,c=/\b(update|edit|modify|change|patch|put|set|rename|move|transform)\b/i,d=/\b(get|read|list|fetch|search|find|query|retrieve|show|view|check|describe|info)\b/i;function u(e,t=""){let l=e.toLowerCase();if(d.test(l))return"read";if(i.test(l))return"delete";if(c.test(l))return"update";if(o.test(l))return"create";if(t){let e=t.toLowerCase();if(d.test(e))return"read";if(i.test(e))return"delete";if(c.test(e))return"update";if(o.test(e))return"create"}return"unknown"}function m(e){let t={read:[],create:[],update:[],delete:[],unknown:[]};for(let l of e)t[u(l.name,l.description)].push(l);return t}let g={read:{label:"Read",description:"Safe operations — fetch, list, search. No side effects.",risk:"low"},create:{label:"Create",description:"Add new resources — insert, upload, register.",risk:"medium"},update:{label:"Update",description:"Modify existing resources — edit, patch, rename.",risk:"medium"},delete:{label:"Delete",description:"Destructive operations — remove, purge, destroy.",risk:"high"},unknown:{label:"Other",description:"Operations that could not be automatically classified.",risk:"unknown"}};e.s(["CRUD_GROUP_META",0,g,"classifyToolOp",0,u,"groupToolsByCrud",0,m],696609);let p=["read","create","update","delete","unknown"],h={low:"bg-green-100 text-green-800",medium:"bg-yellow-100 text-yellow-800",high:"bg-red-100 text-red-800 font-semibold",unknown:"bg-gray-100 text-gray-700"},x={read:"border-green-200",create:"border-blue-200",update:"border-yellow-200",delete:"border-red-300",unknown:"border-gray-200"},f={read:"bg-green-50",create:"bg-blue-50",update:"bg-yellow-50",delete:"bg-red-50",unknown:"bg-gray-50"};e.s(["default",0,({tools:e,value:i,onChange:o,readOnly:c=!1,searchFilter:d=""})=>{let[u,y]=(0,l.useState)({read:!1,create:!1,update:!1,delete:!1,unknown:!0}),b=(0,l.useMemo)(()=>m(e),[e]),v=(0,l.useMemo)(()=>new Set(void 0===i?e.map(e=>e.name):i),[i,e]),w=e=>{if(c)return;let t=new Set(v);t.has(e)?t.delete(e):t.add(e),o(Array.from(t))};return 0===e.length?null:(0,t.jsx)("div",{className:"space-y-3",children:p.map(e=>{let l,i=b[e];if(0===i.length)return null;if(d){let e=d.toLowerCase();if(!i.some(t=>t.name.toLowerCase().includes(e)||(t.description??"").toLowerCase().includes(e)))return null}let m=g[e],p=(l=b[e]).length>0&&l.every(e=>v.has(e.name)),j=(e=>{let t=b[e];if(0===t.length)return!1;let l=t.filter(e=>v.has(e.name)).length;return l>0&&l{y(t=>({...t,[e]:!t[e]}))},children:[N?(0,t.jsx)(n.default,{className:"w-4 h-4 text-gray-500 shrink-0"}):(0,t.jsx)(a.ChevronDownIcon,{className:"w-4 h-4 text-gray-500 shrink-0"}),(0,t.jsx)("span",{className:"font-semibold text-gray-900 text-sm",children:m.label}),(0,t.jsx)("span",{className:`text-xs px-2 py-0.5 rounded-full ${h[m.risk]}`,children:"high"===m.risk?"High Risk":"medium"===m.risk?"Medium Risk":"low"===m.risk?"Safe":"Unclassified"}),(0,t.jsxs)("span",{className:"text-xs text-gray-500 ml-1",children:[i.filter(e=>v.has(e.name)).length,"/",i.length," allowed"]})]}),!c&&(0,t.jsxs)("div",{className:"flex items-center gap-2 ml-4",children:[(0,t.jsx)(r.Text,{className:"text-xs text-gray-500",children:p?"All on":j?"Partial":"All off"}),(0,t.jsx)(s.Checkbox,{checked:p,indeterminate:j,onChange:t=>((e,t)=>{if(c)return;let l=new Set(v);for(let s of b[e])t?l.add(s.name):l.delete(s.name);o(Array.from(l))})(e,t.target.checked),onClick:e=>e.stopPropagation()})]})]}),!N&&(0,t.jsx)("div",{className:"px-4 pt-2 pb-1 text-xs text-gray-500 bg-white border-b border-gray-100",children:m.description}),!N&&(0,t.jsx)("div",{className:"bg-white divide-y divide-gray-50",children:i.filter(e=>!d||e.name.toLowerCase().includes(d.toLowerCase())||(e.description??"").toLowerCase().includes(d.toLowerCase())).map(e=>{let l,a=(l=e.name,v.has(l));return(0,t.jsxs)("div",{className:`flex items-start gap-3 px-4 py-2.5 transition-colors hover:bg-gray-50 ${!c?"cursor-pointer":""} ${a?"":"opacity-60"}`,onClick:()=>w(e.name),children:[(0,t.jsx)(s.Checkbox,{checked:a,onChange:()=>w(e.name),disabled:c,onClick:e=>e.stopPropagation()}),(0,t.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,t.jsx)(r.Text,{className:"font-medium text-gray-900 text-sm",children:e.name}),e.description&&(0,t.jsx)(r.Text,{className:"text-xs text-gray-500 mt-0.5 leading-snug",children:e.description})]}),(0,t.jsx)("span",{className:`text-xs px-1.5 py-0.5 rounded shrink-0 ${a?"bg-green-100 text-green-700":"bg-gray-100 text-gray-500"}`,children:a?"on":"off"})]},e.name)})})]},e)})})}],531516)},695411,e=>{"use strict";var t=e.i(602869);let l=async e=>{try{let l=await (0,t.modelHubCall)(e);if(l?.data.length>0){let e=l.data.map(e=>({model_group:e.model_group,mode:e?.mode}));return e.sort((e,t)=>e.model_group.localeCompare(t.model_group)),e}return[]}catch(e){throw console.error("Error fetching model info:",e),e}};e.s(["fetchAvailableModels",0,l])},841947,e=>{"use strict";let t=(0,e.i(475254).default)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);e.s(["default",0,t])},603908,e=>{"use strict";let t=(0,e.i(475254).default)("plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]);e.s(["default",0,t])},107233,e=>{"use strict";var t=e.i(603908);e.s(["Plus",()=>t.default])},37727,e=>{"use strict";var t=e.i(841947);e.s(["X",()=>t.default])},158392,63209,e=>{"use strict";var t=e.i(843476),l=e.i(311451);let s={ttl:3600,lowest_latency_buffer:0},r=({routingStrategyArgs:e})=>{let r={ttl:"Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"max-w-3xl",children:[(0,t.jsx)("h3",{className:"text-sm font-medium text-gray-900",children:"Latency-Based Configuration"}),(0,t.jsx)("p",{className:"text-xs text-gray-500 mt-1",children:"Fine-tune latency-based routing behavior"})]}),(0,t.jsx)("div",{className:"grid grid-cols-1 gap-6 lg:grid-cols-2 xl:grid-cols-3",children:Object.entries(e||s).map(([e,s])=>(0,t.jsx)("div",{className:"space-y-2",children:(0,t.jsxs)("label",{className:"block",children:[(0,t.jsx)("span",{className:"text-xs font-medium text-gray-700 uppercase tracking-wide",children:e.replace(/_/g," ")}),(0,t.jsx)("p",{className:"text-xs text-gray-500 mt-0.5 mb-2",children:r[e]||""}),(0,t.jsx)(l.Input,{name:e,defaultValue:"object"==typeof s?JSON.stringify(s,null,2):s?.toString(),className:"font-mono text-sm w-full"})]})},e))})]}),(0,t.jsx)("div",{className:"border-t border-gray-200"})]})},a=({routerSettings:e,routerFieldsMetadata:s})=>(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"max-w-3xl",children:[(0,t.jsx)("h3",{className:"text-sm font-medium text-gray-900",children:"Reliability & Retries"}),(0,t.jsx)("p",{className:"text-xs text-gray-500 mt-1",children:"Configure retry logic and failure handling"})]}),(0,t.jsx)("div",{className:"grid grid-cols-1 gap-6 lg:grid-cols-2 xl:grid-cols-3",children:Object.entries(e).filter(([e])=>"fallbacks"!=e&&"context_window_fallbacks"!=e&&"routing_strategy_args"!=e&&"routing_strategy"!=e&&"enable_tag_filtering"!=e&&"retry_policy"!=e&&"model_group_retry_policy"!=e&&"routing_groups"!=e).map(([e,r])=>(0,t.jsx)("div",{className:"space-y-2",children:(0,t.jsxs)("label",{className:"block",children:[(0,t.jsx)("span",{className:"text-xs font-medium text-gray-700 uppercase tracking-wide",children:s[e]?.ui_field_name||e}),(0,t.jsx)("p",{className:"text-xs text-gray-500 mt-0.5 mb-2",children:s[e]?.field_description||""}),(0,t.jsx)(l.Input,{name:e,defaultValue:null==r||"null"===r?"":"object"==typeof r?JSON.stringify(r,null,2):r?.toString()||"",placeholder:"—",className:"font-mono text-sm w-full"})]})},e))})]});var n=e.i(199133);let i=({selectedStrategy:e,availableStrategies:l,routingStrategyDescriptions:s,routerFieldsMetadata:r,onStrategyChange:a})=>(0,t.jsxs)("div",{className:"space-y-2 max-w-3xl",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"text-xs font-medium text-gray-700 uppercase tracking-wide",children:r.routing_strategy?.ui_field_name||"Routing Strategy"}),(0,t.jsx)("p",{className:"text-xs text-gray-500 mt-0.5 mb-2",children:r.routing_strategy?.field_description||""})]}),(0,t.jsx)("div",{className:"routing-strategy-select max-w-3xl",children:(0,t.jsx)(n.Select,{value:e,onChange:a,style:{width:"100%"},size:"large",children:l.map(e=>(0,t.jsx)(n.Select.Option,{value:e,label:e,children:(0,t.jsxs)("div",{className:"flex flex-col gap-0.5 py-1",children:[(0,t.jsx)("span",{className:"font-mono text-sm font-medium",children:e}),s[e]&&(0,t.jsx)("span",{className:"text-xs text-gray-500 font-normal",children:s[e]})]})},e))})})]});var o=e.i(790848);let c=({enabled:e,routerFieldsMetadata:l,onToggle:s})=>(0,t.jsx)("div",{className:"space-y-3 max-w-3xl",children:(0,t.jsxs)("div",{className:"flex items-start justify-between",children:[(0,t.jsxs)("div",{className:"flex-1",children:[(0,t.jsx)("label",{className:"text-xs font-medium text-gray-700 uppercase tracking-wide",children:l.enable_tag_filtering?.ui_field_name||"Enable Tag Filtering"}),(0,t.jsxs)("p",{className:"text-xs text-gray-500 mt-0.5",children:[l.enable_tag_filtering?.field_description||"",l.enable_tag_filtering?.link&&(0,t.jsxs)(t.Fragment,{children:[" ",(0,t.jsx)("a",{href:l.enable_tag_filtering.link,target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:text-blue-800 underline",children:"Learn more"})]})]})]}),(0,t.jsx)(o.Switch,{checked:e,onChange:s,className:"ml-4"})]})});e.s(["default",0,({value:e,onChange:l,routerFieldsMetadata:s,availableRoutingStrategies:n,routingStrategyDescriptions:o})=>(0,t.jsxs)("div",{className:"w-full space-y-8 py-2",children:[(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"max-w-3xl",children:[(0,t.jsx)("h3",{className:"text-sm font-medium text-gray-900",children:"Routing Settings"}),(0,t.jsx)("p",{className:"text-xs text-gray-500 mt-1",children:"Configure how requests are routed to deployments"})]}),n.length>0&&(0,t.jsx)(i,{selectedStrategy:e.selectedStrategy||e.routerSettings.routing_strategy||null,availableStrategies:n,routingStrategyDescriptions:o,routerFieldsMetadata:s,onStrategyChange:t=>{l({...e,selectedStrategy:t})}}),(0,t.jsx)(c,{enabled:e.enableTagFiltering,routerFieldsMetadata:s,onToggle:t=>{l({...e,enableTagFiltering:t})}})]}),(0,t.jsx)("div",{className:"border-t border-gray-200"}),"latency-based-routing"===e.selectedStrategy&&(0,t.jsx)(r,{routingStrategyArgs:e.routerSettings.routing_strategy_args}),(0,t.jsx)(a,{routerSettings:e.routerSettings,routerFieldsMetadata:s})]})],158392);var d=e.i(361653);e.s(["AlertCircle",()=>d.default],63209)},425063,e=>{"use strict";let t=(0,e.i(475254).default)("arrow-down",[["path",{d:"M12 5v14",key:"s699le"}],["path",{d:"m19 12-7 7-7-7",key:"1idqje"}]]);e.s(["ArrowDown",0,t],425063)},419470,e=>{"use strict";var t=e.i(843476),l=e.i(994388),s=e.i(653496),r=e.i(107233),a=e.i(271645),n=e.i(888259),i=e.i(199133),o=e.i(592968),c=e.i(63209),d=e.i(425063),u=e.i(37727);function m({group:e,onChange:l,availableModels:s,maxFallbacks:r}){let a=s.filter(t=>t!==e.primaryModel),n=e.fallbackModels.length{let s=[...e.fallbackModels];s.includes(t)&&(s=s.filter(e=>e!==t)),l({...e,primaryModel:t,fallbackModels:s})},showSearch:!0,getPopupContainer:e=>e.parentElement||document.body,filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase()),options:s.map(e=>({label:e,value:e}))}),!e.primaryModel&&(0,t.jsxs)("div",{className:"mt-2 flex items-center gap-2 text-amber-600 text-xs bg-amber-50 p-2 rounded-sm",children:[(0,t.jsx)(c.AlertCircle,{className:"w-4 h-4"}),(0,t.jsx)("span",{children:"Select a model to begin configuring fallbacks"})]})]}),(0,t.jsx)("div",{className:"flex items-center justify-center -my-4 z-10",children:(0,t.jsxs)("div",{className:"bg-indigo-50 text-indigo-500 px-4 py-1 rounded-full text-xs font-bold border border-indigo-100 flex items-center gap-2 shadow-xs",children:[(0,t.jsx)(d.ArrowDown,{className:"w-4 h-4"}),"IF FAILS, TRY..."]})}),(0,t.jsxs)("div",{className:`transition-opacity duration-300 ${!e.primaryModel?"opacity-50 pointer-events-none":"opacity-100"}`,children:[(0,t.jsxs)("label",{className:"block text-sm font-semibold text-gray-700 mb-2",children:["Fallback Chain ",(0,t.jsx)("span",{className:"text-red-500",children:"*"}),(0,t.jsxs)("span",{className:"text-xs text-gray-500 font-normal ml-2",children:["(Max ",r," fallbacks at a time)"]})]}),(0,t.jsxs)("div",{className:"bg-gray-50 rounded-xl p-4 border border-gray-200",children:[(0,t.jsxs)("div",{className:"mb-4",children:[(0,t.jsx)(i.Select,{mode:"multiple",className:"w-full",size:"large",placeholder:n?"Select fallback models to add...":`Maximum ${r} fallbacks reached`,value:e.fallbackModels,onChange:t=>{let s=t.slice(0,r);l({...e,fallbackModels:s})},disabled:!e.primaryModel,getPopupContainer:e=>e.parentElement||document.body,options:a.map(e=>({label:e,value:e})),optionRender:(l,s)=>{let r=e.fallbackModels.includes(l.value),a=r?e.fallbackModels.indexOf(l.value)+1:null;return(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[r&&null!==a&&(0,t.jsx)("span",{className:"flex items-center justify-center w-5 h-5 rounded-sm bg-indigo-100 text-indigo-600 text-xs font-bold",children:a}),(0,t.jsx)("span",{children:l.label})]})},maxTagCount:"responsive",maxTagPlaceholder:e=>(0,t.jsx)(o.Tooltip,{styles:{root:{pointerEvents:"none"}},title:e.map(({value:e})=>e).join(", "),children:(0,t.jsxs)("span",{children:["+",e.length," more"]})}),showSearch:!0,filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase())}),(0,t.jsx)("p",{className:"text-xs text-gray-500 mt-1 ml-1",children:n?`Search and select multiple models. Selected models will appear below in order. (${e.fallbackModels.length}/${r} used)`:`Maximum ${r} fallbacks reached. Remove some to add more.`})]}),(0,t.jsx)("div",{className:"space-y-2 min-h-[100px]",children:0===e.fallbackModels.length?(0,t.jsxs)("div",{className:"h-32 border-2 border-dashed border-gray-300 rounded-lg flex flex-col items-center justify-center text-gray-400",children:[(0,t.jsx)("span",{className:"text-sm",children:"No fallback models selected"}),(0,t.jsx)("span",{className:"text-xs mt-1",children:"Add models from the dropdown above"})]}):e.fallbackModels.map((s,r)=>(0,t.jsxs)("div",{className:"group flex items-center justify-between p-3 bg-white rounded-lg border border-gray-200 hover:border-indigo-300 hover:shadow-xs transition-all",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)("div",{className:"flex items-center justify-center w-6 h-6 rounded-sm bg-gray-100 text-gray-400 group-hover:text-indigo-500 group-hover:bg-indigo-50",children:(0,t.jsx)("span",{className:"text-xs font-bold",children:r+1})}),(0,t.jsx)("div",{children:(0,t.jsx)("span",{className:"font-medium text-gray-800",children:s})})]}),(0,t.jsx)("button",{type:"button",onClick:()=>{let t;return t=e.fallbackModels.filter((e,t)=>t!==r),void l({...e,fallbackModels:t})},className:"opacity-0 group-hover:opacity-100 transition-opacity text-gray-400 hover:text-red-500 p-1",children:(0,t.jsx)(u.X,{className:"w-4 h-4"})})]},`${s}-${r}`))})]})]})]})}e.s(["FallbackSelectionForm",0,function({groups:e,onGroupsChange:i,availableModels:o,maxFallbacks:c=10,maxGroups:d=5}){let[u,g]=(0,a.useState)(e.length>0?e[0].id:"1");(0,a.useEffect)(()=>{e.length>0?e.some(e=>e.id===u)||g(e[0].id):g("1")},[e]);let p=()=>{if(e.length>=d)return;let t=Date.now().toString();i([...e,{id:t,primaryModel:null,fallbackModels:[]}]),g(t)},h=t=>{i(e.map(e=>e.id===t.id?t:e))},x=e.map((l,s)=>{let r=l.primaryModel?l.primaryModel:`Group ${s+1}`;return{key:l.id,label:r,closable:e.length>1,children:(0,t.jsx)(m,{group:l,onChange:h,availableModels:o,maxFallbacks:c})}});return 0===e.length?(0,t.jsxs)("div",{className:"text-center py-12 bg-gray-50 rounded-lg border border-dashed border-gray-300",children:[(0,t.jsx)("p",{className:"text-gray-500 mb-4",children:"No fallback groups configured"}),(0,t.jsx)(l.Button,{variant:"primary",onClick:p,icon:()=>(0,t.jsx)(r.Plus,{className:"w-4 h-4"}),children:"Create First Group"})]}):(0,t.jsx)(s.Tabs,{type:"editable-card",activeKey:u,onChange:g,onEdit:(t,l)=>{"add"===l?p():"remove"===l&&e.length>1&&(t=>{if(1===e.length)return n.default.warning("At least one group is required");let l=e.filter(e=>e.id!==t);i(l),u===t&&l.length>0&&g(l[l.length-1].id)})(t)},items:x,className:"fallback-tabs",tabBarStyle:{marginBottom:0},hideAdd:e.length>=d})}],419470)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0.1o3m2oaq6je.js b/litellm/proxy/_experimental/out/_next/static/chunks/0.1o3m2oaq6je.js new file mode 100644 index 00000000000..2eeed6a6c76 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/0.1o3m2oaq6je.js @@ -0,0 +1,86 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,509345,e=>{"use strict";var t,a,l=e.i(843476),r=e.i(271645),i=e.i(464571),s=e.i(326373),n=e.i(653496),o=e.i(755151),d=e.i(646563),c=e.i(245094),m=e.i(602869),u=e.i(808613),p=e.i(311451),g=e.i(212931),x=e.i(199133),h=e.i(262218),f=e.i(898586),y=e.i(727749),j=e.i(770914),_=e.i(515831),b=e.i(175712),v=e.i(519756);let{Text:w}=f.Typography,{Option:N}=x.Select,C=({visible:e,prebuiltPatterns:t,categories:a,selectedPatternName:r,patternAction:s,onPatternNameChange:n,onActionChange:o,onAdd:d,onCancel:c})=>(0,l.jsxs)(g.Modal,{title:"Add prebuilt pattern",open:e,onCancel:c,footer:null,width:800,children:[(0,l.jsxs)(j.Space,{direction:"vertical",style:{width:"100%"},size:"large",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)(w,{strong:!0,children:"Pattern type"}),(0,l.jsx)(x.Select,{placeholder:"Choose pattern type",value:r,onChange:n,style:{width:"100%",marginTop:8},showSearch:!0,filterOption:(e,a)=>{let l=t.find(e=>e.name===a?.value);return!!l&&(l.display_name.toLowerCase().includes(e.toLowerCase())||l.name.toLowerCase().includes(e.toLowerCase()))},children:a.map(e=>{let a=t.filter(t=>t.category===e);return 0===a.length?null:(0,l.jsx)(x.Select.OptGroup,{label:e,children:a.map(e=>(0,l.jsx)(N,{value:e.name,children:e.display_name},e.name))},e)})})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(w,{strong:!0,children:"Action"}),(0,l.jsx)(w,{type:"secondary",style:{display:"block",marginTop:4,marginBottom:8},children:"Choose what action the guardrail should take when this pattern is detected"}),(0,l.jsxs)(x.Select,{value:s,onChange:o,style:{width:"100%"},children:[(0,l.jsx)(N,{value:"BLOCK",children:"Block"}),(0,l.jsx)(N,{value:"MASK",children:"Mask"})]})]})]}),(0,l.jsxs)("div",{style:{display:"flex",justifyContent:"flex-end",gap:"8px",marginTop:"24px"},children:[(0,l.jsx)(i.Button,{onClick:c,children:"Cancel"}),(0,l.jsx)(i.Button,{type:"primary",onClick:d,children:"Add"})]})]}),{Text:S}=f.Typography,{Option:k}=x.Select,I=({visible:e,patternName:t,patternRegex:a,patternAction:r,onNameChange:s,onRegexChange:n,onActionChange:o,onAdd:d,onCancel:c})=>(0,l.jsxs)(g.Modal,{title:"Add custom regex pattern",open:e,onCancel:c,footer:null,width:800,children:[(0,l.jsxs)(j.Space,{direction:"vertical",style:{width:"100%"},size:"large",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)(S,{strong:!0,children:"Pattern name"}),(0,l.jsx)(p.Input,{placeholder:"e.g., internal_id, employee_code",value:t,onChange:e=>s(e.target.value),style:{marginTop:8}})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(S,{strong:!0,children:"Regex pattern"}),(0,l.jsx)(p.Input,{placeholder:"e.g., ID-[0-9]{6}",value:a,onChange:e=>n(e.target.value),style:{marginTop:8}}),(0,l.jsx)(S,{type:"secondary",style:{fontSize:12},children:"Enter a valid regular expression to match sensitive data"})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(S,{strong:!0,children:"Action"}),(0,l.jsx)(S,{type:"secondary",style:{display:"block",marginTop:4,marginBottom:8},children:"Choose what action the guardrail should take when this pattern is detected"}),(0,l.jsxs)(x.Select,{value:r,onChange:o,style:{width:"100%"},children:[(0,l.jsx)(k,{value:"BLOCK",children:"Block"}),(0,l.jsx)(k,{value:"MASK",children:"Mask"})]})]})]}),(0,l.jsxs)("div",{style:{display:"flex",justifyContent:"flex-end",gap:"8px",marginTop:"24px"},children:[(0,l.jsx)(i.Button,{onClick:c,children:"Cancel"}),(0,l.jsx)(i.Button,{type:"primary",onClick:d,children:"Add"})]})]}),{Text:A}=f.Typography,{Option:O}=x.Select,T=({visible:e,keyword:t,action:a,description:r,onKeywordChange:s,onActionChange:n,onDescriptionChange:o,onAdd:d,onCancel:c})=>(0,l.jsxs)(g.Modal,{title:"Add blocked keyword",open:e,onCancel:c,footer:null,width:800,children:[(0,l.jsxs)(j.Space,{direction:"vertical",style:{width:"100%"},size:"large",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)(A,{strong:!0,children:"Keyword"}),(0,l.jsx)(p.Input,{placeholder:"Enter sensitive keyword or phrase",value:t,onChange:e=>s(e.target.value),style:{marginTop:8}})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(A,{strong:!0,children:"Action"}),(0,l.jsx)(A,{type:"secondary",style:{display:"block",marginTop:4,marginBottom:8},children:"Choose what action the guardrail should take when this keyword is detected"}),(0,l.jsxs)(x.Select,{value:a,onChange:n,style:{width:"100%"},children:[(0,l.jsx)(O,{value:"BLOCK",children:"Block"}),(0,l.jsx)(O,{value:"MASK",children:"Mask"})]})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(A,{strong:!0,children:"Description (optional)"}),(0,l.jsx)(p.Input.TextArea,{placeholder:"Explain why this keyword is sensitive",value:r,onChange:e=>o(e.target.value),rows:3,style:{marginTop:8}})]})]}),(0,l.jsxs)("div",{style:{display:"flex",justifyContent:"flex-end",gap:"8px",marginTop:"24px"},children:[(0,l.jsx)(i.Button,{onClick:c,children:"Cancel"}),(0,l.jsx)(i.Button,{type:"primary",onClick:d,children:"Add"})]})]});var P=e.i(291542),L=e.i(955135);let{Text:B}=f.Typography,{Option:F}=x.Select,$=({patterns:e,onActionChange:t,onRemove:a})=>{let r=[{title:"Type",dataIndex:"type",key:"type",width:100,render:e=>(0,l.jsx)(h.Tag,{color:"prebuilt"===e?"blue":"green",children:"prebuilt"===e?"Prebuilt":"Custom"})},{title:"Pattern name",dataIndex:"name",key:"name",render:(e,t)=>t.display_name||t.name},{title:"Regex pattern",dataIndex:"pattern",key:"pattern",render:e=>e?(0,l.jsxs)(B,{code:!0,style:{fontSize:12},children:[e.substring(0,40),"..."]}):"-"},{title:"Action",dataIndex:"action",key:"action",width:150,render:(e,a)=>(0,l.jsxs)(x.Select,{value:e,onChange:e=>t(a.id,e),style:{width:120},size:"small",children:[(0,l.jsx)(F,{value:"BLOCK",children:"Block"}),(0,l.jsx)(F,{value:"MASK",children:"Mask"})]})},{title:"",key:"actions",width:100,render:(e,t)=>(0,l.jsx)(i.Button,{type:"text",danger:!0,size:"small",icon:(0,l.jsx)(L.DeleteOutlined,{}),onClick:()=>a(t.id),children:"Delete"})}];return 0===e.length?(0,l.jsx)("div",{style:{textAlign:"center",padding:"40px 0",color:"#999"},children:"No patterns added."}):(0,l.jsx)(P.Table,{dataSource:e,columns:r,rowKey:"id",pagination:!1,size:"small"})},{Text:E}=f.Typography,{Option:M}=x.Select,R=({keywords:e,onActionChange:t,onRemove:a})=>{let r=[{title:"Keyword",dataIndex:"keyword",key:"keyword"},{title:"Action",dataIndex:"action",key:"action",width:150,render:(e,a)=>(0,l.jsxs)(x.Select,{value:e,onChange:e=>t(a.id,"action",e),style:{width:120},size:"small",children:[(0,l.jsx)(M,{value:"BLOCK",children:"Block"}),(0,l.jsx)(M,{value:"MASK",children:"Mask"})]})},{title:"Description",dataIndex:"description",key:"description",render:e=>e||"-"},{title:"",key:"actions",width:100,render:(e,t)=>(0,l.jsx)(i.Button,{type:"text",danger:!0,size:"small",icon:(0,l.jsx)(L.DeleteOutlined,{}),onClick:()=>a(t.id),children:"Delete"})}];return 0===e.length?(0,l.jsx)("div",{style:{textAlign:"center",padding:"40px 0",color:"#999"},children:"No keywords added."}):(0,l.jsx)(P.Table,{dataSource:e,columns:r,rowKey:"id",pagination:!1,size:"small"})};var G=e.i(362024),z=e.i(993914);let{Title:D,Text:K}=f.Typography,{Option:q}=x.Select,H=({availableCategories:e,selectedCategories:t,onCategoryAdd:a,onCategoryRemove:s,onCategoryUpdate:n,accessToken:o,pendingSelection:c,onPendingSelectionChange:u})=>{let[p,g]=r.default.useState(""),f=void 0!==c?c:p,y=u||g,[j,_]=r.default.useState({}),[v,w]=r.default.useState({}),[N,C]=r.default.useState({}),[S,k]=r.default.useState([]),[I,A]=r.default.useState(""),[O,T]=r.default.useState(!1),B=async e=>{if(o&&!j[e]){C(t=>({...t,[e]:!0}));try{let t=await (0,m.getCategoryYaml)(o,e),a=t.yaml_content;if("json"===t.file_type)try{let e=JSON.parse(a);a=JSON.stringify(e,null,2)}catch(t){console.warn(`Failed to format JSON for ${e}:`,t)}_(t=>({...t,[e]:a})),w(a=>({...a,[e]:t.file_type||"yaml"}))}catch(t){console.error(`Failed to fetch content for category ${e}:`,t)}finally{C(t=>({...t,[e]:!1}))}}};r.default.useEffect(()=>{if(f&&o){let e=j[f];if(e)return void A(e);T(!0),(0,m.getCategoryYaml)(o,f).then(e=>{let t=e.yaml_content;if("json"===e.file_type)try{let e=JSON.parse(t);t=JSON.stringify(e,null,2)}catch(e){console.warn(`Failed to format JSON for ${f}:`,e)}A(t),_(e=>({...e,[f]:t})),w(t=>({...t,[f]:e.file_type||"yaml"}))}).catch(e=>{console.error(`Failed to fetch preview content for category ${f}:`,e),A("")}).finally(()=>{T(!1)})}else A(""),T(!1)},[f,o]);let F=[{title:"Category",dataIndex:"display_name",key:"display_name",render:(t,a)=>{let r=e.find(e=>e.name===a.category);return(0,l.jsxs)("div",{children:[(0,l.jsx)("div",{style:{fontWeight:500},children:t}),r?.description&&(0,l.jsx)("div",{style:{fontSize:"12px",color:"#888",marginTop:"4px"},children:r.description})]})}},{title:"Action",dataIndex:"action",key:"action",width:150,render:(e,t)=>(0,l.jsxs)(x.Select,{value:e,onChange:e=>n(t.id,"action",e),style:{width:"100%"},children:[(0,l.jsx)(q,{value:"BLOCK",children:(0,l.jsx)(h.Tag,{color:"red",children:"BLOCK"})}),(0,l.jsx)(q,{value:"MASK",children:(0,l.jsx)(h.Tag,{color:"orange",children:"MASK"})})]})},{title:"Severity Threshold",dataIndex:"severity_threshold",key:"severity_threshold",width:180,render:(e,t)=>(0,l.jsxs)(x.Select,{value:e,onChange:e=>n(t.id,"severity_threshold",e),style:{width:"100%"},children:[(0,l.jsx)(q,{value:"low",children:"Low"}),(0,l.jsx)(q,{value:"medium",children:"Medium"}),(0,l.jsx)(q,{value:"high",children:"High"})]})},{title:"",key:"actions",width:80,render:(e,t)=>(0,l.jsx)(i.Button,{icon:(0,l.jsx)(L.DeleteOutlined,{}),onClick:()=>s(t.id),size:"small",children:"Remove"})}],$=e.filter(e=>!t.some(t=>t.category===e.name));return(0,l.jsxs)(b.Card,{title:(0,l.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",flexWrap:"wrap",gap:8},children:[(0,l.jsx)(D,{level:5,style:{margin:0},children:"Blocked topics"}),(0,l.jsx)(K,{type:"secondary",style:{fontSize:12,fontWeight:400},children:"Select topics to block using keyword and semantic analysis"})]}),size:"small",children:[(0,l.jsxs)("div",{style:{marginBottom:16,display:"flex",gap:8},children:[(0,l.jsx)(x.Select,{placeholder:"Select a content category",value:f||void 0,onChange:y,style:{flex:1},showSearch:!0,optionLabelProp:"label",filterOption:(e,t)=>(t?.label?.toString().toLowerCase()??"").includes(e.toLowerCase()),children:$.map(e=>(0,l.jsx)(q,{value:e.name,label:e.display_name,children:(0,l.jsxs)("div",{children:[(0,l.jsx)("div",{style:{fontWeight:500},children:e.display_name}),(0,l.jsx)("div",{style:{fontSize:"12px",color:"#666",marginTop:"2px"},children:e.description})]})},e.name))}),(0,l.jsx)(i.Button,{type:"primary",onClick:()=>{if(!f)return;let l=e.find(e=>e.name===f);!l||t.some(e=>e.category===f)||(a({id:`category-${Date.now()}`,category:l.name,display_name:l.display_name,action:l.default_action,severity_threshold:"medium"}),y(""),A(""))},disabled:!f,icon:(0,l.jsx)(d.PlusOutlined,{}),children:"Add"})]}),f&&(0,l.jsxs)("div",{style:{marginBottom:16,padding:"12px",background:"#f9f9f9",border:"1px solid #e0e0e0",borderRadius:"4px"},children:[(0,l.jsxs)("div",{style:{marginBottom:8,fontWeight:500,fontSize:"14px"},children:["Preview: ",e.find(e=>e.name===f)?.display_name,v[f]&&(0,l.jsxs)("span",{style:{marginLeft:8,fontSize:"12px",color:"#888",fontWeight:400},children:["(",v[f]?.toUpperCase(),")"]})]}),O?(0,l.jsx)("div",{style:{padding:"16px",textAlign:"center",color:"#888"},children:"Loading content..."}):I?(0,l.jsx)("pre",{style:{background:"#fff",padding:"12px",borderRadius:"4px",overflow:"auto",maxHeight:"300px",maxWidth:"100%",fontSize:"12px",lineHeight:"1.5",margin:0,border:"1px solid #e0e0e0",whiteSpace:"pre-wrap",wordBreak:"break-word"},children:(0,l.jsx)("code",{children:I})}):(0,l.jsx)("div",{style:{padding:"8px",textAlign:"center",color:"#888",fontSize:"12px"},children:"Unable to load category content"})]}),t.length>0?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(P.Table,{dataSource:t,columns:F,pagination:!1,size:"small",rowKey:"id"}),(0,l.jsx)("div",{style:{marginTop:16},children:(0,l.jsx)(G.Collapse,{activeKey:S,onChange:e=>{let t=Array.isArray(e)?e:e?[e]:[],a=new Set(S);t.forEach(e=>{a.has(e)||j[e]||B(e)}),k(t)},ghost:!0,items:t.map(e=>{let t=(v[e.category]||"yaml").toUpperCase();return{key:e.category,label:(0,l.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:8},children:[(0,l.jsx)(z.FileTextOutlined,{}),(0,l.jsxs)("span",{children:["View ",t," for ",e.display_name]})]}),children:N[e.category]?(0,l.jsx)("div",{style:{padding:"16px",textAlign:"center",color:"#888"},children:"Loading content..."}):j[e.category]?(0,l.jsx)("pre",{style:{background:"#f5f5f5",padding:"16px",borderRadius:"4px",overflow:"auto",maxHeight:"400px",fontSize:"12px",lineHeight:"1.5",margin:0},children:(0,l.jsx)("code",{children:j[e.category]})}):(0,l.jsx)("div",{style:{padding:"16px",textAlign:"center",color:"#888"},children:"Content will load when expanded"})}})})})]}):(0,l.jsx)("div",{style:{textAlign:"center",padding:"24px",color:"#888",border:"1px dashed #d9d9d9",borderRadius:"4px"},children:"No blocked topics selected. Add topics to detect and block harmful content."})]})};var U=e.i(790848),J=e.i(28651);let{Title:W,Text:V}=f.Typography,{Option:Y}=x.Select,Q={competitor_intent_type:"airline",brand_self:[],locations:[],policy:{competitor_comparison:"refuse",possible_competitor_comparison:"reframe"},threshold_high:.7,threshold_medium:.45,threshold_low:.3},X=({enabled:e,config:t,onChange:a,accessToken:i})=>{let s=t??Q,[n,o]=(0,r.useState)([]),[d,c]=(0,r.useState)(!1);(0,r.useEffect)(()=>{"airline"===s.competitor_intent_type&&i&&0===n.length&&(c(!0),(0,m.getMajorAirlines)(i).then(e=>o(e.airlines??[])).catch(()=>o([])).finally(()=>c(!1)))},[s.competitor_intent_type,i,n.length]);let p=e=>{a(e,e?{...Q}:null)},g=(t,l)=>{a(e,{...s,[t]:l})},h=(t,l)=>{a(e,{...s,policy:{...s.policy,[t]:l}})},f=(t,l)=>{a(e,{...s,[t]:l.filter(Boolean)})};return e?(0,l.jsxs)(b.Card,{title:(0,l.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[(0,l.jsx)(W,{level:5,style:{margin:0},children:"Competitor Intent Filter"}),(0,l.jsx)(U.Switch,{checked:e,onChange:p})]}),size:"small",children:[(0,l.jsx)(V,{type:"secondary",style:{display:"block",marginBottom:16},children:"Block or reframe competitor comparison questions. Airline type uses major airlines (excluding your brand); generic requires manual competitor list."}),(0,l.jsxs)(u.Form,{layout:"vertical",size:"small",children:[(0,l.jsx)(u.Form.Item,{label:"Type",children:(0,l.jsxs)(x.Select,{value:s.competitor_intent_type,onChange:e=>g("competitor_intent_type",e),style:{width:"100%"},children:[(0,l.jsx)(Y,{value:"airline",children:"Airline (auto-load competitors from IATA)"}),(0,l.jsx)(Y,{value:"generic",children:"Generic (specify competitors manually)"})]})}),(0,l.jsx)(u.Form.Item,{label:"Your Brand (brand_self)",required:!0,help:"airline"===s.competitor_intent_type?"Select your airline from the list (excluded from competitors) or type to add a custom term":"Names/codes users use for your brand",children:(0,l.jsx)(x.Select,{mode:"tags",style:{width:"100%"},placeholder:d?"Loading airlines...":"airline"===s.competitor_intent_type?"Search or select airline, or type to add custom":"Type and press Enter to add",value:s.brand_self,onChange:t=>"airline"===s.competitor_intent_type&&n.length>0?(t=>{let l=t.filter(Boolean),r=[],i=new Set;for(let e of l){let t=n.find(t=>t.match.split("|")[0]?.trim().toLowerCase()===e.toLowerCase());if(t)for(let e of t.match.split("|").map(e=>e.trim().toLowerCase()).filter(Boolean))i.has(e)||(i.add(e),r.push(e));else i.has(e.toLowerCase())||(i.add(e.toLowerCase()),r.push(e))}a(e,{...s,brand_self:r})})(t??[]):f("brand_self",t??[]),tokenSeparators:[","],loading:d,showSearch:!0,filterOption:(e,t)=>(t?.label?.toString().toLowerCase()??"").includes(e.toLowerCase()),optionFilterProp:"label",options:"airline"===s.competitor_intent_type&&n.length>0?n.map(e=>{let t=e.match.split("|")[0]?.trim()??e.id,a=e.match.split("|").map(e=>e.trim().toLowerCase()).filter(Boolean);return{value:t.toLowerCase(),label:`${t}${a.length>1?` (${a.slice(1).join(", ")})`:""}`}}):void 0})}),"airline"===s.competitor_intent_type&&(0,l.jsx)(u.Form.Item,{label:"Locations (optional)",help:"Countries, cities, airports for disambiguation (e.g. qatar, doha)",children:(0,l.jsx)(x.Select,{mode:"tags",style:{width:"100%"},placeholder:"Type and press Enter to add",value:s.locations??[],onChange:e=>f("locations",e??[]),tokenSeparators:[","]})}),"generic"===s.competitor_intent_type&&(0,l.jsx)(u.Form.Item,{label:"Competitors",required:!0,help:"Competitor names to detect (required for generic type)",children:(0,l.jsx)(x.Select,{mode:"tags",style:{width:"100%"},placeholder:"Type and press Enter to add",value:s.competitors??[],onChange:e=>f("competitors",e??[]),tokenSeparators:[","]})}),(0,l.jsx)(u.Form.Item,{label:"Policy: Competitor comparison",children:(0,l.jsxs)(x.Select,{value:s.policy?.competitor_comparison??"refuse",onChange:e=>h("competitor_comparison",e),style:{width:"100%"},children:[(0,l.jsx)(Y,{value:"refuse",children:"Refuse (block request)"}),(0,l.jsx)(Y,{value:"reframe",children:"Reframe (suggest alternative)"})]})}),(0,l.jsx)(u.Form.Item,{label:"Policy: Possible competitor comparison",children:(0,l.jsxs)(x.Select,{value:s.policy?.possible_competitor_comparison??"reframe",onChange:e=>h("possible_competitor_comparison",e),style:{width:"100%"},children:[(0,l.jsx)(Y,{value:"refuse",children:"Refuse (block request)"}),(0,l.jsx)(Y,{value:"reframe",children:"Reframe (suggest alternative to backend LLM)"})]})}),(0,l.jsx)(u.Form.Item,{label:"Confidence thresholds",help:(0,l.jsxs)(l.Fragment,{children:["Classify competitor intent by confidence (0–1). Higher confidence → stronger intent.",(0,l.jsxs)("ul",{style:{marginBottom:0,marginTop:4,paddingLeft:20},children:[(0,l.jsxs)("li",{children:[(0,l.jsx)("strong",{children:"High (≥)"}),': Treat as full competitor comparison → uses "Competitor comparison" policy']}),(0,l.jsxs)("li",{children:[(0,l.jsx)("strong",{children:"Medium (≥)"}),': Treat as possible comparison → uses "Possible competitor comparison" policy']}),(0,l.jsxs)("li",{children:[(0,l.jsx)("strong",{children:"Low (≥)"}),": Log only; allow request. Below Low → allow with no action"]})]}),"Raise thresholds to be more permissive; lower them to be stricter."]}),children:(0,l.jsxs)(j.Space,{wrap:!0,children:[(0,l.jsx)(u.Form.Item,{label:"High",style:{marginBottom:0},help:"e.g. 0.7",children:(0,l.jsx)(J.InputNumber,{min:0,max:1,step:.05,value:s.threshold_high??.7,onChange:e=>g("threshold_high",e??.7),style:{width:80}})}),(0,l.jsx)(u.Form.Item,{label:"Medium",style:{marginBottom:0},help:"e.g. 0.45",children:(0,l.jsx)(J.InputNumber,{min:0,max:1,step:.05,value:s.threshold_medium??.45,onChange:e=>g("threshold_medium",e??.45),style:{width:80}})}),(0,l.jsx)(u.Form.Item,{label:"Low",style:{marginBottom:0},help:"e.g. 0.3",children:(0,l.jsx)(J.InputNumber,{min:0,max:1,step:.05,value:s.threshold_low??.3,onChange:e=>g("threshold_low",e??.3),style:{width:80}})})]})})]})]}):(0,l.jsx)(b.Card,{title:(0,l.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[(0,l.jsx)(W,{level:5,style:{margin:0},children:"Competitor Intent Filter"}),(0,l.jsx)(U.Switch,{checked:!1,onChange:p})]}),size:"small",children:(0,l.jsx)(V,{type:"secondary",children:"Block or reframe competitor comparison questions. When enabled, airline type auto-loads competitors from IATA; generic type requires manual competitor list."})})},{Title:Z,Text:ee}=f.Typography,et=({prebuiltPatterns:e,categories:t,selectedPatterns:a,blockedWords:s,onPatternAdd:n,onPatternRemove:o,onPatternActionChange:c,onBlockedWordAdd:u,onBlockedWordRemove:p,onBlockedWordUpdate:g,onFileUpload:x,accessToken:h,showStep:f,contentCategories:w=[],selectedContentCategories:N=[],onContentCategoryAdd:S,onContentCategoryRemove:k,onContentCategoryUpdate:A,pendingCategorySelection:O,onPendingCategorySelectionChange:P,competitorIntentEnabled:L=!1,competitorIntentConfig:B=null,onCompetitorIntentChange:F})=>{let[E,M]=(0,r.useState)(!1),[G,z]=(0,r.useState)(!1),[D,K]=(0,r.useState)(!1),[q,U]=(0,r.useState)(""),[J,W]=(0,r.useState)("BLOCK"),[V,Y]=(0,r.useState)(""),[Q,et]=(0,r.useState)(""),[ea,el]=(0,r.useState)("BLOCK"),[er,ei]=(0,r.useState)(""),[es,en]=(0,r.useState)("BLOCK"),[eo,ed]=(0,r.useState)(""),[ec,em]=(0,r.useState)(!1),eu=async e=>{em(!0);try{let t=await e.text();if(h){let e=await (0,m.validateBlockedWordsFile)(h,t);if(e.valid)x&&x(t),y.default.success(e.message||"File uploaded successfully");else{let t=e.error||e.errors&&e.errors.join(", ")||"Invalid file";y.default.error(`Validation failed: ${t}`)}}}catch(e){y.default.error(`Failed to upload file: ${e}`)}finally{em(!1)}return!1};return(0,l.jsxs)("div",{className:"space-y-6",children:[!f&&(0,l.jsx)("div",{children:(0,l.jsx)(ee,{type:"secondary",children:"Configure patterns, keywords, and content categories to detect and filter sensitive information in requests and responses."})}),(!f||"patterns"===f)&&(0,l.jsxs)(b.Card,{title:(0,l.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[(0,l.jsx)(Z,{level:5,style:{margin:0},children:"Pattern Detection"}),(0,l.jsx)(ee,{type:"secondary",style:{fontSize:14,fontWeight:400},children:"Detect sensitive information using regex patterns (SSN, credit cards, API keys, etc.)"})]}),size:"small",children:[(0,l.jsx)("div",{style:{marginBottom:16},children:(0,l.jsxs)(j.Space,{children:[(0,l.jsx)(i.Button,{type:"primary",onClick:()=>M(!0),icon:(0,l.jsx)(d.PlusOutlined,{}),children:"Add prebuilt pattern"}),(0,l.jsx)(i.Button,{onClick:()=>K(!0),icon:(0,l.jsx)(d.PlusOutlined,{}),children:"Add custom regex"})]})}),(0,l.jsx)($,{patterns:a,onActionChange:c,onRemove:o})]}),(!f||"keywords"===f)&&(0,l.jsxs)(b.Card,{title:(0,l.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[(0,l.jsx)(Z,{level:5,style:{margin:0},children:"Blocked Keywords"}),(0,l.jsx)(ee,{type:"secondary",style:{fontSize:14,fontWeight:400},children:"Block or mask specific sensitive terms and phrases"})]}),size:"small",children:[(0,l.jsx)("div",{style:{marginBottom:16},children:(0,l.jsxs)(j.Space,{children:[(0,l.jsx)(i.Button,{type:"primary",onClick:()=>z(!0),icon:(0,l.jsx)(d.PlusOutlined,{}),children:"Add keyword"}),(0,l.jsx)(_.Upload,{beforeUpload:eu,accept:".yaml,.yml",showUploadList:!1,children:(0,l.jsx)(i.Button,{icon:(0,l.jsx)(v.UploadOutlined,{}),loading:ec,children:"Upload YAML file"})})]})}),(0,l.jsx)(R,{keywords:s,onActionChange:g,onRemove:p})]}),(!f||"competitor_intent"===f||"categories"===f)&&F&&(0,l.jsx)(X,{enabled:L,config:B,onChange:F,accessToken:h}),(!f||"categories"===f)&&w.length>0&&S&&k&&A&&(0,l.jsx)(H,{availableCategories:w,selectedCategories:N,onCategoryAdd:S,onCategoryRemove:k,onCategoryUpdate:A,accessToken:h,pendingSelection:O,onPendingSelectionChange:P}),(0,l.jsx)(C,{visible:E,prebuiltPatterns:e,categories:t,selectedPatternName:q,patternAction:J,onPatternNameChange:U,onActionChange:e=>W(e),onAdd:()=>{if(!q)return void y.default.error("Please select a pattern");let t=e.find(e=>e.name===q);n({id:`pattern-${Date.now()}`,type:"prebuilt",name:q,display_name:t?.display_name,action:J}),M(!1),U(""),W("BLOCK")},onCancel:()=>{M(!1),U(""),W("BLOCK")}}),(0,l.jsx)(I,{visible:D,patternName:V,patternRegex:Q,patternAction:ea,onNameChange:Y,onRegexChange:et,onActionChange:e=>el(e),onAdd:()=>{V&&Q?(n({id:`custom-${Date.now()}`,type:"custom",name:V,pattern:Q,action:ea}),K(!1),Y(""),et(""),el("BLOCK")):y.default.error("Please provide pattern name and regex")},onCancel:()=>{K(!1),Y(""),et(""),el("BLOCK")}}),(0,l.jsx)(T,{visible:G,keyword:er,action:es,description:eo,onKeywordChange:ei,onActionChange:e=>en(e),onDescriptionChange:ed,onAdd:()=>{er?(u({id:`word-${Date.now()}`,keyword:er,action:es,description:eo||void 0}),z(!1),ei(""),ed(""),en("BLOCK")):y.default.error("Please enter a keyword")},onCancel:()=>{z(!1),ei(""),ed(""),en("BLOCK")}})]})};var ea=e.i(555987),el=((t={}).PresidioPII="Presidio PII",t.Bedrock="Bedrock Guardrail",t.Lakera="Lakera",t);let er={},ei=e=>{let t={};return t.PresidioPII="Presidio PII",t.Bedrock="Bedrock Guardrail",t.Lakera="Lakera",t.LlmAsAJudge="LiteLLM LLM as a Judge",Object.entries(e).forEach(([e,a])=>{a&&"object"==typeof a&&"ui_friendly_name"in a&&(t[e.split("_").map((e,t)=>e.charAt(0).toUpperCase()+e.slice(1)).join("")]=a.ui_friendly_name)}),er=t,t},es=()=>Object.keys(er).length>0?er:el,en={PresidioPII:"presidio",Bedrock:"bedrock",Lakera:"lakera_v2",LitellmContentFilter:"litellm_content_filter",ToolPermission:"tool_permission",BlockCodeExecution:"block_code_execution",Promptguard:"promptguard",LlmAsAJudge:"llm_as_a_judge",Xecguard:"xecguard",QostodianNexus:"qostodian_nexus",Repelloai:"repelloai"},eo=e=>{Object.entries(e).forEach(([e,t])=>{t&&"object"==typeof t&&"ui_friendly_name"in t&&(en[e.split("_").map((e,t)=>e.charAt(0).toUpperCase()+e.slice(1)).join("")]=e)})},ed=e=>!!e&&"Presidio PII"===es()[e],ec=e=>!!e&&"LiteLLM Content Filter"===es()[e],em=e=>!!e&&"llm_as_a_judge"===en[e],eu="/ui/assets/logos/",ep={"Zscaler AI Guard":`${eu}zscaler.svg`,"Presidio PII":`${eu}microsoft_azure.svg`,"Bedrock Guardrail":`${eu}bedrock.svg`,Lakera:`${eu}lakeraai.jpeg`,"Azure Content Safety Prompt Shield":`${eu}microsoft_azure.svg`,"Azure Content Safety Text Moderation":`${eu}microsoft_azure.svg`,"Aporia AI":`${eu}aporia.png`,"PANW Prisma AIRS":`${eu}palo_alto_networks.jpeg`,"Cisco AI Defense":`${eu}cisco.png`,"Noma Security":`${eu}noma_security.png`,"Javelin Guardrails":`${eu}javelin.png`,"Pillar Guardrail":`${eu}pillar.jpeg`,"Google Cloud Model Armor":`${eu}google.svg`,"Guardrails AI":`${eu}guardrails_ai.jpeg`,"Lasso Guardrail":`${eu}lasso.png`,"Pangea Guardrail":`${eu}pangea.png`,"AIM Guardrail":`${eu}aim_security.jpeg`,"Cato Networks Guardrail":`${eu}cato_networks.svg`,"OpenAI Moderation":`${eu}openai_small.svg`,EnkryptAI:`${eu}enkrypt_ai.avif`,"Prompt Security":`${eu}prompt_security.png`,PromptGuard:`${eu}promptguard.svg`,XecGuard:`${eu}xecguard.svg`,"LiteLLM Content Filter":`${eu}litellm_logo.jpg`,"LiteLLM LLM as a Judge":`${eu}litellm_logo.jpg`,Akto:`${eu}akto.svg`,"Qostodian Nexus":`${eu}qohash.jpg`,"RepelloAI Argus":`${eu}repelloai.png`},eg=e=>{if(!e)return{logo:"",displayName:"-"};let t=Object.keys(en).find(t=>en[t].toLowerCase()===e.toLowerCase());if(!t)return{logo:"",displayName:e};let a=es()[t];return{logo:(0,ea.resolveLogoSrc)(ep[a])??"",displayName:a||e}};function ex(e){return!0===e?"yes":!1===e?"no":"inherit"}function eh(e){return!0===e?"yes":!1===e?"no":"inherit"}var ef=e.i(435451);let{Title:ey}=f.Typography,ej=({field:e,fieldKey:t,fullFieldKey:a,value:s})=>{let[n,o]=r.default.useState([]),[d,c]=r.default.useState(e.dict_key_options||[]);return r.default.useEffect(()=>{if(s&&"object"==typeof s){let t=Object.keys(s);o(t.map(e=>({key:e,id:`${e}_${Date.now()}_${Math.random()}`}))),c((e.dict_key_options||[]).filter(e=>!t.includes(e)))}},[s,e.dict_key_options]),(0,l.jsxs)("div",{className:"space-y-3",children:[n.map(t=>(0,l.jsxs)("div",{className:"flex items-center space-x-3 p-3 border rounded-lg",children:[(0,l.jsx)("div",{className:"w-24 font-medium text-sm",children:t.key}),(0,l.jsx)("div",{className:"flex-1",children:(0,l.jsx)(u.Form.Item,{name:Array.isArray(a)?[...a,t.key]:[a,t.key],style:{marginBottom:0},initialValue:s&&"object"==typeof s?s[t.key]:void 0,normalize:"number"===e.dict_value_type?e=>{if(null==e||""===e)return;let t=Number(e);return isNaN(t)?e:t}:void 0,children:"number"===e.dict_value_type?(0,l.jsx)(ef.default,{step:1,width:200,placeholder:`Enter ${t.key} value`}):"boolean"===e.dict_value_type?(0,l.jsxs)(x.Select,{placeholder:`Select ${t.key} value`,children:[(0,l.jsx)(x.Select.Option,{value:!0,children:"True"}),(0,l.jsx)(x.Select.Option,{value:!1,children:"False"})]}):(0,l.jsx)(p.Input,{placeholder:`Enter ${t.key} value`})})}),(0,l.jsx)(i.Button,{type:"text",danger:!0,size:"small",onClick:()=>{var e,a;return e=t.id,a=t.key,void(o(n.filter(t=>t.id!==e)),c([...d,a].sort()))},children:"Remove"})]},t.id)),d.length>0&&(0,l.jsxs)("div",{className:"flex items-center space-x-3 mt-2",children:[(0,l.jsx)(x.Select,{placeholder:"Select category to configure",style:{width:200},onSelect:e=>e&&void(!e||(o([...n,{key:e,id:`${e}_${Date.now()}`}]),c(d.filter(t=>t!==e)))),value:void 0,children:d.map(e=>(0,l.jsx)(x.Select.Option,{value:e,children:e},e))}),(0,l.jsx)("span",{className:"text-sm text-gray-500",children:"Select a category to add threshold configuration"})]})]})},e_=({optionalParams:e,parentFieldKey:t,values:a})=>e.fields&&0!==Object.keys(e.fields).length?(0,l.jsxs)("div",{className:"guardrail-optional-params",children:[(0,l.jsxs)("div",{className:"mb-8 pb-4 border-b border-gray-100",children:[(0,l.jsx)(ey,{level:3,className:"mb-2 font-semibold text-gray-900",children:"Optional Parameters"}),(0,l.jsx)("p",{className:"text-gray-600 text-sm",children:e.description||"Configure additional settings for this guardrail provider"})]}),(0,l.jsx)("div",{className:"space-y-8",children:Object.entries(e.fields).map(([e,r])=>{let i,s;return i=`${t}.${e}`,s=a?.[e],"dict"===r.type&&r.dict_key_options?(0,l.jsxs)("div",{className:"mb-8 p-6 bg-gray-50 rounded-lg border border-gray-200",children:[(0,l.jsx)("div",{className:"mb-4 font-medium text-gray-900 text-base",children:e}),(0,l.jsx)("p",{className:"text-sm text-gray-600 mb-4",children:r.description}),(0,l.jsx)(ej,{field:r,fieldKey:e,fullFieldKey:[t,e],value:s})]},i):(0,l.jsx)("div",{className:"mb-8 p-6 bg-white rounded-lg border border-gray-200 shadow-xs",children:(0,l.jsx)(u.Form.Item,{name:[t,e],label:(0,l.jsxs)("div",{className:"mb-2",children:[(0,l.jsx)("div",{className:"font-medium text-gray-900 text-base",children:e}),(0,l.jsx)("p",{className:"text-sm text-gray-600 mt-1",children:r.description})]}),rules:r.required?[{required:!0,message:`${e} is required`}]:void 0,className:"mb-0",initialValue:void 0!==s?s:r.default_value,normalize:"number"===r.type?e=>{if(null==e||""===e)return;let t=Number(e);return isNaN(t)?e:t}:void 0,children:"select"===r.type&&r.options?(0,l.jsx)(x.Select,{placeholder:r.description,children:r.options.map(e=>(0,l.jsx)(x.Select.Option,{value:e,children:e},e))}):"multiselect"===r.type&&r.options?(0,l.jsx)(x.Select,{mode:"multiple",placeholder:r.description,children:r.options.map(e=>(0,l.jsx)(x.Select.Option,{value:e,children:e},e))}):"bool"===r.type||"boolean"===r.type?(0,l.jsxs)(x.Select,{placeholder:r.description,children:[(0,l.jsx)(x.Select.Option,{value:!0,children:"True"}),(0,l.jsx)(x.Select.Option,{value:!1,children:"False"})]}):"number"===r.type?(0,l.jsx)(ef.default,{step:1,width:400,placeholder:r.description}):e.includes("password")||e.includes("secret")||e.includes("key")?(0,l.jsx)(p.Input.Password,{placeholder:r.description}):(0,l.jsx)(p.Input,{placeholder:r.description})})},i)})})]}):null;var eb=e.i(482725),ev=e.i(850627);let ew=({selectedProvider:e,accessToken:t,providerParams:a=null,value:i=null})=>{let[s,n]=(0,r.useState)(!1),[o,d]=(0,r.useState)(a),[c,g]=(0,r.useState)(null);if((0,r.useEffect)(()=>{if(a)return void d(a);let e=async()=>{if(t){n(!0),g(null);try{let e=await (0,m.getGuardrailProviderSpecificParams)(t);d(e),ei(e),eo(e)}catch(e){console.error("Error fetching provider params:",e),g("Failed to load provider parameters")}finally{n(!1)}}};a||e()},[t,a]),!e)return null;if(s)return(0,l.jsx)(eb.Spin,{tip:"Loading provider parameters..."});if(c)return(0,l.jsx)("div",{className:"text-red-500",children:c});let h=en[e]?.toLowerCase(),f=o&&o[h];if(!f||0===Object.keys(f).length)return(0,l.jsx)("div",{children:"No configuration fields available for this provider."});let y=new Set(["patterns","blocked_words","blocked_words_file","categories","severity_threshold","pattern_redaction_format","keyword_redaction_tag"]),j=ec(e),_=(e,t="",a)=>Object.entries(e).map(([e,r])=>{let s=t?`${t}.${e}`:e,n=a?a[e]:i?.[e];if("ui_friendly_name"===e||"optional_params"===e&&"nested"===r.type&&r.fields||j&&y.has(e))return null;if("nested"===r.type&&r.fields)return(0,l.jsxs)("div",{children:[(0,l.jsx)("div",{className:"mb-2 font-medium",children:e}),(0,l.jsx)("div",{className:"ml-4 border-l-2 border-gray-200 pl-4",children:_(r.fields,s,n)})]},s);let o=void 0!==n?n:r.default_value??("percentage"===r.type?.5:void 0);return(0,l.jsx)(u.Form.Item,{name:s,label:e,tooltip:r.description,rules:r.required?[{required:!0,message:`${e} is required`}]:void 0,initialValue:o,children:"select"===r.type&&r.options?(0,l.jsx)(x.Select,{placeholder:r.description,defaultValue:n||r.default_value,children:r.options.map(e=>(0,l.jsx)(x.Select.Option,{value:e,children:e},e))}):"multiselect"===r.type&&r.options?(0,l.jsx)(x.Select,{mode:"multiple",placeholder:r.description,defaultValue:n||r.default_value,children:r.options.map(e=>(0,l.jsx)(x.Select.Option,{value:e,children:e},e))}):"bool"===r.type||"boolean"===r.type?(0,l.jsxs)(x.Select,{placeholder:r.description,children:[(0,l.jsx)(x.Select.Option,{value:!0,children:"True"}),(0,l.jsx)(x.Select.Option,{value:!1,children:"False"})]}):"percentage"===r.type&&null!=r.min&&null!=r.max?(0,l.jsx)(ev.Slider,{min:r.min,max:r.max,step:r.step??.1,marks:{[r.min]:"0%",[(r.min+r.max)/2]:"50%",[r.max]:"100%"}}):"number"===r.type?(0,l.jsx)(ef.default,{step:1,width:400,placeholder:r.description,defaultValue:void 0!==n?Number(n):void 0}):e.includes("password")||e.includes("secret")||e.includes("key")?(0,l.jsx)(p.Input.Password,{placeholder:r.description,defaultValue:n||""}):(0,l.jsx)(p.Input,{placeholder:r.description,defaultValue:n||""})},s)});return(0,l.jsx)(l.Fragment,{children:_(f)})};var eN=e.i(592968),eC=e.i(750113);let eS=({availableModels:e,form:t})=>(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)("div",{style:{background:"#f6ffed",border:"1px solid #b7eb8f",borderRadius:6,padding:"10px 14px",marginBottom:16,fontSize:13,color:"#389e0d"},children:["After each LLM response, the ",(0,l.jsx)("strong",{children:"Judge Model"})," scores it 0–100 against your criteria. If the weighted average falls below the threshold, the response is blocked (or logged)."]}),(0,l.jsx)(u.Form.Item,{name:"judge_model",label:(0,l.jsxs)("span",{children:["Judge Model ",(0,l.jsx)(eN.Tooltip,{title:"The LLM that reads each response and grades it. Pick a capable model — it never sees end-user data beyond what the LLM returned.",children:(0,l.jsx)(eC.QuestionCircleOutlined,{style:{color:"#8c8c8c"}})})]}),rules:[{required:!0,message:"Select a judge model"}],children:(0,l.jsx)(x.Select,{showSearch:!0,placeholder:"Select a model",options:e.map(e=>({label:e,value:e}))})}),(0,l.jsx)(u.Form.Item,{name:"overall_threshold",label:(0,l.jsxs)("span",{children:["Minimum Score to Pass ",(0,l.jsx)(eN.Tooltip,{title:"0–100. If the weighted average of criterion scores falls below this, the guardrail triggers. 80 is a good default.",children:(0,l.jsx)(eC.QuestionCircleOutlined,{style:{color:"#8c8c8c"}})})]}),initialValue:80,children:(0,l.jsx)(J.InputNumber,{min:0,max:100,addonAfter:"/ 100",style:{width:"100%"}})}),(0,l.jsx)(u.Form.Item,{name:"on_failure",label:(0,l.jsxs)("span",{children:["On Failure ",(0,l.jsx)(eN.Tooltip,{title:"Block: return HTTP 422 when the score is too low. Log: record the result but let the response through.",children:(0,l.jsx)(eC.QuestionCircleOutlined,{style:{color:"#8c8c8c"}})})]}),initialValue:"block",children:(0,l.jsxs)(x.Select,{children:[(0,l.jsx)(x.Select.Option,{value:"block",children:"Block (return 422)"}),(0,l.jsx)(x.Select.Option,{value:"log",children:"Log only"})]})}),(0,l.jsx)(u.Form.Item,{label:(0,l.jsxs)("span",{children:["Evaluation Criteria ",(0,l.jsx)(eN.Tooltip,{title:"Each criterion is something the judge checks. Weights must add up to 100%.",children:(0,l.jsx)(eC.QuestionCircleOutlined,{style:{color:"#8c8c8c"}})})]}),children:(0,l.jsx)(u.Form.List,{name:"criteria",initialValue:[{name:"",weight:100,description:""}],children:(e,{add:a,remove:r})=>(0,l.jsxs)(l.Fragment,{children:[e.map(({key:e,name:t,...a})=>(0,l.jsxs)("div",{style:{border:"1px solid #f0f0f0",borderRadius:6,padding:"12px 12px 0",marginBottom:8},children:[(0,l.jsxs)("div",{style:{display:"flex",gap:8,alignItems:"flex-end"},children:[(0,l.jsx)(u.Form.Item,{...a,name:[t,"name"],rules:[{required:!0,message:"Enter criterion name"}],style:{flex:2,marginBottom:8},children:(0,l.jsx)(p.Input,{placeholder:"Criterion name (e.g. Policy accuracy)"})}),(0,l.jsx)(u.Form.Item,{...a,name:[t,"weight"],label:(0,l.jsx)(eN.Tooltip,{title:"How much this criterion counts toward the final score. All weights must add up to 100%.",children:(0,l.jsxs)("span",{style:{fontSize:12,color:"#595959"},children:["Weight ",(0,l.jsx)(eC.QuestionCircleOutlined,{style:{color:"#bfbfbf"}})]})}),rules:[{required:!0,message:"Enter weight"}],style:{flex:1,marginBottom:8},children:(0,l.jsx)(J.InputNumber,{min:0,max:100,addonAfter:"%",style:{width:"100%"},placeholder:"e.g. 50"})}),(0,l.jsx)("div",{style:{marginBottom:8},children:(0,l.jsx)(i.Button,{type:"text",danger:!0,size:"small",onClick:()=>r(t),children:"×"})})]}),(0,l.jsx)(u.Form.Item,{...a,name:[t,"description"],rules:[{required:!0,message:"Describe what to check"}],style:{marginBottom:8},children:(0,l.jsx)(p.Input,{placeholder:"What should the judge check for this criterion?"})})]},e)),(0,l.jsx)(i.Button,{type:"dashed",block:!0,style:{marginTop:4},onClick:()=>a({name:"",weight:0,description:""}),icon:(0,l.jsx)(d.PlusOutlined,{}),children:"Add Criterion"}),e.length>0&&(0,l.jsx)(u.Form.Item,{shouldUpdate:!0,noStyle:!0,children:()=>{let e=(t.getFieldValue("criteria")||[]).reduce((e,t)=>e+(Number(t?.weight)||0),0),a=100===e;return(0,l.jsxs)("div",{style:{marginTop:6,fontSize:12,color:a?"#52c41a":"#faad14"},children:["Weights total: ",e,"%",a?" ✓":" — must add up to 100%"]})}})]})})})]});var ek=e.i(536916),eI=e.i(149192),eA=e.i(741585),eA=eA,eO=e.i(724154);e.i(247167);var eT=e.i(931067);let eP={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M880.1 154H143.9c-24.5 0-39.8 26.7-27.5 48L349 597.4V838c0 17.7 14.2 32 31.8 32h262.4c17.6 0 31.8-14.3 31.8-32V597.4L907.7 202c12.2-21.3-3.1-48-27.6-48zM603.4 798H420.6V642h182.9v156zm9.6-236.6l-9.5 16.6h-183l-9.5-16.6L212.7 226h598.6L613 561.4z"}}]},name:"filter",theme:"outlined"};var eL=e.i(9583),eB=r.forwardRef(function(e,t){return r.createElement(eL.default,(0,eT.default)({},e,{ref:t,icon:eP}))});let{Text:eF}=f.Typography,{Option:e$}=x.Select,eE=({categories:e,selectedCategories:t,onChange:a})=>(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{className:"flex items-center mb-2",children:[(0,l.jsx)(eB,{className:"text-gray-500 mr-1"}),(0,l.jsx)(eF,{className:"text-gray-500 font-medium",children:"Filter by category"})]}),(0,l.jsx)(x.Select,{mode:"multiple",placeholder:"Select categories to filter by",style:{width:"100%"},onChange:a,value:t,allowClear:!0,showSearch:!0,optionFilterProp:"children",className:"mb-4",tagRender:e=>(0,l.jsx)(h.Tag,{color:"blue",closable:e.closable,onClose:e.onClose,className:"mr-2 mb-2",children:e.label}),children:e.map(e=>(0,l.jsx)(e$,{value:e.category,children:e.category},e.category))})]}),eM=({onSelectAll:e,onUnselectAll:t,hasSelectedEntities:a})=>(0,l.jsxs)("div",{className:"bg-gray-50 p-5 rounded-lg mb-6 border border-gray-200 shadow-xs",children:[(0,l.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)(eF,{strong:!0,className:"text-gray-700 text-base",children:"Quick Actions"}),(0,l.jsx)(eN.Tooltip,{title:"Apply action to all PII types at once",children:(0,l.jsx)("div",{className:"ml-2 text-gray-400 cursor-help text-xs",children:"ⓘ"})})]}),(0,l.jsx)(i.Button,{color:"danger",variant:"outlined",onClick:t,disabled:!a,icon:(0,l.jsx)(eI.CloseOutlined,{}),children:"Unselect All"})]}),(0,l.jsxs)("div",{className:"grid grid-cols-2 gap-4",children:[(0,l.jsx)(i.Button,{color:"primary",variant:"outlined",onClick:()=>e("MASK"),className:"h-10",block:!0,icon:(0,l.jsx)(eA.default,{}),children:"Select All & Mask"}),(0,l.jsx)(i.Button,{color:"danger",variant:"outlined",onClick:()=>e("BLOCK"),className:"h-10 hover:bg-red-100",block:!0,icon:(0,l.jsx)(eO.StopOutlined,{}),children:"Select All & Block"})]})]}),eR=({entities:e,selectedEntities:t,selectedActions:a,actions:r,onEntitySelect:i,onActionSelect:s,entityToCategoryMap:n})=>(0,l.jsxs)("div",{className:"border rounded-lg overflow-hidden shadow-xs",children:[(0,l.jsxs)("div",{className:"bg-gray-50 px-5 py-3 border-b flex",children:[(0,l.jsx)(eF,{strong:!0,className:"flex-1 text-gray-700",children:"PII Type"}),(0,l.jsx)(eF,{strong:!0,className:"w-32 text-right text-gray-700",children:"Action"})]}),(0,l.jsx)("div",{className:"max-h-[400px] overflow-y-auto",children:0===e.length?(0,l.jsx)("div",{className:"py-10 text-center text-gray-500",children:"No PII types match your filter criteria"}):e.map(e=>(0,l.jsxs)("div",{className:`px-5 py-3 flex items-center justify-between hover:bg-gray-50 border-b ${t.includes(e)?"bg-blue-50":""}`,children:[(0,l.jsxs)("div",{className:"flex items-center flex-1",children:[(0,l.jsx)(ek.Checkbox,{checked:t.includes(e),onChange:()=>i(e),className:"mr-3"}),(0,l.jsx)(eF,{className:t.includes(e)?"font-medium text-gray-900":"text-gray-700",children:e.replace(/_/g," ")}),n.get(e)&&(0,l.jsx)(h.Tag,{className:"ml-2 text-xs",color:"blue",children:n.get(e)})]}),(0,l.jsx)("div",{className:"w-32",children:(0,l.jsx)(x.Select,{value:t.includes(e)&&a[e]||"MASK",onChange:t=>s(e,t),style:{width:120},disabled:!t.includes(e),className:`${!t.includes(e)?"opacity-50":""}`,dropdownMatchSelectWidth:!1,children:r.map(e=>(0,l.jsx)(e$,{value:e,children:(0,l.jsxs)("div",{className:"flex items-center",children:[(e=>{switch(e){case"MASK":return(0,l.jsx)(eA.default,{style:{marginRight:4}});case"BLOCK":return(0,l.jsx)(eO.StopOutlined,{style:{marginRight:4}});default:return null}})(e),e]})},e))})})]},e))})]}),{Title:eG,Text:ez}=f.Typography,eD=({entities:e,actions:t,selectedEntities:a,selectedActions:i,onEntitySelect:s,onActionSelect:n,entityCategories:o=[]})=>{let[d,c]=(0,r.useState)([]),m=new Map;o.forEach(e=>{e.entities.forEach(t=>{m.set(t,e.category)})});let u=e.filter(e=>0===d.length||d.includes(m.get(e)||""));return(0,l.jsxs)("div",{className:"pii-configuration",children:[(0,l.jsxs)("div",{className:"flex justify-between items-center mb-5",children:[(0,l.jsx)("div",{className:"flex items-center",children:(0,l.jsx)(eG,{level:4,className:"m-0! font-semibold text-gray-800",children:"Configure PII Protection"})}),(0,l.jsxs)(ez,{className:"text-gray-500",children:[a.length," items selected"]})]}),(0,l.jsxs)("div",{className:"mb-6",children:[(0,l.jsx)(eE,{categories:o,selectedCategories:d,onChange:c}),(0,l.jsx)(eM,{onSelectAll:t=>{e.forEach(e=>{a.includes(e)||s(e),n(e,t)})},onUnselectAll:()=>{a.forEach(e=>{s(e)})},hasSelectedEntities:a.length>0})]}),(0,l.jsx)(eR,{entities:u,selectedEntities:a,selectedActions:i,actions:t,onEntitySelect:s,onActionSelect:n,entityToCategoryMap:m})]})};var eK=e.i(304967),eq=e.i(599724),eH=e.i(312361),eU=e.i(21548),eJ=e.i(827252);let eW={rules:[],default_action:"deny",on_disallowed_action:"block",violation_message_template:""},eV=({value:e,onChange:t,disabled:a=!1})=>{let r={...eW,...e||{},rules:e?.rules?[...e.rules]:[]},s=e=>{let a={...r,...e};t?.(a)},n=(e,t)=>{s({rules:r.rules.map((a,l)=>l===e?{...a,...t}:a)})},o=(e,t)=>{let a=r.rules[e];if(!a)return;let l=Object.entries(a.allowed_param_patterns||{});t(l);let i={};l.forEach(([e,t])=>{i[e]=t}),n(e,{allowed_param_patterns:Object.keys(i).length>0?i:void 0})};return(0,l.jsxs)(eK.Card,{children:[(0,l.jsxs)("div",{className:"flex items-center justify-between",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)(eq.Text,{className:"text-lg font-semibold",children:"LiteLLM Tool Permission Guardrail"}),(0,l.jsx)(eq.Text,{className:"text-sm text-gray-500",children:"Provide regex patterns (e.g., ^mcp__github_.*$) for tool names or types and optionally constrain payload fields."})]}),!a&&(0,l.jsx)(i.Button,{icon:(0,l.jsx)(d.PlusOutlined,{}),type:"primary",onClick:()=>{s({rules:[...r.rules,{id:`rule_${Math.random().toString(36).slice(2,8)}`,decision:"allow",allowed_param_patterns:void 0}]})},className:"bg-blue-600! text-white! hover:bg-blue-500!",children:"Add Rule"})]}),(0,l.jsx)(eH.Divider,{}),0===r.rules.length?(0,l.jsx)(eU.Empty,{description:"No tool rules added yet"}):(0,l.jsx)("div",{className:"space-y-4",children:r.rules.map((e,t)=>{let d;return(0,l.jsxs)(eK.Card,{className:"bg-gray-50",children:[(0,l.jsxs)("div",{className:"flex items-center justify-between mb-3",children:[(0,l.jsxs)(eq.Text,{className:"font-semibold",children:["Rule ",t+1]}),(0,l.jsx)(i.Button,{icon:(0,l.jsx)(L.DeleteOutlined,{}),danger:!0,type:"text",disabled:a,onClick:()=>{s({rules:r.rules.filter((e,a)=>a!==t)})},children:"Remove"})]}),(0,l.jsxs)("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-2",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)(eq.Text,{className:"text-sm font-medium",children:"Rule ID"}),(0,l.jsx)(p.Input,{disabled:a,placeholder:"unique_rule_id",value:e.id,onChange:e=>n(t,{id:e.target.value})})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(eq.Text,{className:"text-sm font-medium",children:"Tool Name (optional)"}),(0,l.jsx)(p.Input,{disabled:a,placeholder:"^mcp__github_.*$",value:e.tool_name??"",onChange:e=>n(t,{tool_name:""===e.target.value.trim()?void 0:e.target.value})})]})]}),(0,l.jsx)("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-2 mt-4",children:(0,l.jsxs)("div",{children:[(0,l.jsx)(eq.Text,{className:"text-sm font-medium",children:"Tool Type (optional)"}),(0,l.jsx)(p.Input,{disabled:a,placeholder:"^function$",value:e.tool_type??"",onChange:e=>n(t,{tool_type:""===e.target.value.trim()?void 0:e.target.value})})]})}),(0,l.jsxs)("div",{className:"mt-4 flex flex-col gap-2",children:[(0,l.jsx)(eq.Text,{className:"text-sm font-medium",children:"Decision"}),(0,l.jsxs)(x.Select,{disabled:a,value:e.decision,style:{width:200},onChange:e=>n(t,{decision:e}),children:[(0,l.jsx)(x.Select.Option,{value:"allow",children:"Allow"}),(0,l.jsx)(x.Select.Option,{value:"deny",children:"Deny"})]})]}),(0,l.jsx)("div",{className:"mt-4",children:0===(d=Object.entries(e.allowed_param_patterns||{})).length?(0,l.jsx)(i.Button,{disabled:a,size:"small",onClick:()=>n(t,{allowed_param_patterns:{"":""}}),children:"+ Restrict tool arguments (optional)"}):(0,l.jsxs)("div",{className:"space-y-2",children:[(0,l.jsx)(eq.Text,{className:"text-sm text-gray-600",children:"Argument constraints (dot or array paths)"}),d.map(([r,s],n)=>(0,l.jsxs)(j.Space,{align:"start",children:[(0,l.jsx)(p.Input,{disabled:a,placeholder:"messages[0].content",value:r,onChange:e=>{var a;return a=e.target.value,void o(t,e=>{if(!e[n])return;let[,t]=e[n];e[n]=[a,t]})}}),(0,l.jsx)(p.Input,{disabled:a,placeholder:"^email@.*$",value:s,onChange:e=>{var a;return a=e.target.value,void o(t,e=>{if(!e[n])return;let[t]=e[n];e[n]=[t,a]})}}),(0,l.jsx)(i.Button,{disabled:a,icon:(0,l.jsx)(L.DeleteOutlined,{}),danger:!0,onClick:()=>o(t,e=>{e.splice(n,1)})})]},`${e.id||t}-${n}`)),(0,l.jsx)(i.Button,{disabled:a,size:"small",onClick:()=>n(t,{allowed_param_patterns:{...e.allowed_param_patterns||{},"":""}}),children:"+ Add another constraint"})]})})]},e.id||t)})}),(0,l.jsx)(eH.Divider,{}),(0,l.jsxs)("div",{className:"grid gap-4 md:grid-cols-2",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)(eq.Text,{className:"text-sm font-medium",children:"Default action"}),(0,l.jsxs)(x.Select,{disabled:a,value:r.default_action,onChange:e=>s({default_action:e}),children:[(0,l.jsx)(x.Select.Option,{value:"allow",children:"Allow"}),(0,l.jsx)(x.Select.Option,{value:"deny",children:"Deny"})]})]}),(0,l.jsxs)("div",{children:[(0,l.jsxs)(eq.Text,{className:"text-sm font-medium flex items-center gap-1",children:["On disallowed action",(0,l.jsx)(eN.Tooltip,{title:"Block returns an error when a forbidden tool is invoked. Rewrite strips the tool call but lets the rest of the response continue.",children:(0,l.jsx)(eJ.InfoCircleOutlined,{})})]}),(0,l.jsxs)(x.Select,{disabled:a,value:r.on_disallowed_action,onChange:e=>s({on_disallowed_action:e}),children:[(0,l.jsx)(x.Select.Option,{value:"block",children:"Block"}),(0,l.jsx)(x.Select.Option,{value:"rewrite",children:"Rewrite"})]})]})]}),(0,l.jsxs)("div",{className:"mt-4",children:[(0,l.jsx)(eq.Text,{className:"text-sm font-medium",children:"Violation message (optional)"}),(0,l.jsx)(p.Input.TextArea,{disabled:a,rows:3,placeholder:"This violates our org policy...",value:r.violation_message_template,onChange:e=>s({violation_message_template:e.target.value})})]})]})},{Title:eY,Text:eQ,Link:eX}=f.Typography,{Option:eZ}=x.Select,e0={pre_call:"Before LLM Call - Runs before the LLM call and checks the input (Recommended)",during_call:"During LLM Call - Runs in parallel with the LLM call, with response held until check completes",post_call:"After LLM Call - Runs after the LLM call and checks only the output",logging_only:"Logging Only - Only runs on logging callbacks without affecting the LLM call",pre_mcp_call:"Before MCP Tool Call - Runs before MCP tool execution and validates tool calls",during_mcp_call:"During MCP Tool Call - Runs in parallel with MCP tool execution for monitoring"},e1=({visible:e,onClose:t,accessToken:a,onSuccess:s,preset:n})=>{let[o]=u.Form.useForm(),[d,c]=(0,r.useState)(!1),[f,j]=(0,r.useState)(null),[_,b]=(0,r.useState)(null),[v,w]=(0,r.useState)([]),[N,C]=(0,r.useState)({}),[S,k]=(0,r.useState)(0),[I,A]=(0,r.useState)(null),[O,T]=(0,r.useState)([]),[P,L]=(0,r.useState)(2),[B,F]=(0,r.useState)({}),[$,E]=(0,r.useState)([]),[M,R]=(0,r.useState)([]),[G,z]=(0,r.useState)([]),[D,K]=(0,r.useState)(""),[q,H]=(0,r.useState)(!1),[U,J]=(0,r.useState)(null),[W,V]=(0,r.useState)(""),[Y,Q]=(0,r.useState)(void 0),[X,Z]=(0,r.useState)("warn"),[ee,el]=(0,r.useState)(""),[er,eu]=(0,r.useState)(!1),[eg,ex]=(0,r.useState)([]),[eh,ef]=(0,r.useState)({rules:[],default_action:"deny",on_disallowed_action:"block",violation_message_template:""}),ey=(0,r.useMemo)(()=>!!f&&"tool_permission"===(en[f]||"").toLowerCase(),[f]);(0,r.useEffect)(()=>{a&&(async()=>{try{let[e,t,l]=await Promise.all([(0,m.getGuardrailUISettings)(a),(0,m.getGuardrailProviderSpecificParams)(a),(0,m.modelAvailableCall)(a,"","").catch(()=>null)]);b(e),A(t),l?.data&&ex(l.data.map(e=>e.id)),ei(t),eo(t)}catch(e){console.error("Error fetching guardrail data:",e),y.default.fromBackend("Failed to load guardrail configuration")}})()},[a]),(0,r.useEffect)(()=>{if(!n||!e||!_)return;j(n.provider);let t={provider:n.provider,guardrail_name:n.guardrailNameSuggestion,mode:n.mode,default_on:n.defaultOn,skip_system_message_choice:"inherit",skip_tool_message_choice:"inherit"};if("BlockCodeExecution"===n.provider&&(t.confidence_threshold=.5),o.setFieldsValue(t),n.categoryName&&_.content_filter_settings?.content_categories){let e=_.content_filter_settings.content_categories.find(e=>e.name===n.categoryName);e&&z([{id:`category-${Date.now()}`,category:e.name,display_name:e.display_name,action:e.default_action,severity_threshold:"medium"}])}},[n,e,_]);let ej=e=>{j(e);let t={config:void 0,presidio_analyzer_api_base:void 0,presidio_anonymizer_api_base:void 0};"BlockCodeExecution"===e&&(t.confidence_threshold=.5),o.setFieldsValue(t),w([]),C({}),T([]),L(2),F({}),E([]),R([]),z([]),K(""),H(!1),J(null),ef({rules:[],default_action:"deny",on_disallowed_action:"block",violation_message_template:""}),"LlmAsAJudge"===e&&o.setFieldsValue({mode:"post_call"})},eb=e=>{w(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e])},ev=(e,t)=>{C(a=>({...a,[e]:t}))},eN=async()=>{try{if(0===S&&(await o.validateFields(["guardrail_name","provider","mode","default_on"]),f)){let e=["guardrail_name","provider","mode","default_on"];"PresidioPII"===f&&e.push("presidio_analyzer_api_base","presidio_anonymizer_api_base"),await o.validateFields(e)}if(1===S&&ed(f)&&0===v.length)return void y.default.fromBackend("Please select at least one PII entity to continue");k(S+1)}catch(e){console.error("Form validation failed:",e)}},eC=()=>{o.resetFields(),j(null),w([]),C({}),T([]),L(2),F({}),E([]),R([]),z([]),K(""),ef({rules:[],default_action:"deny",on_disallowed_action:"block",violation_message_template:""}),V(""),Q(void 0),Z("warn"),el(""),eu(!1),k(0)},ek=()=>{eC(),t()},eI=async()=>{try{var e,l;c(!0),await o.validateFields();let r=o.getFieldsValue(!0),i=en[r.provider],n={guardrail_name:r.guardrail_name,litellm_params:{guardrail:i,mode:r.mode,default_on:r.default_on},guardrail_info:{}},d=(e=r.skip_system_message_choice,"yes"===e||"no"!==e&&void 0);void 0!==d&&(n.litellm_params.skip_system_message_in_guardrail=d);let u=(l=r.skip_tool_message_choice,"yes"===l||"no"!==l&&void 0);if(void 0!==u&&(n.litellm_params.skip_tool_message_in_guardrail=u),"PresidioPII"===r.provider&&v.length>0){let e={};v.forEach(t=>{e[t]=N[t]||"MASK"}),n.litellm_params.pii_entities_config=e,r.presidio_analyzer_api_base&&(n.litellm_params.presidio_analyzer_api_base=r.presidio_analyzer_api_base),r.presidio_anonymizer_api_base&&(n.litellm_params.presidio_anonymizer_api_base=r.presidio_anonymizer_api_base)}if(ec(r.provider)){let e=q&&U?.brand_self?.length>0;if(0===$.length&&0===M.length&&0===G.length&&!e){y.default.fromBackend("Please configure at least one content filter setting (category, pattern, keyword, or competitor intent)"),c(!1);return}$.length>0&&(n.litellm_params.patterns=$.map(e=>({pattern_type:"prebuilt"===e.type?"prebuilt":"regex",pattern_name:"prebuilt"===e.type?e.name:void 0,pattern:"custom"===e.type?e.pattern:void 0,name:e.name,action:e.action}))),M.length>0&&(n.litellm_params.blocked_words=M.map(e=>({keyword:e.keyword,action:e.action,description:e.description}))),G.length>0&&(n.litellm_params.categories=G.map(e=>({category:e.category,enabled:!0,action:e.action,severity_threshold:e.severity_threshold||"medium"}))),q&&U?.brand_self?.length>0&&(n.litellm_params.competitor_intent_config={competitor_intent_type:U.competitor_intent_type??"airline",brand_self:U.brand_self,locations:U.locations?.length>0?U.locations:void 0,competitors:"generic"===U.competitor_intent_type&&U.competitors?.length>0?U.competitors:void 0,policy:U.policy,threshold_high:U.threshold_high,threshold_medium:U.threshold_medium,threshold_low:U.threshold_low})}else if(r.config)try{n.guardrail_info=JSON.parse(r.config)}catch(e){y.default.fromBackend("Invalid JSON in configuration"),c(!1);return}if("llm_as_a_judge"===i){let e=r.criteria||[];if(0===e.length){y.default.fromBackend("Add at least one evaluation criterion"),c(!1);return}let t=e.reduce((e,t)=>e+(Number(t?.weight)||0),0);if(100!==t){y.default.fromBackend(`Criterion weights must sum to 100% (currently ${t}%)`),c(!1);return}n.litellm_params.judge_model=r.judge_model,n.litellm_params.overall_threshold=r.overall_threshold??80,n.litellm_params.on_failure=r.on_failure??"block",n.litellm_params.criteria=e.map(e=>({name:e.name,weight:Number(e.weight),description:e.description||""}))}if("tool_permission"===i){if(0===eh.rules.length){y.default.fromBackend("Add at least one tool permission rule"),c(!1);return}n.litellm_params.rules=eh.rules,n.litellm_params.default_action=eh.default_action,n.litellm_params.on_disallowed_action=eh.on_disallowed_action,eh.violation_message_template&&(n.litellm_params.violation_message_template=eh.violation_message_template)}if(ec(r.provider)&&(void 0!==Y&&Y>0&&(n.litellm_params.end_session_after_n_fails=Y),X&&"realtime"===W&&(n.litellm_params.on_violation=X),ee.trim()&&(n.litellm_params.realtime_violation_message=ee.trim())),I&&f&&"llm_as_a_judge"!==i){let e=I[en[f]?.toLowerCase()]||{},t=new Set;Object.keys(e).forEach(e=>{"optional_params"!==e&&t.add(e)}),e.optional_params&&e.optional_params.fields&&Object.keys(e.optional_params.fields).forEach(e=>{t.add(e)}),t.forEach(e=>{let t=r[e];(null==t||""===t)&&(t=r.optional_params?.[e]),null!=t&&""!==t&&(n.litellm_params[e]=t)})}if(!a)throw Error("No access token available");await (0,m.createGuardrailCall)(a,n),y.default.success("Guardrail created successfully"),eC(),s(),t()}catch(e){console.error("Failed to create guardrail:",e),y.default.fromBackend("Failed to create guardrail: "+(e instanceof Error?e.message:String(e)))}finally{c(!1)}},eA=e=>{if(!_||!ec(f))return null;let t=_.content_filter_settings;return t?(0,l.jsx)(et,{prebuiltPatterns:t.prebuilt_patterns||[],categories:t.pattern_categories||[],selectedPatterns:$,blockedWords:M,onPatternAdd:e=>E([...$,e]),onPatternRemove:e=>E($.filter(t=>t.id!==e)),onPatternActionChange:(e,t)=>{E($.map(a=>a.id===e?{...a,action:t}:a))},onBlockedWordAdd:e=>R([...M,e]),onBlockedWordRemove:e=>R(M.filter(t=>t.id!==e)),onBlockedWordUpdate:(e,t,a)=>{R(M.map(l=>l.id===e?{...l,[t]:a}:l))},contentCategories:t.content_categories||[],selectedContentCategories:G,onContentCategoryAdd:e=>z([...G,e]),onContentCategoryRemove:e=>z(G.filter(t=>t.id!==e)),onContentCategoryUpdate:(e,t,a)=>{z(G.map(l=>l.id===e?{...l,[t]:a}:l))},pendingCategorySelection:D,onPendingCategorySelectionChange:K,accessToken:a,showStep:e,competitorIntentEnabled:q,competitorIntentConfig:U,onCompetitorIntentChange:(e,t)=>{H(e),J(t)}}):null},eO=ec(f)?[{title:"Basic Info",optional:!1},{title:"Topics",optional:!1},{title:"Patterns",optional:!1},{title:"Keywords",optional:!1},{title:"Endpoint Settings (Optional)",optional:!0}]:ed(f)?[{title:"Basic Info",optional:!1},{title:"PII Configuration",optional:!1}]:[{title:"Basic Info",optional:!1},{title:"Provider Configuration",optional:!1}];return(0,l.jsx)(g.Modal,{title:null,open:e,onCancel:ek,maskClosable:!1,footer:null,width:1e3,closable:!1,className:"top-8",styles:{body:{padding:0}},children:(0,l.jsxs)("div",{className:"flex flex-col",children:[(0,l.jsxs)("div",{className:"flex items-center justify-between px-6 py-4 border-b border-gray-200",children:[(0,l.jsx)("h3",{className:"text-base font-semibold text-gray-900 m-0",children:"Create guardrail"}),(0,l.jsx)("button",{onClick:ek,className:"text-gray-400 hover:text-gray-600 bg-transparent border-none cursor-pointer text-base leading-none p-1",children:"✕"})]}),(0,l.jsx)("div",{className:"overflow-auto px-6 py-4",style:{maxHeight:"calc(80vh - 120px)"},children:(0,l.jsx)(u.Form,{form:o,layout:"vertical",initialValues:{mode:"pre_call",default_on:!1,skip_system_message_choice:"inherit",skip_tool_message_choice:"inherit"},children:eO.map((e,t)=>{let r=t{r&&k(t)},style:{minHeight:24},children:[(0,l.jsx)("span",{className:"text-sm",style:{fontWeight:i?600:500,color:i?"#1e293b":r?"#4f46e5":"#94a3b8"},children:e.title}),e.optional&&!i&&(0,l.jsx)("span",{className:"text-[11px] text-slate-400",children:"optional"}),r&&(0,l.jsx)("span",{className:"text-[11px] text-indigo-500 hover:underline",children:"Edit"})]}),i&&(0,l.jsx)("div",{className:"mt-3",children:(()=>{switch(S){case 0:return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(u.Form.Item,{name:"guardrail_name",label:"Guardrail Name",rules:[{required:!0,message:"Please enter a guardrail name"}],children:(0,l.jsx)(p.Input,{placeholder:"Enter a name for this guardrail"})}),(0,l.jsx)(u.Form.Item,{name:"provider",label:"Guardrail Provider",rules:[{required:!0,message:"Please select a provider"}],children:(0,l.jsx)(x.Select,{placeholder:"Select a guardrail provider",onChange:ej,labelInValue:!1,optionLabelProp:"label",dropdownRender:e=>e,showSearch:!0,children:Object.entries(es()).map(([e,t])=>(0,l.jsx)(eZ,{value:e,label:(0,l.jsxs)("div",{style:{display:"flex",alignItems:"center"},children:[ep[t]&&(0,l.jsx)("img",{src:(0,ea.resolveLogoSrc)(ep[t]),alt:"",style:{height:"20px",width:"20px",marginRight:"8px",objectFit:"contain"},onError:e=>{e.currentTarget.style.display="none"}}),(0,l.jsx)("span",{children:t})]}),children:(0,l.jsxs)("div",{style:{display:"flex",alignItems:"center"},children:[ep[t]&&(0,l.jsx)("img",{src:(0,ea.resolveLogoSrc)(ep[t]),alt:"",style:{height:"20px",width:"20px",marginRight:"8px",objectFit:"contain"},onError:e=>{e.currentTarget.style.display="none"}}),(0,l.jsx)("span",{children:t})]})},e))})}),(0,l.jsx)(u.Form.Item,{name:"mode",label:"Mode",tooltip:"How the guardrail should be applied",rules:[{required:!0,message:"Please select a mode"}],children:(0,l.jsx)(x.Select,{optionLabelProp:"label",mode:"multiple",children:_?.supported_modes?.map(e=>(0,l.jsx)(eZ,{value:e,label:e,children:(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("strong",{children:e}),"pre_call"===e&&(0,l.jsx)(h.Tag,{color:"green",style:{marginLeft:"8px"},children:"Recommended"})]}),(0,l.jsx)("div",{style:{fontSize:"12px",color:"#888"},children:e0[e]})]})},e))||(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(eZ,{value:"pre_call",label:"pre_call",children:(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("strong",{children:"pre_call"})," ",(0,l.jsx)(h.Tag,{color:"green",children:"Recommended"})]}),(0,l.jsx)("div",{style:{fontSize:"12px",color:"#888"},children:e0.pre_call})]})}),(0,l.jsx)(eZ,{value:"during_call",label:"during_call",children:(0,l.jsxs)("div",{children:[(0,l.jsx)("div",{children:(0,l.jsx)("strong",{children:"during_call"})}),(0,l.jsx)("div",{style:{fontSize:"12px",color:"#888"},children:e0.during_call})]})}),(0,l.jsx)(eZ,{value:"post_call",label:"post_call",children:(0,l.jsxs)("div",{children:[(0,l.jsx)("div",{children:(0,l.jsx)("strong",{children:"post_call"})}),(0,l.jsx)("div",{style:{fontSize:"12px",color:"#888"},children:e0.post_call})]})}),(0,l.jsx)(eZ,{value:"logging_only",label:"logging_only",children:(0,l.jsxs)("div",{children:[(0,l.jsx)("div",{children:(0,l.jsx)("strong",{children:"logging_only"})}),(0,l.jsx)("div",{style:{fontSize:"12px",color:"#888"},children:e0.logging_only})]})})]})})}),(0,l.jsx)(u.Form.Item,{name:"default_on",label:"Always On",tooltip:"If enabled, this guardrail will be applied to all requests by default.",children:(0,l.jsxs)(x.Select,{children:[(0,l.jsx)(x.Select.Option,{value:!0,children:"Yes"}),(0,l.jsx)(x.Select.Option,{value:!1,children:"No"})]})}),(0,l.jsx)(u.Form.Item,{name:"skip_system_message_choice",label:"Skip system messages in guardrail",tooltip:"Unified guardrails only: omit role: system from guardrail evaluation input (OpenAI chat + Anthropic messages). The model still receives full messages. Use global default follows litellm_settings.skip_system_message_in_guardrail.",children:(0,l.jsxs)(x.Select,{children:[(0,l.jsx)(x.Select.Option,{value:"inherit",children:"Use global default"}),(0,l.jsx)(x.Select.Option,{value:"yes",children:"Yes — exclude from guardrail scan"}),(0,l.jsx)(x.Select.Option,{value:"no",children:"No — always include in scan"})]})}),(0,l.jsx)(u.Form.Item,{name:"skip_tool_message_choice",label:"Skip tool messages in guardrail",tooltip:"Unified guardrails only: omit role: tool from guardrail evaluation input (OpenAI chat + Anthropic messages). The model still receives full messages. Use global default follows litellm_settings.skip_tool_message_in_guardrail.",children:(0,l.jsxs)(x.Select,{children:[(0,l.jsx)(x.Select.Option,{value:"inherit",children:"Use global default"}),(0,l.jsx)(x.Select.Option,{value:"yes",children:"Yes — exclude from guardrail scan"}),(0,l.jsx)(x.Select.Option,{value:"no",children:"No — always include in scan"})]})}),!ey&&!ec(f)&&!em(f)&&(0,l.jsx)(ew,{selectedProvider:f,accessToken:a,providerParams:I})]});case 1:if(ed(f))return _&&"PresidioPII"===f?(0,l.jsx)(eD,{entities:_.supported_entities,actions:_.supported_actions,selectedEntities:v,selectedActions:N,onEntitySelect:eb,onActionSelect:ev,entityCategories:_.pii_entity_categories}):null;if(ec(f))return eA("categories");if(em(f))return(0,l.jsx)(eS,{availableModels:eg,form:o});if(!f)return null;if(ey)return(0,l.jsx)(eV,{value:eh,onChange:ef});if(!I)return null;let e=en[f]?.toLowerCase(),t=I&&I[e];return t&&t.optional_params?(0,l.jsx)(e_,{optionalParams:t.optional_params,parentFieldKey:"optional_params"}):null;case 2:if(ec(f))return eA("patterns");return null;case 3:if(ec(f))return eA("keywords");return null;case 4:return(0,l.jsxs)("div",{className:"space-y-6",children:[(0,l.jsx)("div",{children:(0,l.jsxs)("p",{className:"text-sm text-gray-500",children:["Configure settings for a specific call type. Most guardrails don't need this — skip it unless you're using a specific endpoint like ",(0,l.jsx)("code",{children:"/v1/realtime"}),"."]})}),(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{className:"block text-sm font-medium text-gray-700 mb-1",children:"Call type"}),(0,l.jsx)(x.Select,{placeholder:"Select a call type",value:W||void 0,onChange:e=>{V(e),eu(!1)},style:{width:260},allowClear:!0,options:[{value:"realtime",label:"/v1/realtime"}]}),(0,l.jsx)("p",{className:"text-xs text-gray-400 mt-1",children:"More call types coming soon."})]}),"realtime"===W&&(0,l.jsxs)("div",{className:"border border-gray-200 rounded-lg overflow-hidden",children:[(0,l.jsxs)("button",{type:"button",onClick:()=>eu(e=>!e),className:"w-full flex items-center justify-between px-4 py-3 bg-gray-50 hover:bg-gray-100 text-sm font-medium text-gray-700",children:[(0,l.jsx)("span",{children:"/v1/realtime settings"}),(0,l.jsx)("svg",{className:`w-4 h-4 text-gray-500 transition-transform ${er?"rotate-180":""}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:(0,l.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"})})]}),er&&(0,l.jsxs)("div",{className:"space-y-5 px-4 py-4 border-t border-gray-200",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{className:"block text-sm font-medium text-gray-700 mb-1",children:"End session after X violations"}),(0,l.jsx)("p",{className:"text-xs text-gray-400 mb-2",children:"Automatically close the session after this many guardrail violations. Leave empty to never auto-close."}),(0,l.jsx)("input",{type:"number",min:1,placeholder:"e.g. 3",value:Y??"",onChange:e=>Q(e.target.value?parseInt(e.target.value,10):void 0),className:"border border-gray-300 rounded-sm px-3 py-1.5 text-sm w-32"})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{className:"block text-sm font-medium text-gray-700 mb-2",children:"On violation"}),(0,l.jsx)("div",{className:"space-y-2",children:["warn","end_session"].map(e=>(0,l.jsxs)("label",{className:"flex items-start gap-2 cursor-pointer",children:[(0,l.jsx)("input",{type:"radio",name:"on_violation",value:e,checked:X===e,onChange:()=>Z(e),className:"mt-0.5"}),(0,l.jsxs)("div",{children:[(0,l.jsx)("span",{className:"text-sm font-medium text-gray-800",children:"warn"===e?"Warn":"End session"}),(0,l.jsx)("p",{className:"text-xs text-gray-400 m-0",children:"warn"===e?"Bot speaks the message, session continues":"Bot speaks the message, connection closes immediately"})]})]},e))})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{className:"block text-sm font-medium text-gray-700 mb-1",children:"Message the user hears"}),(0,l.jsx)("p",{className:"text-xs text-gray-400 mb-2",children:"What the bot says aloud when this guardrail fires. Falls back to the default violation message if empty."}),(0,l.jsx)("textarea",{rows:3,placeholder:"e.g. I'm not able to continue this conversation. Please contact us at 1-800-774-2678.",value:ee,onChange:e=>el(e.target.value),className:"border border-gray-300 rounded-sm px-3 py-2 text-sm w-full resize-none"})]})]})]})]});default:return null}})()})]})]},t)})})}),(0,l.jsxs)("div",{className:"flex items-center justify-end space-x-3 px-6 py-3 border-t border-gray-200",children:[(0,l.jsx)(i.Button,{onClick:ek,children:"Cancel"}),S>0&&(0,l.jsx)(i.Button,{onClick:()=>{k(S-1)},children:"Previous"}),S{let[d]=u.Form.useForm(),[c,h]=(0,r.useState)(!1),[f,j]=(0,r.useState)(o?.provider||null),[_,b]=(0,r.useState)(null),[v,w]=(0,r.useState)([]),[N,C]=(0,r.useState)({});(0,r.useEffect)(()=>{(async()=>{try{if(!a)return;let e=await (0,m.getGuardrailUISettings)(a);b(e)}catch(e){console.error("Error fetching guardrail settings:",e),y.default.fromBackend("Failed to load guardrail settings")}})()},[a]),(0,r.useEffect)(()=>{o?.pii_entities_config&&Object.keys(o.pii_entities_config).length>0&&(w(Object.keys(o.pii_entities_config)),C(o.pii_entities_config))},[o]);let S=e=>{w(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e])},k=(e,t)=>{C(a=>({...a,[e]:t}))},I=async()=>{try{h(!0);let e=await d.validateFields(),l=en[e.provider],r=n&&"object"==typeof n?{...n}:{};r.guardrail=l,r.mode=e.mode,r.default_on=e.default_on;let o=e.skip_system_message_choice;"yes"===o?r.skip_system_message_in_guardrail=!0:"no"===o?r.skip_system_message_in_guardrail=!1:delete r.skip_system_message_in_guardrail;let c=e.skip_tool_message_choice;"yes"===c?r.skip_tool_message_in_guardrail=!0:"no"===c?r.skip_tool_message_in_guardrail=!1:delete r.skip_tool_message_in_guardrail;let u={};if("PresidioPII"===e.provider&&v.length>0){let e={};v.forEach(t=>{e[t]=N[t]||"MASK"}),r.pii_entities_config=e}else if(e.config)try{let t=JSON.parse(e.config);"Bedrock"===e.provider&&t?(t.guardrail_id&&(r.guardrailIdentifier=t.guardrail_id),t.guardrail_version&&(r.guardrailVersion=t.guardrail_version)):u=t}catch(e){y.default.fromBackend("Invalid JSON in configuration"),h(!1);return}let p={guardrail_id:s,guardrail:{guardrail_name:e.guardrail_name,litellm_params:r,guardrail_info:u}};if(!a)throw Error("No access token available");let g=`/guardrails/${s}`,x=await fetch(g,{method:"PUT",headers:{[(0,m.getGlobalLitellmHeaderName)()]:`Bearer ${a}`,"Content-Type":"application/json"},body:JSON.stringify(p)});if(!x.ok){let e=await x.text();throw Error(e||"Failed to update guardrail")}y.default.success("Guardrail updated successfully"),i(),t()}catch(e){console.error("Failed to update guardrail:",e),y.default.fromBackend("Failed to update guardrail: "+(e instanceof Error?e.message:String(e)))}finally{h(!1)}};return(0,l.jsx)(g.Modal,{title:"Edit Guardrail",open:e,onCancel:t,footer:null,width:700,children:(0,l.jsxs)(u.Form,{form:d,layout:"vertical",initialValues:o,children:[(0,l.jsx)(u.Form.Item,{name:"guardrail_name",label:"Guardrail Name",rules:[{required:!0,message:"Please enter a guardrail name"}],children:(0,l.jsx)(tn.TextInput,{placeholder:"Enter a name for this guardrail"})}),(0,l.jsx)(u.Form.Item,{name:"provider",label:"Guardrail Provider",rules:[{required:!0,message:"Please select a provider"}],children:(0,l.jsx)(x.Select,{placeholder:"Select a guardrail provider",onChange:e=>{j(e),d.setFieldsValue({config:void 0}),w([]),C({})},disabled:!0,optionLabelProp:"label",children:Object.entries(es()).map(([e,t])=>(0,l.jsx)(tc,{value:e,label:t,children:(0,l.jsxs)("div",{style:{display:"flex",alignItems:"center"},children:[ep[t]&&(0,l.jsx)("img",{src:(0,ea.resolveLogoSrc)(ep[t]),alt:"",style:{height:"20px",width:"20px",marginRight:"8px",objectFit:"contain"},onError:e=>{e.currentTarget.style.display="none"}}),(0,l.jsx)("span",{children:t})]})},e))})}),(0,l.jsx)(u.Form.Item,{name:"mode",label:"Mode",tooltip:"How the guardrail should be applied",rules:[{required:!0,message:"Please select a mode"}],children:(0,l.jsx)(x.Select,{children:_?.supported_modes?.map(e=>(0,l.jsx)(tc,{value:e,children:e},e))||(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(tc,{value:"pre_call",children:"pre_call"}),(0,l.jsx)(tc,{value:"post_call",children:"post_call"})]})})}),(0,l.jsx)(u.Form.Item,{name:"default_on",label:"Always On",tooltip:"If enabled, this guardrail will be applied to all requests by default",valuePropName:"checked",children:(0,l.jsx)(U.Switch,{})}),(0,l.jsx)(u.Form.Item,{name:"skip_system_message_choice",label:"Skip system messages in guardrail",tooltip:"Unified guardrails only: whether role: system content is omitted from guardrail input (LLM still receives full messages). Use global default follows litellm_settings.skip_system_message_in_guardrail.",children:(0,l.jsxs)(x.Select,{children:[(0,l.jsx)(tc,{value:"inherit",children:"Use global default"}),(0,l.jsx)(tc,{value:"yes",children:"Yes — exclude from guardrail scan"}),(0,l.jsx)(tc,{value:"no",children:"No — always include in scan"})]})}),(0,l.jsx)(u.Form.Item,{name:"skip_tool_message_choice",label:"Skip tool messages in guardrail",tooltip:"Unified guardrails only: whether role: tool content is omitted from guardrail input (LLM still receives full messages). Use global default follows litellm_settings.skip_tool_message_in_guardrail.",children:(0,l.jsxs)(x.Select,{children:[(0,l.jsx)(tc,{value:"inherit",children:"Use global default"}),(0,l.jsx)(tc,{value:"yes",children:"Yes — exclude from guardrail scan"}),(0,l.jsx)(tc,{value:"no",children:"No — always include in scan"})]})}),(()=>{if(!f)return null;if("PresidioPII"===f)return _&&f&&"PresidioPII"===f?(0,l.jsx)(eD,{entities:_.supported_entities,actions:_.supported_actions,selectedEntities:v,selectedActions:N,onEntitySelect:S,onActionSelect:k,entityCategories:_.pii_entity_categories}):null;switch(f){case"Aporia":return(0,l.jsx)(u.Form.Item,{label:"Aporia Configuration",name:"config",tooltip:"JSON configuration for Aporia",children:(0,l.jsx)(p.Input.TextArea,{rows:4,placeholder:`{ + "api_key": "your_aporia_api_key", + "project_name": "your_project_name" +}`})});case"AimSecurity":return(0,l.jsx)(u.Form.Item,{label:"Aim Security Configuration",name:"config",tooltip:"JSON configuration for Aim Security",children:(0,l.jsx)(p.Input.TextArea,{rows:4,placeholder:`{ + "api_key": "your_aim_api_key" +}`})});case"Bedrock":return(0,l.jsx)(u.Form.Item,{label:"Amazon Bedrock Configuration",name:"config",tooltip:"JSON configuration for Amazon Bedrock guardrails",children:(0,l.jsx)(p.Input.TextArea,{rows:4,placeholder:`{ + "guardrail_id": "your_guardrail_id", + "guardrail_version": "your_guardrail_version" +}`})});case"CatoNetworks":return(0,l.jsx)(u.Form.Item,{label:"Cato Networks Configuration",name:"config",tooltip:"JSON configuration for Cato Networks",children:(0,l.jsx)(p.Input.TextArea,{rows:4,placeholder:`{ + "api_key": "your_cato_api_key" +}`})});case"GuardrailsAI":return(0,l.jsx)(u.Form.Item,{label:"Guardrails.ai Configuration",name:"config",tooltip:"JSON configuration for Guardrails.ai",children:(0,l.jsx)(p.Input.TextArea,{rows:4,placeholder:`{ + "api_key": "your_guardrails_api_key", + "guardrail_id": "your_guardrail_id" +}`})});case"LakeraAI":return(0,l.jsx)(u.Form.Item,{label:"Lakera AI Configuration",name:"config",tooltip:"JSON configuration for Lakera AI",children:(0,l.jsx)(p.Input.TextArea,{rows:4,placeholder:`{ + "api_key": "your_lakera_api_key" +}`})});case"PromptInjection":return(0,l.jsx)(u.Form.Item,{label:"Prompt Injection Configuration",name:"config",tooltip:"JSON configuration for prompt injection detection",children:(0,l.jsx)(p.Input.TextArea,{rows:4,placeholder:`{ + "threshold": 0.8 +}`})});default:return(0,l.jsx)(u.Form.Item,{label:"Custom Configuration",name:"config",tooltip:"JSON configuration for your custom guardrail",children:(0,l.jsx)(p.Input.TextArea,{rows:4,placeholder:`{ + "key1": "value1", + "key2": "value2" +}`})})}})(),(0,l.jsxs)("div",{className:"flex justify-end space-x-2 mt-4",children:[(0,l.jsx)(e9.Button,{variant:"secondary",onClick:t,children:"Cancel"}),(0,l.jsx)(e9.Button,{onClick:I,loading:c,children:"Update Guardrail"})]})]})})};var tu=((a={}).DB="db",a.CONFIG="config",a);let tp=({guardrailsList:e,isLoading:t,onDeleteClick:a,accessToken:i,onGuardrailUpdated:s,isAdmin:n=!1,onGuardrailClick:o})=>{let[d,c]=(0,r.useState)([{id:"created_at",desc:!0}]),[m,u]=(0,r.useState)(!1),[p,g]=(0,r.useState)(null),x=e=>e?new Date(e).toLocaleString():"-",h=[{header:"Guardrail ID",accessorKey:"guardrail_id",cell:e=>(0,l.jsx)(eN.Tooltip,{title:String(e.getValue()||""),children:(0,l.jsx)(e9.Button,{size:"xs",variant:"light",className:"font-mono text-blue-500 bg-blue-50 hover:bg-blue-100 text-xs font-normal px-2 py-0.5 text-left overflow-hidden truncate max-w-[200px]",onClick:()=>e.getValue()&&o(e.getValue()),children:e.getValue()?`${String(e.getValue()).slice(0,7)}...`:""})})},{header:"Name",accessorKey:"guardrail_name",cell:({row:e})=>{let t=e.original;return(0,l.jsx)(eN.Tooltip,{title:t.guardrail_name,children:(0,l.jsx)("span",{className:"text-xs font-medium",children:t.guardrail_name||"-"})})}},{header:"Provider",accessorKey:"litellm_params.guardrail",cell:({row:e})=>{let{logo:t,displayName:a}=eg(e.original.litellm_params.guardrail);return(0,l.jsxs)("div",{className:"flex items-center space-x-2",children:[t&&(0,l.jsx)("img",{src:t,alt:`${a} logo`,className:"w-4 h-4",onError:e=>{e.target.style.display="none"}}),(0,l.jsx)("span",{className:"text-xs",children:a})]})}},{header:"Mode",accessorKey:"litellm_params.mode",cell:({row:e})=>{let t=e.original;return(0,l.jsx)("span",{className:"text-xs",children:t.litellm_params.mode})}},{header:"Default On",accessorKey:"litellm_params.default_on",cell:({row:e})=>{let t=e.original;return(0,l.jsx)(tr.Badge,{color:t.litellm_params?.default_on?"green":"gray",className:"text-xs font-normal",size:"xs",children:t.litellm_params?.default_on?"Default On":"Default Off"})}},{header:"Created At",accessorKey:"created_at",cell:({row:e})=>{let t=e.original;return(0,l.jsx)(eN.Tooltip,{title:t.created_at,children:(0,l.jsx)("span",{className:"text-xs",children:x(t.created_at)})})}},{header:"Updated At",accessorKey:"updated_at",cell:({row:e})=>{let t=e.original;return(0,l.jsx)(eN.Tooltip,{title:t.updated_at,children:(0,l.jsx)("span",{className:"text-xs",children:x(t.updated_at)})})}},{id:"actions",header:"Actions",cell:({row:e})=>{let t=e.original,r=t.guardrail_definition_location===tu.CONFIG;return(0,l.jsx)("div",{className:"flex space-x-2",children:r?(0,l.jsx)(eN.Tooltip,{title:"Config guardrail cannot be deleted on the dashboard. Please delete it from the config file.",children:(0,l.jsx)(e7.Icon,{"data-testid":"config-delete-icon",icon:te.TrashIcon,size:"sm",className:"cursor-not-allowed text-gray-400",title:"Config guardrail cannot be deleted on the dashboard. Please delete it from the config file.","aria-label":"Delete guardrail (config)"})}):(0,l.jsx)(eN.Tooltip,{title:"Delete guardrail",children:(0,l.jsx)(e7.Icon,{icon:te.TrashIcon,size:"sm",onClick:()=>t.guardrail_id&&a(t.guardrail_id,t.guardrail_name||"Unnamed Guardrail"),className:"cursor-pointer hover:text-red-500"})})})}}],f=(0,ti.useReactTable)({data:e,columns:h,state:{sorting:d},onSortingChange:c,getCoreRowModel:(0,ts.getCoreRowModel)(),getSortedRowModel:(0,ts.getSortedRowModel)(),enableSorting:!0});return(0,l.jsxs)("div",{className:"rounded-lg custom-border relative",children:[(0,l.jsx)("div",{className:"overflow-x-auto",children:(0,l.jsxs)(e2.Table,{className:"[&_td]:py-0.5 [&_th]:py-1",children:[(0,l.jsx)(e8.TableHead,{children:f.getHeaderGroups().map(e=>(0,l.jsx)(e3.TableRow,{children:e.headers.map(e=>(0,l.jsx)(e6.TableHeaderCell,{className:`py-1 h-8 ${"actions"===e.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)]":""}`,onClick:e.column.getToggleSortingHandler(),children:(0,l.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,l.jsx)("div",{className:"flex items-center",children:e.isPlaceholder?null:(0,ti.flexRender)(e.column.columnDef.header,e.getContext())}),"actions"!==e.id&&(0,l.jsx)("div",{className:"w-4",children:e.column.getIsSorted()?({asc:(0,l.jsx)(ta.ChevronUpIcon,{className:"h-4 w-4 text-blue-500"}),desc:(0,l.jsx)(tl.ChevronDownIcon,{className:"h-4 w-4 text-blue-500"})})[e.column.getIsSorted()]:(0,l.jsx)(tt.SwitchVerticalIcon,{className:"h-4 w-4 text-gray-400"})})]})},e.id))},e.id))}),(0,l.jsx)(e4.TableBody,{children:t?(0,l.jsx)(e3.TableRow,{children:(0,l.jsx)(e5.TableCell,{colSpan:h.length,className:"h-8 text-center",children:(0,l.jsx)("div",{className:"text-center text-gray-500",children:(0,l.jsx)("p",{children:"Loading..."})})})}):e.length>0?f.getRowModel().rows.map(e=>(0,l.jsx)(e3.TableRow,{className:"h-8",children:e.getVisibleCells().map(e=>(0,l.jsx)(e5.TableCell,{className:`py-0.5 max-h-8 overflow-hidden text-ellipsis whitespace-nowrap ${"actions"===e.column.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)]":""}`,children:(0,ti.flexRender)(e.column.columnDef.cell,e.getContext())},e.id))},e.id)):(0,l.jsx)(e3.TableRow,{children:(0,l.jsx)(e5.TableCell,{colSpan:h.length,className:"h-8 text-center",children:(0,l.jsx)("div",{className:"text-center text-gray-500",children:(0,l.jsx)("p",{children:"No guardrails found"})})})})})]})}),p&&(0,l.jsx)(tm,{visible:m,onClose:()=>u(!1),accessToken:i,onSuccess:()=>{u(!1),g(null),s()},guardrailId:p.guardrail_id||"",fullLitellmParams:p.litellm_params,initialValues:{guardrail_name:p.guardrail_name||"",provider:Object.keys(en).find(e=>en[e]===p?.litellm_params.guardrail)||"",mode:p.litellm_params.mode,default_on:p.litellm_params.default_on,pii_entities_config:p.litellm_params.pii_entities_config,skip_system_message_choice:ex(p.litellm_params?.skip_system_message_in_guardrail),skip_tool_message_choice:eh(p.litellm_params?.skip_tool_message_in_guardrail),...p.guardrail_info}})]})};var tg=e.i(708347),tx=e.i(500330),eA=eA,th=e.i(530212),tf=e.i(350967),ty=e.i(197647),tj=e.i(653824),t_=e.i(881073),tb=e.i(404206),tv=e.i(723731),tw=e.i(629569),tN=e.i(678784),tC=e.i(118366),tS=e.i(560445);let{Text:tk}=f.Typography,{Option:tI}=x.Select,tA=({categories:e,onActionChange:t,onSeverityChange:a,onRemove:r,readOnly:s=!1})=>{let n=[{title:"Category",dataIndex:"display_name",key:"display_name",render:(e,t)=>(0,l.jsxs)("div",{children:[(0,l.jsx)(tk,{strong:!0,children:e}),e!==t.category&&(0,l.jsx)("div",{children:(0,l.jsx)(tk,{type:"secondary",style:{fontSize:12},children:t.category})})]})},{title:"Severity Threshold",dataIndex:"severity_threshold",key:"severity_threshold",width:180,render:(e,t)=>s?(0,l.jsx)(h.Tag,{color:{high:"red",medium:"orange",low:"yellow"}[e],children:e.toUpperCase()}):(0,l.jsxs)(x.Select,{value:e,onChange:e=>a?.(t.id,e),style:{width:150},size:"small",children:[(0,l.jsx)(tI,{value:"high",children:"High"}),(0,l.jsx)(tI,{value:"medium",children:"Medium"}),(0,l.jsx)(tI,{value:"low",children:"Low"})]})},{title:"Action",dataIndex:"action",key:"action",width:150,render:(e,a)=>s?(0,l.jsx)(h.Tag,{color:"BLOCK"===e?"red":"blue",children:e}):(0,l.jsxs)(x.Select,{value:e,onChange:e=>t?.(a.id,e),style:{width:120},size:"small",children:[(0,l.jsx)(tI,{value:"BLOCK",children:"Block"}),(0,l.jsx)(tI,{value:"MASK",children:"Mask"})]})}];return(s||n.push({title:"",key:"actions",width:100,render:(e,t)=>(0,l.jsx)(i.Button,{type:"text",danger:!0,size:"small",icon:(0,l.jsx)(L.DeleteOutlined,{}),onClick:()=>r?.(t.id),children:"Delete"})}),0===e.length)?(0,l.jsx)("div",{style:{textAlign:"center",padding:"40px 0",color:"#999"},children:"No categories configured."}):(0,l.jsx)(P.Table,{dataSource:e,columns:n,rowKey:"id",pagination:!1,size:"small"})},tO=({patterns:e,blockedWords:t,categories:a=[],readOnly:r=!0,onPatternActionChange:i,onPatternRemove:s,onBlockedWordUpdate:n,onBlockedWordRemove:o,onCategoryActionChange:d,onCategorySeverityChange:c,onCategoryRemove:m})=>{if(0===e.length&&0===t.length&&0===a.length)return null;let u=()=>{};return(0,l.jsxs)(l.Fragment,{children:[a.length>0&&(0,l.jsxs)(eK.Card,{className:"mt-6",children:[(0,l.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,l.jsx)(eq.Text,{className:"text-lg font-semibold",children:"Content Categories"}),(0,l.jsxs)(tr.Badge,{color:"blue",children:[a.length," categories configured"]})]}),(0,l.jsx)(tA,{categories:a,onActionChange:r?void 0:d,onSeverityChange:r?void 0:c,onRemove:r?void 0:m,readOnly:r})]}),e.length>0&&(0,l.jsxs)(eK.Card,{className:"mt-6",children:[(0,l.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,l.jsx)(eq.Text,{className:"text-lg font-semibold",children:"Pattern Detection"}),(0,l.jsxs)(tr.Badge,{color:"blue",children:[e.length," patterns configured"]})]}),(0,l.jsx)($,{patterns:e,onActionChange:r?u:i||u,onRemove:r?u:s||u})]}),t.length>0&&(0,l.jsxs)(eK.Card,{className:"mt-6",children:[(0,l.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,l.jsx)(eq.Text,{className:"text-lg font-semibold",children:"Blocked Keywords"}),(0,l.jsxs)(tr.Badge,{color:"blue",children:[t.length," keywords configured"]})]}),(0,l.jsx)(R,{keywords:t,onActionChange:r?u:n||u,onRemove:r?u:o||u})]})]})},{Text:tT}=f.Typography,tP=({guardrailData:e,guardrailSettings:t,isEditing:a,accessToken:i,onDataChange:s,onUnsavedChanges:n})=>{let[o,d]=(0,r.useState)([]),[c,m]=(0,r.useState)([]),[u,p]=(0,r.useState)([]),[g,x]=(0,r.useState)([]),[h,f]=(0,r.useState)([]),[y,j]=(0,r.useState)([]),[_,b]=(0,r.useState)(!1),[v,w]=(0,r.useState)(null),[N,C]=(0,r.useState)(!1),[S,k]=(0,r.useState)(null);(0,r.useEffect)(()=>{if(e?.litellm_params?.patterns){let t=e.litellm_params.patterns.map((e,t)=>({id:`pattern-${t}`,type:"prebuilt"===e.pattern_type?"prebuilt":"custom",name:e.pattern_name||e.name,display_name:e.display_name,pattern:e.pattern,action:e.action||"BLOCK"}));d(t),x(t)}else d([]),x([]);if(e?.litellm_params?.blocked_words){let t=e.litellm_params.blocked_words.map((e,t)=>({id:`word-${t}`,keyword:e.keyword,action:e.action||"BLOCK",description:e.description}));m(t),f(t)}else m([]),f([]);if(e?.litellm_params?.categories?.length>0){let a=t?.content_filter_settings?.content_categories?Object.fromEntries(t.content_filter_settings.content_categories.map(e=>[e.name,e])):{},l=e.litellm_params.categories.map((e,t)=>{let l=a[e.category];return{id:`category-${t}`,category:e.category,display_name:l?.display_name??e.category,action:e.action||"BLOCK",severity_threshold:e.severity_threshold||"medium"}});p(l),j(l)}else p([]),j([]);let a=e?.litellm_params?.competitor_intent_config;if(a&&"object"==typeof a){let e=!!(a.brand_self&&Array.isArray(a.brand_self)&&a.brand_self.length>0),t={competitor_intent_type:a.competitor_intent_type??"airline",brand_self:Array.isArray(a.brand_self)?a.brand_self:[],locations:Array.isArray(a.locations)?a.locations:[],competitors:Array.isArray(a.competitors)?a.competitors:[],policy:a.policy??{competitor_comparison:"refuse",possible_competitor_comparison:"reframe"},threshold_high:"number"==typeof a.threshold_high?a.threshold_high:.7,threshold_medium:"number"==typeof a.threshold_medium?a.threshold_medium:.45,threshold_low:"number"==typeof a.threshold_low?a.threshold_low:.3};b(e),w(t),C(e),k(t)}else b(!1),w(null),C(!1),k(null)},[e,t?.content_filter_settings?.content_categories]),(0,r.useEffect)(()=>{s&&s(o,c,u,_,v)},[o,c,u,_,v,s]);let I=r.default.useMemo(()=>{let e=JSON.stringify(o)!==JSON.stringify(g),t=JSON.stringify(c)!==JSON.stringify(h),a=JSON.stringify(u)!==JSON.stringify(y),l=_!==N||JSON.stringify(v)!==JSON.stringify(S);return e||t||a||l},[o,c,u,_,v,g,h,y,N,S]);return((0,r.useEffect)(()=>{a&&n&&n(I)},[I,a,n]),e?.litellm_params?.guardrail!=="litellm_content_filter")?null:a?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(eH.Divider,{orientation:"left",children:"Content Filter Configuration"}),I&&(0,l.jsx)(tS.Alert,{type:"warning",showIcon:!0,className:"mb-4",message:(0,l.jsx)(tT,{children:'You have unsaved changes to patterns or keywords. Remember to click "Save Changes" at the bottom.'})}),(0,l.jsx)("div",{className:"mb-6",children:t&&t.content_filter_settings&&(0,l.jsx)(et,{prebuiltPatterns:t.content_filter_settings.prebuilt_patterns||[],categories:t.content_filter_settings.pattern_categories||[],selectedPatterns:o,blockedWords:c,onPatternAdd:e=>d([...o,e]),onPatternRemove:e=>d(o.filter(t=>t.id!==e)),onPatternActionChange:(e,t)=>d(o.map(a=>a.id===e?{...a,action:t}:a)),onBlockedWordAdd:e=>m([...c,e]),onBlockedWordRemove:e=>m(c.filter(t=>t.id!==e)),onBlockedWordUpdate:(e,t,a)=>m(c.map(l=>l.id===e?{...l,[t]:a}:l)),onFileUpload:e=>{},accessToken:i,contentCategories:t.content_filter_settings.content_categories||[],selectedContentCategories:u,onContentCategoryAdd:e=>p([...u,e]),onContentCategoryRemove:e=>p(u.filter(t=>t.id!==e)),onContentCategoryUpdate:(e,t,a)=>p(u.map(l=>l.id===e?{...l,[t]:a}:l)),competitorIntentEnabled:_,competitorIntentConfig:v,onCompetitorIntentChange:(e,t)=>{b(e),w(t)}})})]}):(0,l.jsx)(tO,{patterns:o,blockedWords:c,categories:u,readOnly:!0})};var tL=e.i(788191),tB=e.i(245704),tF=e.i(518617);let t$={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M715.8 493.5L335 165.1c-14.2-12.2-35-1.2-35 18.5v656.8c0 19.7 20.8 30.7 35 18.5l380.8-328.4c10.9-9.4 10.9-27.6 0-37z"}}]},name:"caret-right",theme:"outlined"};var tE=r.forwardRef(function(e,t){return r.createElement(eL.default,(0,eT.default)({},e,{ref:t,icon:t$}))}),tM=e.i(987432);let tR={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M892 772h-80v-80c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v80h-80c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h80v80c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-80h80c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM373.5 498.4c-.9-8.7-1.4-17.5-1.4-26.4 0-15.9 1.5-31.4 4.3-46.5.7-3.6-1.2-7.3-4.5-8.8-13.6-6.1-26.1-14.5-36.9-25.1a127.54 127.54 0 01-38.7-95.4c.9-32.1 13.8-62.6 36.3-85.6 24.7-25.3 57.9-39.1 93.2-38.7 31.9.3 62.7 12.6 86 34.4 7.9 7.4 14.7 15.6 20.4 24.4 2 3.1 5.9 4.4 9.3 3.2 17.6-6.1 36.2-10.4 55.3-12.4 5.6-.6 8.8-6.6 6.3-11.6-32.5-64.3-98.9-108.7-175.7-109.9-110.8-1.7-203.2 89.2-203.2 200 0 62.8 28.9 118.8 74.2 155.5-31.8 14.7-61.1 35-86.5 60.4-54.8 54.7-85.8 126.9-87.8 204a8 8 0 008 8.2h56.1c4.3 0 7.9-3.4 8-7.7 1.9-58 25.4-112.3 66.7-153.5 29.4-29.4 65.4-49.8 104.7-59.7 3.8-1.1 6.4-4.8 5.9-8.8zM824 472c0-109.4-87.9-198.3-196.9-200C516.3 270.3 424 361.2 424 472c0 62.8 29 118.8 74.2 155.5a300.95 300.95 0 00-86.4 60.4C357 742.6 326 814.8 324 891.8a8 8 0 008 8.2h56c4.3 0 7.9-3.4 8-7.7 1.9-58 25.4-112.3 66.7-153.5C505.8 695.7 563 672 624 672c110.4 0 200-89.5 200-200zm-109.5 90.5C690.3 586.7 658.2 600 624 600s-66.3-13.3-90.5-37.5a127.26 127.26 0 01-37.5-91.8c.3-32.8 13.4-64.5 36.3-88 24-24.6 56.1-38.3 90.4-38.7 33.9-.3 66.8 12.9 91 36.6 24.8 24.3 38.4 56.8 38.4 91.4-.1 34.2-13.4 66.3-37.6 90.5z"}}]},name:"usergroup-add",theme:"outlined"};var tG=r.forwardRef(function(e,t){return r.createElement(eL.default,(0,eT.default)({},e,{ref:t,icon:tR}))}),tz=e.i(872934);let{Panel:tD}=G.Collapse,{TextArea:tK}=p.Input,tq={empty:{name:"Empty Template",code:`async def apply_guardrail(inputs, request_data, input_type): + # inputs: {texts, images, tools, tool_calls, structured_messages, model} + # request_data: {model, user_id, team_id, end_user_id, metadata} + # input_type: "request" or "response" + return allow()`},blockSSN:{name:"Block SSN",code:`def apply_guardrail(inputs, request_data, input_type): + for text in inputs["texts"]: + if regex_match(text, r"\\d{3}-\\d{2}-\\d{4}"): + return block("SSN detected") + return allow()`},redactEmail:{name:"Redact Emails",code:`def apply_guardrail(inputs, request_data, input_type): + pattern = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}" + modified = [] + for text in inputs["texts"]: + modified.append(regex_replace(text, pattern, "[EMAIL REDACTED]")) + return modify(texts=modified)`},blockSQL:{name:"Block SQL Injection",code:`def apply_guardrail(inputs, request_data, input_type): + if input_type != "request": + return allow() + for text in inputs["texts"]: + if contains_code_language(text, ["sql"]): + return block("SQL code not allowed") + return allow()`},validateJSON:{name:"Validate JSON",code:`def apply_guardrail(inputs, request_data, input_type): + if input_type != "response": + return allow() + + schema = {"type": "object", "required": ["name", "value"]} + + for text in inputs["texts"]: + obj = json_parse(text) + if obj is None: + return block("Invalid JSON response") + if not json_schema_valid(obj, schema): + return block("Response missing required fields") + return allow()`},externalAPI:{name:"External API Check (async)",code:`async def apply_guardrail(inputs, request_data, input_type): + # Call an external moderation API (async for non-blocking) + for text in inputs["texts"]: + response = await http_post( + "https://api.example.com/moderate", + body={"text": text, "user_id": request_data["user_id"]}, + headers={"Authorization": "Bearer YOUR_API_KEY"}, + timeout=10 + ) + + if not response["success"]: + # API call failed, allow by default or block + return allow() + + if response["body"].get("flagged"): + return block(response["body"].get("reason", "Content flagged")) + + return allow()`}},tH={"Return Values":[{name:"allow()",desc:"Let request/response through"},{name:"block(reason)",desc:"Reject with message"},{name:"modify(texts=[], images=[], tool_calls=[])",desc:"Transform content"}],"HTTP Requests (async)":[{name:"await http_request(url, method, headers, body)",desc:"Make async HTTP request"},{name:"await http_get(url, headers)",desc:"Async GET request"},{name:"await http_post(url, body, headers)",desc:"Async POST request"}],"Regex Functions":[{name:"regex_match(text, pattern)",desc:"Returns True if pattern found"},{name:"regex_replace(text, pattern, replacement)",desc:"Replace all matches"},{name:"regex_find_all(text, pattern)",desc:"Return list of matches"}],"JSON Functions":[{name:"json_parse(text)",desc:"Parse JSON string, returns None on error"},{name:"json_stringify(obj)",desc:"Convert to JSON string"},{name:"json_schema_valid(obj, schema)",desc:"Validate against JSON schema"}],"URL Functions":[{name:"extract_urls(text)",desc:"Extract all URLs from text"},{name:"is_valid_url(url)",desc:"Check if URL is valid"},{name:"all_urls_valid(text)",desc:"Check all URLs in text are valid"}],"Code Detection":[{name:"detect_code(text)",desc:"Returns True if code detected"},{name:"detect_code_languages(text)",desc:"Returns list of detected languages"},{name:'contains_code_language(text, ["sql"])',desc:"Check for specific languages"}],"Text Utilities":[{name:"contains(text, substring)",desc:"Check if substring exists"},{name:"contains_any(text, [substr1, substr2])",desc:"Check if any substring exists"},{name:"word_count(text)",desc:"Count words"},{name:"char_count(text)",desc:"Count characters"},{name:"lower(text) / upper(text) / trim(text)",desc:"String transforms"}]},tU=[{value:"pre_call",label:"pre_call (Request)"},{value:"post_call",label:"post_call (Response)"},{value:"during_call",label:"during_call (Parallel)"},{value:"logging_only",label:"logging_only"},{value:"pre_mcp_call",label:"pre_mcp_call (Before MCP Tool Call)"},{value:"post_mcp_call",label:"post_mcp_call (After MCP Tool Call)"},{value:"during_mcp_call",label:"during_mcp_call (During MCP Tool Call)"}],tJ=({visible:e,onClose:t,onSuccess:a,accessToken:i,editData:s})=>{let n=!!s,[o,d]=(0,r.useState)(""),[u,p]=(0,r.useState)(["pre_call"]),[h,f]=(0,r.useState)(!1),[j,_]=(0,r.useState)("empty"),[b,v]=(0,r.useState)(tq.empty.code),[w,N]=(0,r.useState)(!1),[C,S]=(0,r.useState)(!1),[k,I]=(0,r.useState)(!1),A={texts:["Hello, my SSN is 123-45-6789"],images:[],tools:[{type:"function",function:{name:"get_weather",description:"Get the current weather in a location",parameters:{type:"object",properties:{location:{type:"string",description:"City name"}},required:["location"]}}}],tool_calls:[],structured_messages:[{role:"system",content:"You are a helpful assistant."},{role:"user",content:"Hello, my SSN is 123-45-6789"}],model:"gpt-4"},O={texts:["The weather in San Francisco is 72°F and sunny."],images:[],tools:[],tool_calls:[{id:"call_abc123",type:"function",function:{name:"get_weather",arguments:'{"location": "San Francisco"}'}}],structured_messages:[],model:"gpt-4"},T={texts:['Tool: read_wiki_structure\nArguments: {"repoName": "BerriAI/litellm"}'],images:[],tools:[{type:"function",function:{name:"read_wiki_structure",description:"Read the structure of a GitHub repository (MCP tool passed as OpenAI tool)",parameters:{type:"object",properties:{repoName:{type:"string",description:"Repository name, e.g. BerriAI/litellm"}},required:["repoName"]}}}],tool_calls:[{id:"call_mcp_001",type:"function",function:{name:"read_wiki_structure",arguments:'{"repoName": "BerriAI/litellm"}'}}],structured_messages:[{role:"user",content:'Tool: read_wiki_structure\nArguments: {"repoName": "BerriAI/litellm"}'}],model:"mcp-tool-call"},[P,L]=(0,r.useState)(JSON.stringify(A,null,2)),[B,F]=(0,r.useState)(null),[$,E]=(0,r.useState)(null),M=(0,r.useRef)(null),R=e=>null==e?["pre_call"]:Array.isArray(e)?e.length?e:["pre_call"]:[e];(0,r.useEffect)(()=>{e&&(s?(d(s.guardrail_name||""),p(R(s.litellm_params?.mode)),f(s.litellm_params?.default_on||!1),v(s.litellm_params?.custom_code||tq.empty.code),_("")):(d(""),p(["pre_call"]),f(!1),_("empty"),v(tq.empty.code)),F(null),I(!1))},[e,s]);let z=async e=>{try{await navigator.clipboard.writeText(e),E(e),setTimeout(()=>E(null),2e3)}catch(e){console.error("Failed to copy:",e)}},D=async()=>{if(!o.trim())return void y.default.fromBackend("Please enter a guardrail name");if(!b.trim())return void y.default.fromBackend("Please enter custom code");if(!i)return void y.default.fromBackend("No access token available");N(!0);try{if(n&&s){let e={litellm_params:{custom_code:b}};o!==s.guardrail_name&&(e.guardrail_name=o);let t=R(s.litellm_params?.mode);(u.length!==t.length||u.some((e,a)=>e!==t[a]))&&(e.litellm_params.mode=u),h!==s.litellm_params?.default_on&&(e.litellm_params.default_on=h),await (0,m.updateGuardrailCall)(i,s.guardrail_id,e),y.default.success("Custom code guardrail updated successfully")}else await (0,m.createGuardrailCall)(i,{guardrail_name:o,litellm_params:{guardrail:"custom_code",mode:u,default_on:h,custom_code:b},guardrail_info:{}}),y.default.success("Custom code guardrail created successfully");a(),t()}catch(e){console.error("Failed to save guardrail:",e),y.default.fromBackend(`Failed to ${n?"update":"create"} guardrail: `+(e instanceof Error?e.message:String(e)))}finally{N(!1)}},K=async()=>{if(!i)return void F({error:"No access token available"});S(!0),F(null);try{let e;try{e=JSON.parse(P)}catch(e){F({error:"Invalid test input JSON"}),S(!1);return}e.texts||(e.texts=[]);let t=["pre_call","pre_mcp_call"],a=["post_call","post_mcp_call"],l=u.some(e=>t.includes(e))?"request":u.some(e=>a.includes(e))?"response":"request",r=await (0,m.testCustomCodeGuardrail)(i,{custom_code:b,test_input:e,input_type:l,request_data:{model:"test-model",metadata:{}}});r.success&&r.result?F(r.result):r.error?F({error:r.error,error_type:r.error_type}):F({error:"Unknown error occurred"})}catch(e){console.error("Failed to test custom code:",e),F({error:e instanceof Error?e.message:"Failed to test custom code"})}finally{S(!1)}},q=b.split("\n").length;return(0,l.jsxs)(g.Modal,{open:e,onCancel:t,footer:null,width:1400,className:"custom-code-modal",closable:!0,destroyOnClose:!0,children:[(0,l.jsxs)("div",{className:"flex flex-col h-[80vh]",children:[(0,l.jsxs)("div",{className:"pb-4 border-b border-gray-200",children:[(0,l.jsx)("h2",{className:"text-xl font-semibold text-gray-900",children:n?"Edit Custom Guardrail":"Create Custom Guardrail"}),(0,l.jsx)("p",{className:"text-sm text-gray-500 mt-1",children:"Define custom logic using Python-like syntax"})]}),(0,l.jsxs)("div",{className:"flex items-center gap-4 py-4 border-b border-gray-100",children:[(0,l.jsxs)("div",{className:"flex-1 max-w-[200px]",children:[(0,l.jsx)("label",{className:"block text-xs font-medium text-gray-600 mb-1",children:"Guardrail Name"}),(0,l.jsx)(tn.TextInput,{value:o,onValueChange:d,placeholder:"e.g., block-pii-custom"})]}),(0,l.jsxs)("div",{className:"w-[280px]",children:[(0,l.jsx)("label",{className:"block text-xs font-medium text-gray-600 mb-1",children:"Mode (can select multiple)"}),(0,l.jsx)(x.Select,{mode:"multiple",value:u,onChange:p,options:tU,className:"w-full",size:"middle",placeholder:"Select modes"})]}),(0,l.jsxs)("div",{className:"w-[180px]",children:[(0,l.jsx)("label",{className:"block text-xs font-medium text-gray-600 mb-1",children:"Template"}),(0,l.jsx)(x.Select,{value:j,onChange:e=>{_(e),v(tq[e].code)},className:"w-full",size:"middle",dropdownRender:e=>(0,l.jsxs)(l.Fragment,{children:[e,(0,l.jsx)(eH.Divider,{style:{margin:"8px 0"}}),(0,l.jsxs)("div",{style:{padding:"8px 12px",cursor:"pointer",color:"#1890ff",fontSize:"12px",display:"flex",alignItems:"center",gap:"4px"},onClick:e=>{e.preventDefault(),window.open("https://models.litellm.ai/guardrails","_blank")},onMouseEnter:e=>{e.currentTarget.style.backgroundColor="#f0f0f0"},onMouseLeave:e=>{e.currentTarget.style.backgroundColor="transparent"},children:[(0,l.jsx)(tG,{}),(0,l.jsx)("span",{children:"Browse Community templates"}),(0,l.jsx)(tz.ExportOutlined,{style:{fontSize:"10px"}})]})]}),children:(0,l.jsx)(x.Select.OptGroup,{label:"STANDARD",children:Object.entries(tq).map(([e,t])=>(0,l.jsx)(x.Select.Option,{value:e,children:t.name},e))})})]}),(0,l.jsxs)("div",{className:"flex items-center gap-2 pt-5",children:[(0,l.jsx)("span",{className:"text-sm text-gray-600",children:"Default On"}),(0,l.jsx)(U.Switch,{checked:h,onChange:f})]})]}),(0,l.jsxs)("div",{className:"flex flex-1 overflow-hidden mt-4 gap-6",children:[(0,l.jsxs)("div",{className:"flex-2 flex flex-col min-w-0 overflow-y-auto",children:[(0,l.jsxs)("div",{className:"flex items-center justify-between mb-2 shrink-0",children:[(0,l.jsx)("span",{className:"text-xs font-semibold text-gray-500 uppercase tracking-wide",children:"Python Logic"}),(0,l.jsx)("span",{className:"text-xs text-gray-400",children:"Restricted environment (no imports)"})]}),(0,l.jsxs)("div",{className:"relative rounded-lg overflow-hidden border border-gray-700 bg-[#1e1e1e] shrink-0",style:{minHeight:"300px",maxHeight:"400px"},children:[(0,l.jsx)("div",{className:"absolute left-0 top-0 bottom-0 w-12 bg-[#1e1e1e] border-r border-gray-700 text-right pr-3 pt-3 select-none overflow-hidden",style:{fontFamily:"'Fira Code', 'Monaco', 'Consolas', monospace",fontSize:"14px",lineHeight:"1.6"},children:Array.from({length:Math.max(q,20)},(e,t)=>(0,l.jsx)("div",{className:"text-gray-500 h-[22.4px]",children:t+1},t+1))}),(0,l.jsx)("textarea",{ref:M,value:b,onChange:e=>v(e.target.value),onKeyDown:e=>{if("Tab"===e.key){e.preventDefault();let t=e.currentTarget,a=t.selectionStart,l=t.selectionEnd;v(b.substring(0,a)+" "+b.substring(l)),setTimeout(()=>{t.selectionStart=t.selectionEnd=a+4},0)}},spellCheck:!1,className:"w-full h-full pl-14 pr-4 pt-3 pb-3 resize-none focus:outline-hidden bg-transparent text-gray-200",style:{fontFamily:"'Fira Code', 'Monaco', 'Consolas', monospace",fontSize:"14px",lineHeight:"1.6",tabSize:4}})]}),(0,l.jsx)(G.Collapse,{activeKey:k?["test"]:[],onChange:e=>I(e.includes("test")),className:"mt-3 bg-white border border-gray-200 rounded-lg shrink-0",expandIcon:({isActive:e})=>(0,l.jsx)(tE,{rotate:90*!!e}),children:(0,l.jsx)(tD,{header:(0,l.jsxs)("span",{className:"flex items-center gap-2 text-sm font-medium",children:[(0,l.jsx)(tL.PlayCircleOutlined,{className:"text-blue-500"}),"Test Your Guardrail"]}),children:(0,l.jsxs)("div",{className:"space-y-3",children:[(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,l.jsx)("label",{className:"block text-xs font-medium text-gray-600",children:"Test Input (JSON)"}),(0,l.jsxs)("div",{className:"flex items-center gap-2",children:[(0,l.jsx)("span",{className:"text-xs text-gray-500",children:"Load example:"}),(0,l.jsx)("button",{type:"button",onClick:()=>L(JSON.stringify(A,null,2)),className:"px-2 py-1 text-xs rounded-sm border border-orange-200 bg-orange-50 text-orange-700 hover:bg-orange-100 transition-colors",children:"Pre-call"}),(0,l.jsx)("button",{type:"button",onClick:()=>L(JSON.stringify(T,null,2)),className:"px-2 py-1 text-xs rounded-sm border border-purple-200 bg-purple-50 text-purple-700 hover:bg-purple-100 transition-colors",children:"Pre MCP"}),(0,l.jsx)("button",{type:"button",onClick:()=>L(JSON.stringify(O,null,2)),className:"px-2 py-1 text-xs rounded-sm border border-green-200 bg-green-50 text-green-700 hover:bg-green-100 transition-colors",children:"Post-call"})]})]}),(0,l.jsx)("div",{className:"mb-2 p-2 bg-gray-50 rounded-sm text-xs text-gray-600 border border-gray-200",children:(0,l.jsxs)("div",{className:"grid grid-cols-2 gap-x-4 gap-y-1",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("strong",{children:"texts"}),": Message content (always)"]}),(0,l.jsxs)("div",{children:[(0,l.jsx)("strong",{children:"images"}),": Base64 images (vision)"]}),(0,l.jsxs)("div",{children:[(0,l.jsx)("strong",{children:"tools"}),": Tool definitions ",(0,l.jsx)("span",{className:"text-orange-600",children:"(pre_call)"}),", MCP as OpenAI tool ",(0,l.jsx)("span",{className:"text-purple-600",children:"(pre_mcp_call)"})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)("strong",{children:"tool_calls"}),": LLM tool calls"," ",(0,l.jsx)("span",{className:"text-green-600",children:"(post_call)"})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)("strong",{children:"structured_messages"}),": Full messages"," ",(0,l.jsx)("span",{className:"text-orange-600",children:"(pre_call)"})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)("strong",{children:"model"}),": Model name (always)"]})]})}),(0,l.jsx)(tK,{value:P,onChange:e=>L(e.target.value),rows:8,className:"font-mono text-xs",placeholder:'{"texts": ["test message"], ...}'})]}),(0,l.jsxs)("div",{className:"flex items-center gap-3",children:[(0,l.jsx)(e9.Button,{size:"xs",onClick:K,disabled:C,icon:tL.PlayCircleOutlined,children:C?"Running...":"Run Test"}),B&&(0,l.jsx)("div",{className:`flex items-center gap-2 text-sm ${B.error?"text-red-600":"allow"===B.action?"text-green-600":"block"===B.action?"text-orange-600":"text-blue-600"}`,children:B.error?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(tF.CloseCircleOutlined,{}),(0,l.jsxs)("span",{children:[B.error_type&&(0,l.jsxs)("span",{className:"font-medium",children:["[",B.error_type,"] "]}),B.error]})]}):"allow"===B.action?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(tB.CheckCircleOutlined,{})," Allowed"]}):"block"===B.action?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(tF.CloseCircleOutlined,{})," Blocked: ",B.reason]}):"modify"===B.action?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(tB.CheckCircleOutlined,{})," Modified",B.texts&&B.texts.length>0&&(0,l.jsxs)("span",{className:"text-xs text-gray-500 ml-1",children:["→ ",B.texts[0].substring(0,50),B.texts[0].length>50?"...":""]})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(tB.CheckCircleOutlined,{})," ",B.action||"Unknown"]})})]})]})},"test")}),(0,l.jsxs)("div",{className:"mt-3 p-4 bg-linear-to-r from-blue-50 to-indigo-50 border border-blue-200 rounded-lg flex items-center justify-between shrink-0",children:[(0,l.jsxs)("div",{className:"flex items-center gap-3",children:[(0,l.jsx)("div",{className:"bg-blue-100 rounded-full p-2",children:(0,l.jsx)(tG,{className:"text-blue-600 text-lg"})}),(0,l.jsxs)("div",{children:[(0,l.jsx)("div",{className:"text-sm font-medium text-gray-900",children:"Built a useful guardrail?"}),(0,l.jsx)("div",{className:"text-xs text-gray-600",children:"Share it with the community and help others build faster"})]})]}),(0,l.jsx)(e9.Button,{size:"xs",onClick:()=>window.open("https://github.com/BerriAI/litellm-guardrails","_blank"),icon:tz.ExportOutlined,className:"bg-blue-600 hover:bg-blue-700 text-white border-0",children:"Contribute Template"})]})]}),(0,l.jsxs)("div",{className:"w-[300px] shrink-0 overflow-auto border-l border-gray-200 pl-6",children:[(0,l.jsxs)("div",{className:"flex items-center gap-2 mb-3",children:[(0,l.jsx)(c.CodeOutlined,{className:"text-blue-500"}),(0,l.jsx)("span",{className:"font-semibold text-gray-700",children:"Available Primitives"})]}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mb-3",children:"Click to copy functions to clipboard"}),(0,l.jsx)(G.Collapse,{defaultActiveKey:["Return Values"],className:"primitives-collapse bg-transparent border-0",expandIconPosition:"end",children:Object.entries(tH).map(([e,t])=>(0,l.jsx)(tD,{header:(0,l.jsx)("span",{className:"text-sm font-medium text-gray-700",children:e}),className:"bg-white mb-2 rounded-lg border border-gray-200",children:(0,l.jsx)("div",{className:"space-y-2",children:t.map(e=>(0,l.jsx)("button",{onClick:()=>z(e.name),className:`w-full text-left px-2 py-2 rounded transition-colors ${$===e.name?"bg-green-100":"bg-gray-50 hover:bg-blue-50"}`,children:$===e.name?(0,l.jsxs)("span",{className:"flex items-center gap-1 text-xs font-mono text-green-700",children:[(0,l.jsx)(tB.CheckCircleOutlined,{})," Copied!"]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("div",{className:"text-xs font-mono text-gray-800",children:e.name}),(0,l.jsx)("div",{className:"text-[10px] text-gray-500 mt-0.5",children:e.desc})]})},e.name))})},e))})]})]}),(0,l.jsxs)("div",{className:"flex items-center justify-between pt-4 mt-4 border-t border-gray-200",children:[(0,l.jsx)("span",{className:"text-xs text-gray-400",children:"Changes are auto-saved to local draft"}),(0,l.jsxs)("div",{className:"flex items-center gap-3",children:[(0,l.jsx)(e9.Button,{variant:"secondary",onClick:t,children:"Cancel"}),(0,l.jsx)(e9.Button,{onClick:D,loading:w,disabled:w||!o.trim(),icon:tM.SaveOutlined,children:n?"Update Guardrail":"Save Guardrail"})]})]})]}),(0,l.jsx)("style",{children:` + .custom-code-modal .ant-modal-content { + padding: 24px; + } + .custom-code-modal .ant-modal-close { + top: 20px; + right: 20px; + } + .primitives-collapse .ant-collapse-item { + border: none !important; + } + .primitives-collapse .ant-collapse-header { + padding: 8px 12px !important; + } + .primitives-collapse .ant-collapse-content-box { + padding: 8px 12px !important; + } + `})]})},tW=({guardrailId:e,onClose:t,accessToken:a,isAdmin:s})=>{let n,[o,d]=(0,r.useState)(null),[g,h]=(0,r.useState)(null),[f,j]=(0,r.useState)(!0),[_,b]=(0,r.useState)(!1),[v]=u.Form.useForm(),[w,N]=(0,r.useState)([]),[C,S]=(0,r.useState)({}),[k,I]=(0,r.useState)(null),[A,O]=(0,r.useState)({}),[T,P]=(0,r.useState)(!1),L={rules:[],default_action:"deny",on_disallowed_action:"block",violation_message_template:""},[B,F]=(0,r.useState)(L),[$,E]=(0,r.useState)(!1),[M,R]=(0,r.useState)(!1),G=r.default.useRef({patterns:[],blockedWords:[],categories:[]}),z=(0,r.useCallback)((e,t,a,l,r)=>{G.current={patterns:e,blockedWords:t,categories:a||[],competitorIntentEnabled:l,competitorIntentConfig:r}},[]),D=async()=>{try{if(j(!0),!a)return;let t=await (0,m.getGuardrailInfo)(a,e);if(d(t),t.litellm_params?.pii_entities_config){let e=t.litellm_params.pii_entities_config;if(N([]),S({}),Object.keys(e).length>0){let t=[],a={};Object.entries(e).forEach(([e,l])=>{t.push(e),a[e]="string"==typeof l?l:"MASK"}),N(t),S(a)}}else N([]),S({})}catch(e){y.default.fromBackend("Failed to load guardrail information"),console.error("Error fetching guardrail info:",e)}finally{j(!1)}},K=async()=>{try{if(!a)return;let e=await (0,m.getGuardrailProviderSpecificParams)(a);h(e)}catch(e){console.error("Error fetching guardrail provider specific params:",e)}},q=async()=>{try{if(!a)return;let e=await (0,m.getGuardrailUISettings)(a);I(e)}catch(e){console.error("Error fetching guardrail UI settings:",e)}};(0,r.useEffect)(()=>{K()},[a]),(0,r.useEffect)(()=>{D(),q()},[e,a]),(0,r.useEffect)(()=>{if(o&&v){let e={...o.litellm_params||{}};delete e.skip_system_message_in_guardrail,delete e.skip_tool_message_in_guardrail,v.setFieldsValue({guardrail_name:o.guardrail_name,...e,skip_system_message_choice:ex(o.litellm_params?.skip_system_message_in_guardrail),skip_tool_message_choice:eh(o.litellm_params?.skip_tool_message_in_guardrail),guardrail_info:o.guardrail_info?JSON.stringify(o.guardrail_info,null,2):"",...o.litellm_params?.optional_params&&{optional_params:o.litellm_params.optional_params}})}},[o,g,v]);let H=(0,r.useCallback)(()=>{o?.litellm_params?.guardrail==="tool_permission"?F({rules:o.litellm_params?.rules||[],default_action:(o.litellm_params?.default_action||"deny").toLowerCase(),on_disallowed_action:(o.litellm_params?.on_disallowed_action||"block").toLowerCase(),violation_message_template:o.litellm_params?.violation_message_template||""}):F(L),E(!1)},[o]);(0,r.useEffect)(()=>{H()},[H]);let U=async t=>{try{if(!a)return;let d={litellm_params:{}};t.guardrail_name!==o.guardrail_name&&(d.guardrail_name=t.guardrail_name),t.default_on!==o.litellm_params?.default_on&&(d.litellm_params.default_on=t.default_on);let c=ex(o.litellm_params?.skip_system_message_in_guardrail),u=t.skip_system_message_choice;void 0!==u&&u!==c&&("inherit"===u?d.litellm_params.skip_system_message_in_guardrail=null:"yes"===u?d.litellm_params.skip_system_message_in_guardrail=!0:d.litellm_params.skip_system_message_in_guardrail=!1);let p=eh(o.litellm_params?.skip_tool_message_in_guardrail),x=t.skip_tool_message_choice;void 0!==x&&x!==p&&("inherit"===x?d.litellm_params.skip_tool_message_in_guardrail=null:"yes"===x?d.litellm_params.skip_tool_message_in_guardrail=!0:d.litellm_params.skip_tool_message_in_guardrail=!1);let h=o.guardrail_info,f=t.guardrail_info?JSON.parse(t.guardrail_info):void 0;JSON.stringify(h)!==JSON.stringify(f)&&(d.guardrail_info=f);let j=o.litellm_params?.pii_entities_config||{},_={};if(w.forEach(e=>{_[e]=C[e]||"MASK"}),JSON.stringify(j)!==JSON.stringify(_)&&(d.litellm_params.pii_entities_config=_),o.litellm_params?.guardrail==="litellm_content_filter"&&T){var l,r,i,s,n;let e,t=(l=G.current.patterns||[],r=G.current.blockedWords||[],i=G.current.categories||[],s=G.current.competitorIntentEnabled,n=G.current.competitorIntentConfig,e={patterns:l.map(e=>({pattern_type:"prebuilt"===e.type?"prebuilt":"regex",pattern_name:"prebuilt"===e.type?e.name:void 0,pattern:"custom"===e.type?e.pattern:void 0,name:e.name,action:e.action})),blocked_words:r.map(e=>({keyword:e.keyword,action:e.action,description:e.description}))},void 0!==i&&(e.categories=i.map(e=>({category:e.category,enabled:!0,action:e.action,severity_threshold:e.severity_threshold||"medium"}))),s&&n&&n.brand_self.length>0&&(e.competitor_intent_config={competitor_intent_type:n.competitor_intent_type,brand_self:n.brand_self,locations:n.locations?.length?n.locations:void 0,competitors:"generic"===n.competitor_intent_type&&n.competitors?.length?n.competitors:void 0,policy:n.policy,threshold_high:n.threshold_high,threshold_medium:n.threshold_medium,threshold_low:n.threshold_low}),e);d.litellm_params.patterns=t.patterns,d.litellm_params.blocked_words=t.blocked_words,d.litellm_params.categories=t.categories,d.litellm_params.competitor_intent_config=t.competitor_intent_config??null}if(o.litellm_params?.guardrail==="tool_permission"){let e=o.litellm_params?.rules||[],t=B.rules||[],a=JSON.stringify(e)!==JSON.stringify(t),l=(o.litellm_params?.default_action||"deny").toLowerCase(),r=(B.default_action||"deny").toLowerCase(),i=l!==r,s=(o.litellm_params?.on_disallowed_action||"block").toLowerCase(),n=(B.on_disallowed_action||"block").toLowerCase(),c=s!==n,m=o.litellm_params?.violation_message_template||"",u=B.violation_message_template||"",p=m!==u;($||a||i||c||p)&&(d.litellm_params.rules=t,d.litellm_params.default_action=r,d.litellm_params.on_disallowed_action=n,d.litellm_params.violation_message_template=u||null)}let v=Object.keys(en).find(e=>en[e]===o.litellm_params?.guardrail),N=o.litellm_params?.guardrail==="tool_permission";if(g&&v&&!N){let e=g[en[v]?.toLowerCase()]||{},a=new Set;Object.keys(e).forEach(e=>{"optional_params"!==e&&a.add(e)}),e.optional_params&&e.optional_params.fields&&Object.keys(e.optional_params.fields).forEach(e=>{a.add(e)}),a.forEach(e=>{if("patterns"===e||"blocked_words"===e||"categories"===e)return;let a=t[e];(null==a||""===a)&&(a=t.optional_params?.[e]);let l=o.litellm_params?.[e];JSON.stringify(a)!==JSON.stringify(l)&&(null!=a&&""!==a?d.litellm_params[e]=a:null!=l&&""!==l&&(d.litellm_params[e]=null))})}if(0===Object.keys(d.litellm_params).length&&delete d.litellm_params,0===Object.keys(d).length){y.default.info("No changes detected"),b(!1);return}await (0,m.updateGuardrailCall)(a,e,d),y.default.success("Guardrail updated successfully"),P(!1),D(),b(!1)}catch(e){console.error("Error updating guardrail:",e),y.default.fromBackend("Failed to update guardrail")}};if(f)return(0,l.jsx)("div",{className:"p-4",children:"Loading..."});if(!o)return(0,l.jsx)("div",{className:"p-4",children:"Guardrail not found"});let J=e=>e?new Date(e).toLocaleString():"-",{logo:W,displayName:V}=eg(o.litellm_params?.guardrail||""),Y=async(e,t)=>{await (0,tx.copyToClipboard)(e)&&(O(e=>({...e,[t]:!0})),setTimeout(()=>{O(e=>({...e,[t]:!1}))},2e3))},Q="config"===o.guardrail_definition_location;return(0,l.jsxs)("div",{className:"p-4",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)(i.Button,{type:"text",icon:(0,l.jsx)(th.ArrowLeftIcon,{className:"w-4 h-4"}),onClick:t,className:"mb-4",children:"Back to Guardrails"}),(0,l.jsx)(tw.Title,{children:o.guardrail_name||"Unnamed Guardrail"}),(0,l.jsxs)("div",{className:"flex items-center cursor-pointer",children:[(0,l.jsx)(eq.Text,{className:"text-gray-500 font-mono",children:o.guardrail_id}),(0,l.jsx)(i.Button,{type:"text",size:"small",icon:A["guardrail-id"]?(0,l.jsx)(tN.CheckIcon,{size:12}):(0,l.jsx)(tC.CopyIcon,{size:12}),onClick:()=>Y(o.guardrail_id,"guardrail-id"),className:`left-2 z-10 transition-all duration-200 ${A["guardrail-id"]?"text-green-600 bg-green-50 border-green-200":"text-gray-500 hover:text-gray-700 hover:bg-gray-100"}`})]})]}),(0,l.jsxs)(tj.TabGroup,{children:[(0,l.jsxs)(t_.TabList,{className:"mb-4",children:[(0,l.jsx)(ty.Tab,{children:"Overview"},"overview"),s?(0,l.jsx)(ty.Tab,{children:"Settings"},"settings"):(0,l.jsx)(l.Fragment,{})]}),(0,l.jsxs)(tv.TabPanels,{children:[(0,l.jsxs)(tb.TabPanel,{children:[(0,l.jsxs)(tf.Grid,{numItems:1,numItemsSm:2,numItemsLg:3,className:"gap-6",children:[(0,l.jsxs)(eK.Card,{children:[(0,l.jsx)(eq.Text,{children:"Provider"}),(0,l.jsxs)("div",{className:"mt-2 flex items-center space-x-2",children:[W&&(0,l.jsx)("img",{src:W,alt:`${V} logo`,className:"w-6 h-6",onError:e=>{e.target.style.display="none"}}),(0,l.jsx)(tw.Title,{children:V})]})]}),(0,l.jsxs)(eK.Card,{children:[(0,l.jsx)(eq.Text,{children:"Mode"}),(0,l.jsxs)("div",{className:"mt-2",children:[(0,l.jsx)(tw.Title,{children:o.litellm_params?.mode||"-"}),(0,l.jsx)(tr.Badge,{color:o.litellm_params?.default_on?"green":"gray",children:o.litellm_params?.default_on?"Default On":"Default Off"})]})]}),(0,l.jsxs)(eK.Card,{children:[(0,l.jsx)(eq.Text,{children:"Created At"}),(0,l.jsxs)("div",{className:"mt-2",children:[(0,l.jsx)(tw.Title,{children:J(o.created_at)}),(0,l.jsxs)(eq.Text,{children:["Last Updated: ",J(o.updated_at)]})]})]})]}),o.litellm_params?.pii_entities_config&&Object.keys(o.litellm_params.pii_entities_config).length>0&&(0,l.jsx)(eK.Card,{className:"mt-6",children:(0,l.jsxs)("div",{className:"flex justify-between items-center",children:[(0,l.jsx)(eq.Text,{className:"font-medium",children:"PII Protection"}),(0,l.jsxs)(tr.Badge,{color:"blue",children:[Object.keys(o.litellm_params.pii_entities_config).length," PII entities configured"]})]})}),o.litellm_params?.pii_entities_config&&Object.keys(o.litellm_params.pii_entities_config).length>0&&(0,l.jsxs)(eK.Card,{className:"mt-6",children:[(0,l.jsx)(eq.Text,{className:"mb-4 text-lg font-semibold",children:"PII Entity Configuration"}),(0,l.jsxs)("div",{className:"border rounded-lg overflow-hidden shadow-xs",children:[(0,l.jsxs)("div",{className:"bg-gray-50 px-5 py-3 border-b flex",children:[(0,l.jsx)(eq.Text,{className:"flex-1 font-semibold text-gray-700",children:"Entity Type"}),(0,l.jsx)(eq.Text,{className:"flex-1 font-semibold text-gray-700",children:"Configuration"})]}),(0,l.jsx)("div",{className:"max-h-[400px] overflow-y-auto",children:Object.entries(o.litellm_params?.pii_entities_config).map(([e,t])=>(0,l.jsxs)("div",{className:"px-5 py-3 flex border-b hover:bg-gray-50 transition-colors",children:[(0,l.jsx)(eq.Text,{className:"flex-1 font-medium text-gray-900",children:e}),(0,l.jsx)(eq.Text,{className:"flex-1",children:(0,l.jsxs)("span",{className:`inline-flex items-center gap-1.5 ${"MASK"===t?"text-blue-600":"text-red-600"}`,children:["MASK"===t?(0,l.jsx)(eA.default,{}):(0,l.jsx)(eO.StopOutlined,{}),String(t)]})})]},e))})]})]}),o.litellm_params?.guardrail==="tool_permission"&&(0,l.jsx)(eK.Card,{className:"mt-6",children:(0,l.jsx)(eV,{value:B,disabled:!0})}),o.litellm_params?.guardrail==="custom_code"&&o.litellm_params?.custom_code&&(0,l.jsxs)(eK.Card,{className:"mt-6",children:[(0,l.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,l.jsxs)("div",{className:"flex items-center gap-2",children:[(0,l.jsx)(c.CodeOutlined,{className:"text-blue-500"}),(0,l.jsx)(eq.Text,{className:"font-medium text-lg",children:"Custom Code"})]}),s&&!Q&&(0,l.jsx)(i.Button,{size:"small",icon:(0,l.jsx)(c.CodeOutlined,{}),onClick:()=>R(!0),children:"Edit Code"})]}),(0,l.jsx)("div",{className:"relative rounded-lg overflow-hidden border border-gray-700 bg-[#1e1e1e]",children:(0,l.jsx)("pre",{className:"p-4 text-sm text-gray-200 overflow-x-auto",style:{fontFamily:"'Fira Code', 'Monaco', 'Consolas', monospace"},children:(0,l.jsx)("code",{children:o.litellm_params.custom_code})})})]}),(0,l.jsx)(tP,{guardrailData:o,guardrailSettings:k,isEditing:!1,accessToken:a})]}),s&&(0,l.jsx)(tb.TabPanel,{children:(0,l.jsxs)(eK.Card,{children:[(0,l.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,l.jsx)(tw.Title,{children:"Guardrail Settings"}),Q&&(0,l.jsx)(eN.Tooltip,{title:"Guardrail is defined in the config file and cannot be edited.",children:(0,l.jsx)(eJ.InfoCircleOutlined,{})}),!_&&!Q&&(o.litellm_params?.guardrail==="custom_code"?(0,l.jsx)(i.Button,{icon:(0,l.jsx)(c.CodeOutlined,{}),onClick:()=>R(!0),children:"Edit Code"}):(0,l.jsx)(i.Button,{onClick:()=>b(!0),children:"Edit Settings"}))]}),_?(0,l.jsxs)(u.Form,{form:v,onFinish:U,initialValues:{guardrail_name:o.guardrail_name,...(n={...o.litellm_params||{}},delete n.skip_system_message_in_guardrail,delete n.skip_tool_message_in_guardrail,n),skip_system_message_choice:ex(o.litellm_params?.skip_system_message_in_guardrail),skip_tool_message_choice:eh(o.litellm_params?.skip_tool_message_in_guardrail),guardrail_info:o.guardrail_info?JSON.stringify(o.guardrail_info,null,2):"",...o.litellm_params?.optional_params&&{optional_params:o.litellm_params.optional_params}},layout:"vertical",children:[(0,l.jsx)(u.Form.Item,{label:"Guardrail Name",name:"guardrail_name",rules:[{required:!0,message:"Please input a guardrail name"}],children:(0,l.jsx)(p.Input,{placeholder:"Enter guardrail name"})}),(0,l.jsx)(u.Form.Item,{label:"Default On",name:"default_on",children:(0,l.jsxs)(x.Select,{children:[(0,l.jsx)(x.Select.Option,{value:!0,children:"Yes"}),(0,l.jsx)(x.Select.Option,{value:!1,children:"No"})]})}),(0,l.jsx)(u.Form.Item,{label:"Skip system messages in guardrail",name:"skip_system_message_choice",tooltip:"Unified guardrails: omit role: system from guardrail input (LLM still gets full messages). Use global default follows litellm_settings.skip_system_message_in_guardrail.",children:(0,l.jsxs)(x.Select,{children:[(0,l.jsx)(x.Select.Option,{value:"inherit",children:"Use global default"}),(0,l.jsx)(x.Select.Option,{value:"yes",children:"Yes — exclude from guardrail scan"}),(0,l.jsx)(x.Select.Option,{value:"no",children:"No — always include in scan"})]})}),(0,l.jsx)(u.Form.Item,{label:"Skip tool messages in guardrail",name:"skip_tool_message_choice",tooltip:"Unified guardrails: omit role: tool from guardrail input (LLM still gets full messages). Use global default follows litellm_settings.skip_tool_message_in_guardrail.",children:(0,l.jsxs)(x.Select,{children:[(0,l.jsx)(x.Select.Option,{value:"inherit",children:"Use global default"}),(0,l.jsx)(x.Select.Option,{value:"yes",children:"Yes — exclude from guardrail scan"}),(0,l.jsx)(x.Select.Option,{value:"no",children:"No — always include in scan"})]})}),o.litellm_params?.guardrail==="presidio"&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(eH.Divider,{orientation:"left",children:"PII Protection"}),(0,l.jsx)("div",{className:"mb-6",children:k&&(0,l.jsx)(eD,{entities:k.supported_entities,actions:k.supported_actions,selectedEntities:w,selectedActions:C,onEntitySelect:e=>{N(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e])},onActionSelect:(e,t)=>{S(a=>({...a,[e]:t}))},entityCategories:k.pii_entity_categories})})]}),(0,l.jsx)(tP,{guardrailData:o,guardrailSettings:k,isEditing:!0,accessToken:a,onDataChange:z,onUnsavedChanges:P}),(o.litellm_params?.guardrail==="tool_permission"||g)&&(0,l.jsx)(eH.Divider,{orientation:"left",children:"Provider Settings"}),o.litellm_params?.guardrail==="tool_permission"?(0,l.jsx)(eV,{value:B,onChange:F}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(ew,{selectedProvider:Object.keys(en).find(e=>en[e]===o.litellm_params?.guardrail)||null,accessToken:a,providerParams:g,value:o.litellm_params}),g&&(()=>{let e=Object.keys(en).find(e=>en[e]===o.litellm_params?.guardrail);if(!e)return null;let t=g[en[e]?.toLowerCase()];return t&&t.optional_params?(0,l.jsx)(e_,{optionalParams:t.optional_params,parentFieldKey:"optional_params",values:o.litellm_params}):null})()]}),(0,l.jsx)(eH.Divider,{orientation:"left",children:"Advanced Settings"}),(0,l.jsx)(u.Form.Item,{label:"Guardrail Information",name:"guardrail_info",children:(0,l.jsx)(p.Input.TextArea,{rows:5})}),(0,l.jsxs)("div",{className:"flex justify-end gap-2 mt-6",children:[(0,l.jsx)(i.Button,{onClick:()=>{b(!1),P(!1),H()},children:"Cancel"}),(0,l.jsx)(i.Button,{type:"primary",htmlType:"submit",children:"Save Changes"})]})]}):(0,l.jsxs)("div",{className:"space-y-4",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)(eq.Text,{className:"font-medium",children:"Guardrail ID"}),(0,l.jsx)("div",{className:"font-mono",children:o.guardrail_id})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(eq.Text,{className:"font-medium",children:"Guardrail Name"}),(0,l.jsx)("div",{children:o.guardrail_name||"Unnamed Guardrail"})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(eq.Text,{className:"font-medium",children:"Provider"}),(0,l.jsx)("div",{children:V})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(eq.Text,{className:"font-medium",children:"Mode"}),(0,l.jsx)("div",{children:o.litellm_params?.mode||"-"})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(eq.Text,{className:"font-medium",children:"Default On"}),(0,l.jsx)(tr.Badge,{color:o.litellm_params?.default_on?"green":"gray",children:o.litellm_params?.default_on?"Yes":"No"})]}),o.litellm_params?.pii_entities_config&&Object.keys(o.litellm_params.pii_entities_config).length>0&&(0,l.jsxs)("div",{children:[(0,l.jsx)(eq.Text,{className:"font-medium",children:"PII Protection"}),(0,l.jsx)("div",{className:"mt-2",children:(0,l.jsxs)(tr.Badge,{color:"blue",children:[Object.keys(o.litellm_params.pii_entities_config).length," PII entities configured"]})})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(eq.Text,{className:"font-medium",children:"Created At"}),(0,l.jsx)("div",{children:J(o.created_at)})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)(eq.Text,{className:"font-medium",children:"Last Updated"}),(0,l.jsx)("div",{children:J(o.updated_at)})]}),o.litellm_params?.guardrail==="tool_permission"&&(0,l.jsx)(eV,{value:B,disabled:!0})]})]})})]})]}),(0,l.jsx)(tJ,{visible:M,onClose:()=>R(!1),onSuccess:()=>{R(!1),D()},accessToken:a,editData:o?{guardrail_id:o.guardrail_id,guardrail_name:o.guardrail_name,litellm_params:o.litellm_params}:null})]})};var tV=e.i(573421),tY=e.i(19732),tQ=e.i(928685),tX=e.i(166406),tZ=e.i(637235),t0=e.i(240647);let{Text:t1}=f.Typography,t2=function({results:e,errors:t}){let[a,i]=(0,r.useState)(new Set),s=e=>{let t=new Set(a);t.has(e)?t.delete(e):t.add(e),i(t)},n=async e=>{try{if(navigator.clipboard&&window.isSecureContext)return await navigator.clipboard.writeText(e),!0;{let t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.focus(),t.select();let a=document.execCommand("copy");if(document.body.removeChild(t),!a)throw Error("execCommand failed");return!0}}catch(e){return console.error("Copy failed:",e),!1}};return e||t?(0,l.jsxs)("div",{className:"space-y-3 pt-4 border-t border-gray-200",children:[(0,l.jsx)("h3",{className:"text-sm font-semibold text-gray-900",children:"Results"}),e&&e.map(e=>{let t=a.has(e.guardrailName);return(0,l.jsx)(eK.Card,{className:"bg-green-50 border-green-200",children:(0,l.jsxs)("div",{className:"space-y-3",children:[(0,l.jsxs)("div",{className:"flex items-center justify-between",children:[(0,l.jsxs)("div",{className:"flex items-center space-x-2 cursor-pointer flex-1",onClick:()=>s(e.guardrailName),children:[t?(0,l.jsx)(t0.RightOutlined,{className:"text-gray-500 text-xs"}):(0,l.jsx)(o.DownOutlined,{className:"text-gray-500 text-xs"}),(0,l.jsx)(tB.CheckCircleOutlined,{className:"text-green-600 text-lg"}),(0,l.jsx)("span",{className:"text-sm font-medium text-green-800",children:e.guardrailName})]}),(0,l.jsxs)("div",{className:"flex items-center gap-3",children:[(0,l.jsxs)("div",{className:"flex items-center space-x-1 text-xs text-gray-600",children:[(0,l.jsx)(tZ.ClockCircleOutlined,{}),(0,l.jsxs)("span",{className:"font-medium",children:[e.latency,"ms"]})]}),!t&&(0,l.jsx)(e9.Button,{size:"xs",variant:"secondary",icon:tX.CopyOutlined,onClick:async()=>{await n(e.response_text)?y.default.success("Result copied to clipboard"):y.default.fromBackend("Failed to copy result")},children:"Copy"})]})]}),!t&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)("div",{className:"bg-white border border-green-200 rounded-sm p-3",children:[(0,l.jsx)("label",{className:"text-xs font-medium text-gray-600 mb-2 block",children:"Output Text"}),(0,l.jsx)("div",{className:"font-mono text-sm text-gray-900 whitespace-pre-wrap wrap-break-word",children:e.response_text})]}),(0,l.jsxs)("div",{className:"text-xs text-gray-600",children:[(0,l.jsx)("span",{className:"font-medium",children:"Characters:"})," ",e.response_text.length]})]})]})},e.guardrailName)}),t&&t.map(e=>{let t=a.has(e.guardrailName);return(0,l.jsx)(eK.Card,{className:"bg-red-50 border-red-200",children:(0,l.jsxs)("div",{className:"flex items-start space-x-2",children:[(0,l.jsx)("div",{className:"cursor-pointer mt-0.5",onClick:()=>s(e.guardrailName),children:t?(0,l.jsx)(t0.RightOutlined,{className:"text-gray-500 text-xs"}):(0,l.jsx)(o.DownOutlined,{className:"text-gray-500 text-xs"})}),(0,l.jsx)("div",{className:"text-red-600 mt-0.5",children:(0,l.jsx)("svg",{className:"w-5 h-5",fill:"currentColor",viewBox:"0 0 20 20",children:(0,l.jsx)("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z",clipRule:"evenodd"})})}),(0,l.jsxs)("div",{className:"flex-1",children:[(0,l.jsxs)("div",{className:"flex items-center justify-between mb-1",children:[(0,l.jsxs)("p",{className:"text-sm font-medium text-red-800 cursor-pointer",onClick:()=>s(e.guardrailName),children:[e.guardrailName," - Error"]}),(0,l.jsxs)("div",{className:"flex items-center space-x-1 text-xs text-gray-600",children:[(0,l.jsx)(tZ.ClockCircleOutlined,{}),(0,l.jsxs)("span",{className:"font-medium",children:[e.latency,"ms"]})]})]}),!t&&(0,l.jsx)("p",{className:"text-sm text-red-700 mt-1",children:e.error.message})]})]})},e.guardrailName)})]}):null},{TextArea:t4}=p.Input,{Text:t5}=f.Typography,t8=function({guardrailNames:e,onSubmit:t,isLoading:a,results:i,errors:s,onClose:n}){let[o,d]=(0,r.useState)(""),c=()=>{o.trim()?t(o):y.default.fromBackend("Please enter text to test")},m=async e=>{try{if(navigator.clipboard&&window.isSecureContext)return await navigator.clipboard.writeText(e),!0;{let t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.focus(),t.select();let a=document.execCommand("copy");if(document.body.removeChild(t),!a)throw Error("execCommand failed");return!0}}catch(e){return console.error("Copy failed:",e),!1}},u=async()=>{await m(o)?y.default.success("Input copied to clipboard"):y.default.fromBackend("Failed to copy input")};return(0,l.jsxs)("div",{className:"space-y-4 h-full flex flex-col",children:[(0,l.jsx)("div",{className:"flex items-center justify-between pb-3 border-b border-gray-200",children:(0,l.jsx)("div",{className:"flex items-center space-x-3",children:(0,l.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,l.jsxs)("div",{className:"flex items-center space-x-2 mb-1",children:[(0,l.jsx)("h2",{className:"text-lg font-semibold text-gray-900",children:"Test Guardrails:"}),(0,l.jsx)("div",{className:"flex flex-wrap gap-2",children:e.map(e=>(0,l.jsx)("div",{className:"inline-flex items-center space-x-1 bg-blue-50 px-3 py-1 rounded-md border border-blue-200",children:(0,l.jsx)("span",{className:"font-mono text-blue-700 font-medium text-sm",children:e})},e))})]}),(0,l.jsxs)("p",{className:"text-sm text-gray-500",children:["Test ",e.length>1?"guardrails":"guardrail"," and compare results"]})]})})}),(0,l.jsxs)("div",{className:"flex-1 overflow-auto space-y-4",children:[(0,l.jsxs)("div",{className:"space-y-3",children:[(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{className:"flex justify-between items-center mb-2",children:[(0,l.jsxs)("div",{className:"flex items-center gap-2",children:[(0,l.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Input Text"}),(0,l.jsx)(eN.Tooltip,{title:"Press Enter to submit. Use Shift+Enter for new line.",children:(0,l.jsx)(eJ.InfoCircleOutlined,{className:"text-gray-400 cursor-help"})})]}),o&&(0,l.jsx)(e9.Button,{size:"xs",variant:"secondary",icon:tX.CopyOutlined,onClick:u,children:"Copy Input"})]}),(0,l.jsx)(t4,{value:o,onChange:e=>d(e.target.value),onKeyDown:e=>{"Enter"!==e.key||e.shiftKey||e.ctrlKey||e.metaKey||(e.preventDefault(),c())},placeholder:"Enter text to test with guardrails...",rows:8,className:"font-mono text-sm"}),(0,l.jsxs)("div",{className:"flex justify-between items-center mt-1",children:[(0,l.jsxs)(t5,{className:"text-xs text-gray-500",children:["Press ",(0,l.jsx)("kbd",{className:"px-1 py-0.5 bg-gray-100 border border-gray-300 rounded-sm text-xs",children:"Enter"})," to submit •"," ",(0,l.jsx)("kbd",{className:"px-1 py-0.5 bg-gray-100 border border-gray-300 rounded-sm text-xs",children:"Shift+Enter"})," for new line"]}),(0,l.jsxs)(t5,{className:"text-xs text-gray-500",children:["Characters: ",o.length]})]})]}),(0,l.jsx)("div",{className:"pt-2",children:(0,l.jsx)(e9.Button,{onClick:c,loading:a,disabled:!o.trim(),className:"w-full",children:a?`Testing ${e.length} guardrail${e.length>1?"s":""}...`:`Test ${e.length} guardrail${e.length>1?"s":""}`})})]}),(0,l.jsx)(t2,{results:i,errors:s})]})]})},t6=({guardrailsList:e,isLoading:t,accessToken:a,onClose:i})=>{let[s,n]=(0,r.useState)(new Set),[o,d]=(0,r.useState)(""),[c,u]=(0,r.useState)([]),[g,x]=(0,r.useState)([]),[h,j]=(0,r.useState)(!1),_=e.filter(e=>e.guardrail_name?.toLowerCase().includes(o.toLowerCase())),v=async e=>{if(0===s.size||!a)return;j(!0),u([]),x([]);let t=[],l=[];await Promise.all(Array.from(s).map(async r=>{let i=Date.now();try{let l=await (0,m.applyGuardrail)(a,r,e,null,null),s=Date.now()-i;t.push({guardrailName:r,response_text:l.response_text,latency:s})}catch(t){let e=Date.now()-i;console.error(`Error testing guardrail ${r}:`,t),l.push({guardrailName:r,error:t,latency:e})}})),u(t),x(l),j(!1),t.length>0&&y.default.success(`${t.length} guardrail${t.length>1?"s":""} applied successfully`),l.length>0&&y.default.fromBackend(`${l.length} guardrail${l.length>1?"s":""} failed`)};return(0,l.jsx)("div",{className:"w-full h-[calc(100vh-200px)]",children:(0,l.jsx)(b.Card,{className:"h-full",styles:{body:{padding:0,height:"100%"}},children:(0,l.jsxs)("div",{className:"flex h-full",children:[(0,l.jsxs)("div",{className:"w-1/4 border-r border-gray-200 flex flex-col overflow-hidden",children:[(0,l.jsx)("div",{className:"p-4 border-b border-gray-200",children:(0,l.jsxs)("div",{className:"mb-3",children:[(0,l.jsx)("h3",{className:"text-lg font-semibold mb-3",children:"Guardrails"}),(0,l.jsx)(p.Input,{prefix:(0,l.jsx)(tQ.SearchOutlined,{}),placeholder:"Search guardrails...",value:o,onChange:e=>d(e.target.value)})]})}),(0,l.jsx)("div",{className:"flex-1 overflow-auto",children:t?(0,l.jsx)("div",{className:"flex items-center justify-center h-32",children:(0,l.jsx)(eb.Spin,{})}):0===_.length?(0,l.jsx)("div",{className:"p-4",children:(0,l.jsx)(eU.Empty,{description:o?"No guardrails match your search":"No guardrails available"})}):(0,l.jsx)(tV.List,{dataSource:_,renderItem:e=>(0,l.jsx)(tV.List.Item,{onClick:()=>{var t;let a;e.guardrail_name&&(t=e.guardrail_name,(a=new Set(s)).has(t)?a.delete(t):a.add(t),n(a))},style:{paddingLeft:24,paddingRight:16},className:`cursor-pointer hover:bg-gray-50 transition-colors ${s.has(e.guardrail_name||"")?"bg-blue-50 border-l-4 border-l-blue-500":"border-l-4 border-l-transparent"}`,children:(0,l.jsx)(tV.List.Item.Meta,{title:(0,l.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,l.jsx)(tY.ExperimentOutlined,{className:"text-gray-400"}),(0,l.jsx)("span",{className:"font-medium text-gray-900",children:e.guardrail_name})]}),description:(0,l.jsxs)("div",{className:"text-xs space-y-1 mt-1",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("span",{className:"font-medium",children:"Type: "}),(0,l.jsx)("span",{className:"text-gray-600",children:e.litellm_params.guardrail})]}),(0,l.jsxs)("div",{children:[(0,l.jsx)("span",{className:"font-medium",children:"Mode: "}),(0,l.jsx)("span",{className:"text-gray-600",children:e.litellm_params.mode})]})]})})})})}),(0,l.jsx)("div",{className:"p-3 border-t border-gray-200 bg-gray-50",children:(0,l.jsxs)(f.Typography.Text,{className:"text-xs text-gray-600",children:[s.size," of ",_.length," selected"]})})]}),(0,l.jsxs)("div",{className:"w-3/4 flex flex-col bg-white",children:[(0,l.jsx)("div",{className:"p-4 border-b border-gray-200 flex justify-between items-center",children:(0,l.jsx)(f.Typography.Title,{level:2,className:"text-xl font-semibold mb-0",children:"Guardrail Testing Playground"})}),(0,l.jsx)("div",{className:"flex-1 overflow-auto p-4",children:0===s.size?(0,l.jsxs)("div",{className:"h-full flex flex-col items-center justify-center text-gray-400",children:[(0,l.jsx)(tY.ExperimentOutlined,{style:{fontSize:"48px",marginBottom:"16px"}}),(0,l.jsx)(f.Typography.Paragraph,{className:"text-lg font-medium text-gray-600 mb-2",children:"Select Guardrails to Test"}),(0,l.jsx)(f.Typography.Paragraph,{className:"text-center text-gray-500 max-w-md",children:"Choose one or more guardrails from the left sidebar to start testing and comparing results."})]}):(0,l.jsx)("div",{className:"h-full",children:(0,l.jsx)(t8,{guardrailNames:Array.from(s),onSubmit:v,results:c.length>0?c:null,errors:g.length>0?g:null,isLoading:h,onClose:()=>n(new Set)})})})]})]})})})};var t3=e.i(127952),t7=e.i(266537);let t9="/ui/assets/logos/",ae=[{id:"cf_denied_financial",name:"Denied Financial Advice",description:"Detects requests for personalized financial advice, investment recommendations, or financial planning.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Topic Blocker"],eval:{f1:100,precision:100,recall:100,testCases:207,latency:"<0.1ms"}},{id:"cf_denied_insults",name:"Insults & Personal Attacks",description:"Detects insults, name-calling, and personal attacks directed at the chatbot, staff, or other people.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Topic Blocker"],eval:{f1:100,precision:100,recall:100,testCases:299,latency:"<0.1ms"}},{id:"cf_denied_legal",name:"Denied Legal Advice",description:"Detects requests for unauthorized legal advice, case analysis, or legal recommendations.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Topic Blocker"]},{id:"cf_denied_medical",name:"Denied Medical Advice",description:"Detects requests for medical diagnosis, treatment recommendations, or health advice.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Topic Blocker"]},{id:"cf_harmful_violence",name:"Harmful Violence",description:"Detects content related to violence, criminal planning, attacks, and violent threats.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Safety"]},{id:"cf_harmful_self_harm",name:"Harmful Self-Harm",description:"Detects content related to self-harm, suicide, and dangerous self-destructive behavior.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Safety"]},{id:"cf_harmful_child_safety",name:"Harmful Child Safety",description:"Detects content that could endanger child safety or exploit minors.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Safety"]},{id:"cf_harmful_illegal_weapons",name:"Harmful Illegal Weapons",description:"Detects content related to illegal weapons manufacturing, distribution, or acquisition.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Safety"]},{id:"cf_bias_gender",name:"Bias: Gender",description:"Detects gender-based discrimination, stereotypes, and biased language.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Bias"]},{id:"cf_bias_racial",name:"Bias: Racial",description:"Detects racial discrimination, stereotypes, and racially biased content.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Bias"]},{id:"cf_bias_religious",name:"Bias: Religious",description:"Detects religious discrimination, intolerance, and religiously biased content.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Bias"]},{id:"cf_bias_sexual_orientation",name:"Bias: Sexual Orientation",description:"Detects discrimination based on sexual orientation and related biased content.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Bias"]},{id:"cf_prompt_injection_jailbreak",name:"Prompt Injection: Jailbreak",description:"Detects jailbreak attempts designed to bypass AI safety guidelines and restrictions.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Prompt Injection"]},{id:"cf_prompt_injection_data_exfil",name:"Prompt Injection: Data Exfiltration",description:"Detects attempts to extract sensitive data through prompt manipulation.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Prompt Injection"]},{id:"cf_prompt_injection_sql",name:"Prompt Injection: SQL",description:"Detects SQL injection attempts embedded in prompts.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Prompt Injection"]},{id:"cf_prompt_injection_malicious_code",name:"Prompt Injection: Malicious Code",description:"Detects attempts to inject malicious code through prompts.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Prompt Injection"]},{id:"cf_prompt_injection_system_prompt",name:"Prompt Injection: System Prompt",description:"Detects attempts to extract or override system prompts.",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Prompt Injection"]},{id:"cf_toxic_abuse",name:"Toxic & Abusive Language",description:"Detects toxic, abusive, and hateful language across multiple languages (EN, AU, DE, ES, FR).",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Toxicity"]},{id:"cf_patterns",name:"Pattern Matching",description:"Detect and block sensitive data patterns like SSNs, credit card numbers, API keys, and custom regex patterns.",category:"litellm",subcategory:"Patterns",logo:`${t9}litellm_logo.jpg`,tags:["PII","Regex","Data Protection"]},{id:"cf_keywords",name:"Keyword Blocking",description:"Block or mask content containing specific keywords or phrases. Upload custom word lists or add individual terms.",category:"litellm",subcategory:"Keywords",logo:`${t9}litellm_logo.jpg`,tags:["Keywords","Blocklist"]},{id:"block_code_execution",name:"Block Code Execution",description:"Detects markdown fenced code blocks in requests and responses. Block or mask executable code (e.g. Python, JavaScript, Bash) by language with configurable confidence.",category:"litellm",subcategory:"Code Safety",logo:`${t9}litellm_logo.jpg`,tags:["Code","Safety","Prompt Injection"]},{id:"cf_competitor_intent",name:"Competitor Name Blocking",description:"Block or reframe competitor comparison and ranking intent. Detect when users ask to compare or recommend competitors (airline or generic competitor lists).",category:"litellm",subcategory:"Content Category",logo:`${t9}litellm_logo.jpg`,tags:["Content Category","Competitor","Topic Blocker"]},{id:"presidio",name:"Presidio PII",description:"Microsoft Presidio for PII detection and anonymization. Supports 30+ entity types with configurable actions.",category:"partner",logo:`${t9}microsoft_azure.svg`,tags:["PII","Microsoft"],providerKey:"PresidioPII"},{id:"bedrock",name:"Bedrock Guardrail",description:"AWS Bedrock Guardrails for content filtering, topic avoidance, and sensitive information detection.",category:"partner",logo:`${t9}bedrock.svg`,tags:["AWS","Content Safety"],providerKey:"Bedrock"},{id:"lakera",name:"Lakera",description:"AI security platform protecting against prompt injections, data leakage, and harmful content.",category:"partner",logo:`${t9}lakeraai.jpeg`,tags:["Security","Prompt Injection"],providerKey:"Lakera"},{id:"openai_moderation",name:"OpenAI Moderation",description:"OpenAI's content moderation API for detecting harmful content across multiple categories.",category:"partner",logo:`${t9}openai_small.svg`,tags:["Content Moderation","OpenAI"]},{id:"google_model_armor",name:"Google Cloud Model Armor",description:"Google Cloud's model protection service for safe and responsible AI deployments.",category:"partner",logo:`${t9}google.svg`,tags:["Google Cloud","Safety"]},{id:"guardrails_ai",name:"Guardrails AI",description:"Open-source framework for adding structural, type, and quality guarantees to LLM outputs.",category:"partner",logo:`${t9}guardrails_ai.jpeg`,tags:["Open Source","Validation"]},{id:"zscaler",name:"Zscaler AI Guard",description:"Enterprise AI security from Zscaler for monitoring and protecting AI/ML workloads.",category:"partner",logo:`${t9}zscaler.svg`,tags:["Enterprise","Security"]},{id:"panw",name:"PANW Prisma AIRS",description:"Palo Alto Networks Prisma AI Runtime Security for securing AI applications in production.",category:"partner",logo:`${t9}palo_alto_networks.jpeg`,tags:["Enterprise","Security"]},{id:"cisco_ai_defense",name:"Cisco AI Defense",description:"Cisco AI Defense Inspection API for runtime protection: prompt injection, PII/PCI/PHI, harassment, hate speech, profanity, violence, and code detection.",category:"partner",logo:`${t9}cisco.png`,tags:["Enterprise","Security","Prompt Injection","PII"],providerKey:"CiscoAiDefense"},{id:"noma",name:"Noma Security",description:"AI security platform for detecting and preventing AI-specific threats and vulnerabilities.",category:"partner",logo:`${t9}noma_security.png`,tags:["Security","Threat Detection"]},{id:"aporia",name:"Aporia AI",description:"Real-time AI guardrails for hallucination detection, topic control, and policy enforcement.",category:"partner",logo:`${t9}aporia.png`,tags:["Hallucination","Policy"]},{id:"aim",name:"AIM Guardrail",description:"AIM Security guardrails for comprehensive AI threat detection and mitigation.",category:"partner",logo:`${t9}aim_security.jpeg`,tags:["Security","Threat Detection"]},{id:"cato_networks",name:"Cato Networks Guardrail",description:"Cato Networks guardrails for comprehensive AI threat detection and mitigation.",category:"partner",logo:`${t9}cato_networks.svg`,tags:["Security","Threat Detection"]},{id:"prompt_security",name:"Prompt Security",description:"Protect against prompt injection attacks, data leakage, and other LLM security threats.",category:"partner",logo:`${t9}prompt_security.png`,tags:["Prompt Injection","Security"]},{id:"lasso",name:"Lasso Guardrail",description:"Content moderation and safety guardrails for responsible AI deployments.",category:"partner",logo:`${t9}lasso.png`,tags:["Content Moderation"]},{id:"pangea",name:"Pangea Guardrail",description:"Pangea's AI guardrails for secure, compliant, and trustworthy AI applications.",category:"partner",logo:`${t9}pangea.png`,tags:["Compliance","Security"]},{id:"enkryptai",name:"EnkryptAI",description:"AI security and governance platform for enterprise AI safety and compliance.",category:"partner",logo:`${t9}enkrypt_ai.avif`,tags:["Enterprise","Governance"]},{id:"javelin",name:"Javelin Guardrails",description:"AI gateway with built-in guardrails for secure and compliant AI operations.",category:"partner",logo:`${t9}javelin.png`,tags:["Gateway","Security"]},{id:"pillar",name:"Pillar Guardrail",description:"AI safety platform for monitoring, testing, and securing AI systems.",category:"partner",logo:`${t9}pillar.jpeg`,tags:["Monitoring","Safety"]},{id:"akto",name:"Akto Guardrail",description:"AI security platform from Akto.io with automatic monitoring and guardrails for AI/ML applications.",category:"partner",logo:`${t9}akto.svg`,tags:["Security","Safety","Monitoring"]},{id:"promptguard",name:"PromptGuard",description:"AI security gateway with prompt injection detection, PII redaction, topic filtering, entity blocklists, and hallucination detection. Self-hostable with drop-in proxy integration.",category:"partner",logo:`${t9}promptguard.svg`,tags:["Security","Prompt Injection","PII"],providerKey:"Promptguard",eval:{f1:94.9,precision:100,recall:90.4,testCases:5384,latency:"~150ms"}},{id:"xecguard",name:"XecGuard",description:"CyCraft XecGuard AI security gateway. Multi-policy scanning (prompt injection, harmful content, PII, system-prompt enforcement) plus RAG context grounding.",category:"partner",logo:`${t9}xecguard.svg`,tags:["Security","Policy","Grounding","RAG"],providerKey:"Xecguard"},{id:"repelloai",name:"RepelloAI Argus",description:"RepelloAI Argus scans prompts and responses against policies configured per asset in the Repello dashboard.",category:"partner",logo:`${t9}repelloai.png`,tags:["Security","Policy","Prompt Injection"],providerKey:"Repelloai"}];var at=e.i(826910);let aa=({src:e,name:t})=>{let[a,i]=(0,r.useState)(!1);return a||!e?(0,l.jsx)("div",{style:{width:28,height:28,borderRadius:6,backgroundColor:"#e5e7eb",display:"flex",alignItems:"center",justifyContent:"center",fontSize:13,fontWeight:600,color:"#6b7280",flexShrink:0},children:t?.charAt(0)||"?"}):(0,l.jsx)("img",{src:(0,ea.resolveLogoSrc)(e),alt:"",style:{width:28,height:28,borderRadius:6,objectFit:"contain",flexShrink:0},onError:()=>i(!0)})},al=({card:e,onClick:t})=>{let[a,i]=(0,r.useState)(!1);return(0,l.jsxs)("div",{onClick:t,onMouseEnter:()=>i(!0),onMouseLeave:()=>i(!1),style:{borderRadius:12,border:a?"1px solid #93c5fd":"1px solid #e5e7eb",backgroundColor:"#ffffff",padding:"20px 20px 16px 20px",cursor:"pointer",transition:"border-color 0.15s, box-shadow 0.15s",display:"flex",flexDirection:"column",minHeight:170,boxShadow:a?"0 1px 6px rgba(59,130,246,0.08)":"none"},children:[(0,l.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:10,marginBottom:10},children:[(0,l.jsx)(aa,{src:e.logo,name:e.name}),(0,l.jsx)("span",{style:{fontSize:14,fontWeight:600,color:"#111827",lineHeight:1.3},children:e.name})]}),(0,l.jsx)("p",{className:"line-clamp-3",style:{fontSize:12,color:"#6b7280",lineHeight:1.6,margin:0,flex:1},children:e.description}),e.eval&&(0,l.jsxs)("div",{style:{marginTop:10,display:"flex",alignItems:"center",gap:4},children:[(0,l.jsx)(at.CheckCircleFilled,{style:{color:"#16a34a",fontSize:12}}),(0,l.jsxs)("span",{style:{fontSize:11,color:"#16a34a",fontWeight:500},children:["F1: ",e.eval.f1,"% · ",e.eval.testCases," test cases"]})]})]})};var ar=e.i(447566);let ai={cf_denied_financial:{provider:"LitellmContentFilter",categoryName:"denied_financial_advice",guardrailNameSuggestion:"Denied Financial Advice",mode:"pre_call",defaultOn:!1},cf_denied_legal:{provider:"LitellmContentFilter",categoryName:"denied_legal_advice",guardrailNameSuggestion:"Denied Legal Advice",mode:"pre_call",defaultOn:!1},cf_denied_medical:{provider:"LitellmContentFilter",categoryName:"denied_medical_advice",guardrailNameSuggestion:"Denied Medical Advice",mode:"pre_call",defaultOn:!1},cf_denied_insults:{provider:"LitellmContentFilter",categoryName:"denied_insults",guardrailNameSuggestion:"Insults & Personal Attacks",mode:"pre_call",defaultOn:!1},cf_harmful_violence:{provider:"LitellmContentFilter",categoryName:"harmful_violence",guardrailNameSuggestion:"Harmful Violence",mode:"pre_call",defaultOn:!1},cf_harmful_self_harm:{provider:"LitellmContentFilter",categoryName:"harmful_self_harm",guardrailNameSuggestion:"Harmful Self-Harm",mode:"pre_call",defaultOn:!1},cf_harmful_child_safety:{provider:"LitellmContentFilter",categoryName:"harmful_child_safety",guardrailNameSuggestion:"Harmful Child Safety",mode:"pre_call",defaultOn:!1},cf_harmful_illegal_weapons:{provider:"LitellmContentFilter",categoryName:"harmful_illegal_weapons",guardrailNameSuggestion:"Harmful Illegal Weapons",mode:"pre_call",defaultOn:!1},cf_bias_gender:{provider:"LitellmContentFilter",categoryName:"bias_gender",guardrailNameSuggestion:"Bias: Gender",mode:"pre_call",defaultOn:!1},cf_bias_racial:{provider:"LitellmContentFilter",categoryName:"bias_racial",guardrailNameSuggestion:"Bias: Racial",mode:"pre_call",defaultOn:!1},cf_bias_religious:{provider:"LitellmContentFilter",categoryName:"bias_religious",guardrailNameSuggestion:"Bias: Religious",mode:"pre_call",defaultOn:!1},cf_bias_sexual_orientation:{provider:"LitellmContentFilter",categoryName:"bias_sexual_orientation",guardrailNameSuggestion:"Bias: Sexual Orientation",mode:"pre_call",defaultOn:!1},cf_prompt_injection_jailbreak:{provider:"LitellmContentFilter",categoryName:"prompt_injection_jailbreak",guardrailNameSuggestion:"Prompt Injection: Jailbreak",mode:"pre_call",defaultOn:!1},cf_prompt_injection_data_exfil:{provider:"LitellmContentFilter",categoryName:"prompt_injection_data_exfiltration",guardrailNameSuggestion:"Prompt Injection: Data Exfiltration",mode:"pre_call",defaultOn:!1},cf_prompt_injection_sql:{provider:"LitellmContentFilter",categoryName:"prompt_injection_sql",guardrailNameSuggestion:"Prompt Injection: SQL",mode:"pre_call",defaultOn:!1},cf_prompt_injection_malicious_code:{provider:"LitellmContentFilter",categoryName:"prompt_injection_malicious_code",guardrailNameSuggestion:"Prompt Injection: Malicious Code",mode:"pre_call",defaultOn:!1},cf_prompt_injection_system_prompt:{provider:"LitellmContentFilter",categoryName:"prompt_injection_system_prompt",guardrailNameSuggestion:"Prompt Injection: System Prompt",mode:"pre_call",defaultOn:!1},cf_toxic_abuse:{provider:"LitellmContentFilter",categoryName:"harm_toxic_abuse",guardrailNameSuggestion:"Toxic & Abusive Language",mode:"pre_call",defaultOn:!1},cf_patterns:{provider:"LitellmContentFilter",guardrailNameSuggestion:"Pattern Matching",mode:"pre_call",defaultOn:!1},cf_keywords:{provider:"LitellmContentFilter",guardrailNameSuggestion:"Keyword Blocking",mode:"pre_call",defaultOn:!1},block_code_execution:{provider:"BlockCodeExecution",guardrailNameSuggestion:"Block Code Execution",mode:"pre_call",defaultOn:!1},cf_competitor_intent:{provider:"LitellmContentFilter",guardrailNameSuggestion:"Competitor Name Blocking",mode:"pre_call",defaultOn:!1},presidio:{provider:"PresidioPII",guardrailNameSuggestion:"Presidio PII",mode:"pre_call",defaultOn:!1},bedrock:{provider:"Bedrock",guardrailNameSuggestion:"Bedrock Guardrail",mode:"pre_call",defaultOn:!1},lakera:{provider:"Lakera",guardrailNameSuggestion:"Lakera",mode:"pre_call",defaultOn:!1},openai_moderation:{provider:"OpenaiModeration",guardrailNameSuggestion:"OpenAI Moderation",mode:"pre_call",defaultOn:!1},google_model_armor:{provider:"ModelArmor",guardrailNameSuggestion:"Google Cloud Model Armor",mode:"pre_call",defaultOn:!1},guardrails_ai:{provider:"GuardrailsAi",guardrailNameSuggestion:"Guardrails AI",mode:"pre_call",defaultOn:!1},zscaler:{provider:"ZscalerAiGuard",guardrailNameSuggestion:"Zscaler AI Guard",mode:"pre_call",defaultOn:!1},panw:{provider:"PanwPrismaAirs",guardrailNameSuggestion:"PANW Prisma AIRS",mode:"pre_call",defaultOn:!1},cisco_ai_defense:{provider:"CiscoAiDefense",guardrailNameSuggestion:"Cisco AI Defense",mode:"pre_call",defaultOn:!1},noma:{provider:"Noma",guardrailNameSuggestion:"Noma Security",mode:"pre_call",defaultOn:!1},aporia:{provider:"AporiaAi",guardrailNameSuggestion:"Aporia AI",mode:"pre_call",defaultOn:!1},aim:{provider:"Aim",guardrailNameSuggestion:"AIM Guardrail",mode:"pre_call",defaultOn:!1},cato_networks:{provider:"Cato Networks",guardrailNameSuggestion:"Cato Networks Guardrail",mode:"pre_call",defaultOn:!1},prompt_security:{provider:"PromptSecurity",guardrailNameSuggestion:"Prompt Security",mode:"pre_call",defaultOn:!1},lasso:{provider:"Lasso",guardrailNameSuggestion:"Lasso Guardrail",mode:"pre_call",defaultOn:!1},pangea:{provider:"Pangea",guardrailNameSuggestion:"Pangea Guardrail",mode:"pre_call",defaultOn:!1},enkryptai:{provider:"Enkryptai",guardrailNameSuggestion:"EnkryptAI",mode:"pre_call",defaultOn:!1},javelin:{provider:"Javelin",guardrailNameSuggestion:"Javelin Guardrails",mode:"pre_call",defaultOn:!1},pillar:{provider:"Pillar",guardrailNameSuggestion:"Pillar Guardrail",mode:"pre_call",defaultOn:!1},akto:{provider:"Akto",guardrailNameSuggestion:"Akto Guardrail",mode:"pre_call",defaultOn:!1},promptguard:{provider:"Promptguard",guardrailNameSuggestion:"PromptGuard",mode:"pre_call",defaultOn:!1},xecguard:{provider:"Xecguard",guardrailNameSuggestion:"XecGuard",mode:"pre_call",defaultOn:!1},repelloai:{provider:"Repelloai",guardrailNameSuggestion:"RepelloAI Argus",mode:"pre_call",defaultOn:!1}},as=({card:e,onBack:t,accessToken:a,onGuardrailCreated:s})=>{let[n,o]=(0,r.useState)(!1),[d,c]=(0,r.useState)("overview"),m=[{property:"Provider",value:"litellm"===e.category?"LiteLLM Content Filter":"Partner Guardrail"},...e.subcategory?[{property:"Subcategory",value:e.subcategory}]:[],..."litellm"===e.category?[{property:"Cost",value:"$0 / request"}]:[],..."litellm"===e.category?[{property:"External Dependencies",value:"None"}]:[],..."litellm"===e.category?[{property:"Latency",value:e.eval?.latency||"<1ms"}]:[]],u=e.eval?[{metric:"Precision",value:`${e.eval.precision}%`},{metric:"Recall",value:`${e.eval.recall}%`},{metric:"F1 Score",value:`${e.eval.f1}%`},{metric:"Test Cases",value:String(e.eval.testCases)},{metric:"False Positives",value:"0"},{metric:"False Negatives",value:"0"},{metric:"Latency (p50)",value:e.eval.latency}]:[],p=[{key:"overview",label:"Overview"},...e.eval?[{key:"eval",label:"Eval Results"}]:[]];return(0,l.jsxs)("div",{style:{maxWidth:960,margin:"0 auto"},children:[(0,l.jsxs)("div",{onClick:t,style:{display:"inline-flex",alignItems:"center",gap:6,color:"#5f6368",cursor:"pointer",fontSize:14,marginBottom:24},children:[(0,l.jsx)(ar.ArrowLeftOutlined,{style:{fontSize:11}}),(0,l.jsx)("span",{children:e.name})]}),(0,l.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:16,marginBottom:8},children:[(0,l.jsx)("img",{src:(0,ea.resolveLogoSrc)(e.logo),alt:"",style:{width:40,height:40,borderRadius:8,objectFit:"contain"},onError:e=>{e.target.style.display="none"}}),(0,l.jsx)("h1",{style:{fontSize:28,fontWeight:400,color:"#202124",margin:0,lineHeight:1.2},children:e.name})]}),(0,l.jsx)("p",{style:{fontSize:14,color:"#5f6368",margin:"0 0 20px 0",lineHeight:1.6},children:e.description}),(0,l.jsx)("div",{style:{display:"flex",gap:10,marginBottom:32},children:(0,l.jsx)(i.Button,{onClick:()=>o(!0),style:{borderRadius:20,padding:"4px 20px",height:36,borderColor:"#dadce0",color:"#1a73e8",fontWeight:500,fontSize:14},children:"Create Guardrail"})}),(0,l.jsx)("div",{style:{borderBottom:"1px solid #dadce0",marginBottom:28},children:(0,l.jsx)("div",{style:{display:"flex",gap:0},children:p.map(e=>(0,l.jsx)("div",{onClick:()=>c(e.key),style:{padding:"12px 20px",fontSize:14,color:d===e.key?"#1a73e8":"#5f6368",borderBottom:d===e.key?"3px solid #1a73e8":"3px solid transparent",cursor:"pointer",fontWeight:d===e.key?500:400,marginBottom:-1},children:e.label},e.key))})}),"overview"===d&&(0,l.jsxs)("div",{style:{display:"flex",gap:64},children:[(0,l.jsxs)("div",{style:{flex:1,minWidth:0},children:[(0,l.jsx)("h2",{style:{fontSize:18,fontWeight:400,color:"#202124",margin:"0 0 12px 0"},children:"Overview"}),(0,l.jsx)("p",{style:{fontSize:14,color:"#3c4043",lineHeight:1.7,margin:"0 0 32px 0"},children:e.description}),(0,l.jsx)("h2",{style:{fontSize:18,fontWeight:400,color:"#202124",margin:"0 0 4px 0"},children:"Guardrail Details"}),(0,l.jsx)("p",{style:{fontSize:13,color:"#5f6368",margin:"0 0 16px 0"},children:"Details are as follows"}),(0,l.jsxs)("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:14},children:[(0,l.jsx)("thead",{children:(0,l.jsxs)("tr",{style:{borderBottom:"1px solid #dadce0"},children:[(0,l.jsx)("th",{style:{textAlign:"left",padding:"12px 0",color:"#5f6368",fontWeight:500,width:200},children:"Property"}),(0,l.jsx)("th",{style:{textAlign:"left",padding:"12px 0",color:"#5f6368",fontWeight:500},children:e.name})]})}),(0,l.jsx)("tbody",{children:m.map((e,t)=>(0,l.jsxs)("tr",{style:{borderBottom:"1px solid #f1f3f4"},children:[(0,l.jsx)("td",{style:{padding:"12px 0",color:"#3c4043"},children:e.property}),(0,l.jsx)("td",{style:{padding:"12px 0",color:"#202124"},children:e.value})]},t))})]})]}),(0,l.jsxs)("div",{style:{width:240,flexShrink:0},children:[(0,l.jsxs)("div",{style:{marginBottom:28},children:[(0,l.jsx)("div",{style:{fontSize:12,color:"#5f6368",marginBottom:4},children:"Guardrail ID"}),(0,l.jsxs)("div",{style:{fontSize:13,color:"#202124",wordBreak:"break-all"},children:["litellm/",e.id]})]}),(0,l.jsxs)("div",{style:{marginBottom:28},children:[(0,l.jsx)("div",{style:{fontSize:12,color:"#5f6368",marginBottom:4},children:"Type"}),(0,l.jsx)("div",{style:{fontSize:13,color:"#202124"},children:"litellm"===e.category?"Content Filter":"Partner"})]}),e.tags.length>0&&(0,l.jsxs)("div",{style:{marginBottom:28},children:[(0,l.jsx)("div",{style:{fontSize:12,color:"#5f6368",marginBottom:8},children:"Tags"}),(0,l.jsx)("div",{style:{display:"flex",flexWrap:"wrap",gap:6},children:e.tags.map(e=>(0,l.jsx)("span",{style:{fontSize:12,padding:"4px 12px",borderRadius:16,border:"1px solid #dadce0",color:"#3c4043",backgroundColor:"#fff"},children:e},e))})]})]})]}),"eval"===d&&(0,l.jsxs)("div",{children:[(0,l.jsx)("h2",{style:{fontSize:18,fontWeight:400,color:"#202124",margin:"0 0 16px 0"},children:"Eval Results"}),(0,l.jsxs)("table",{style:{width:"100%",maxWidth:560,borderCollapse:"collapse",fontSize:14},children:[(0,l.jsx)("thead",{children:(0,l.jsxs)("tr",{style:{backgroundColor:"#f8f9fa",borderBottom:"1px solid #dadce0"},children:[(0,l.jsx)("th",{style:{textAlign:"left",padding:"12px 16px",color:"#5f6368",fontWeight:500},children:"Metric"}),(0,l.jsx)("th",{style:{textAlign:"left",padding:"12px 16px",color:"#5f6368",fontWeight:500},children:"Value"})]})}),(0,l.jsx)("tbody",{children:u.map((e,t)=>(0,l.jsxs)("tr",{style:{borderBottom:"1px solid #f1f3f4"},children:[(0,l.jsx)("td",{style:{padding:"12px 16px",color:"#3c4043"},children:e.metric}),(0,l.jsx)("td",{style:{padding:"12px 16px",color:"#202124",fontWeight:500},children:e.value})]},t))})]})]}),(0,l.jsx)(e1,{visible:n,onClose:()=>o(!1),accessToken:a,onSuccess:()=>{o(!1),s()},preset:ai[e.id]})]})},an=({accessToken:e,onGuardrailCreated:t})=>{let[a,i]=(0,r.useState)(""),[s,n]=(0,r.useState)(null),[o,d]=(0,r.useState)(!1),c=ae.filter(e=>{if(!a)return!0;let t=a.toLowerCase();return e.name.toLowerCase().includes(t)||e.description.toLowerCase().includes(t)||e.tags.some(e=>e.toLowerCase().includes(t))}),m=c.filter(e=>"litellm"===e.category),u=c.filter(e=>"partner"===e.category);return s?(0,l.jsx)(as,{card:s,onBack:()=>n(null),accessToken:e,onGuardrailCreated:t}):(0,l.jsxs)("div",{children:[(0,l.jsx)("div",{style:{marginBottom:24},children:(0,l.jsx)(p.Input,{size:"large",placeholder:"Search guardrails",prefix:(0,l.jsx)(tQ.SearchOutlined,{style:{color:"#9ca3af"}}),value:a,onChange:e=>i(e.target.value),style:{borderRadius:8}})}),(0,l.jsxs)("div",{style:{marginBottom:40},children:[(0,l.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:4},children:[(0,l.jsx)("h2",{style:{fontSize:20,fontWeight:600,color:"#111827",margin:0},children:"LiteLLM Content Filter"}),(0,l.jsx)("span",{style:{display:"inline-flex",alignItems:"center",gap:6,fontSize:14,color:"#1a73e8",cursor:"pointer"},onClick:()=>d(!o),children:o?(0,l.jsx)(l.Fragment,{children:"Show less"}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(t7.ArrowRightOutlined,{style:{fontSize:12}}),`Show all (${m.length})`]})})]}),(0,l.jsx)("p",{style:{fontSize:13,color:"#6b7280",margin:"4px 0 20px 0"},children:"Built-in guardrails powered by LiteLLM. Zero latency, no external dependencies, no additional cost."}),(0,l.jsx)("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(220px, 1fr))",gap:16},children:(o?m:m.slice(0,10)).map(e=>(0,l.jsx)(al,{card:e,onClick:()=>n(e)},e.id))})]}),(0,l.jsxs)("div",{style:{marginBottom:40},children:[(0,l.jsx)("h2",{style:{fontSize:20,fontWeight:600,color:"#111827",margin:"0 0 4px 0"},children:"Partner Guardrails"}),(0,l.jsx)("p",{style:{fontSize:13,color:"#6b7280",margin:"4px 0 20px 0"},children:"Third-party guardrail integrations from leading AI security providers."}),(0,l.jsx)("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(220px, 1fr))",gap:16},children:u.map(e=>(0,l.jsx)(al,{card:e,onClick:()=>n(e)},e.id))})]})]})};var ao=e.i(988846),ad=e.i(837007),ac=e.i(409797),am=e.i(54131),au=e.i(995926),ap=e.i(634831),ag=e.i(438100),ax=e.i(302202),ah=e.i(328196),af=e.i(168118),ay=e.i(663435),aj=e.i(954616),a_=e.i(912598),ab=e.i(431703),av=e.i(135214),aw=e.i(243652);let aN=async(e,t)=>{let a=(0,m.getProxyBaseUrl)(),l=`${a}/guardrails/register`,r=await fetch(l,{method:"POST",headers:{[(0,m.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify(t)});if(!r.ok){let e=await r.json().catch(()=>({})),t=(0,ab.deriveErrorMessage)(e);throw(0,m.handleError)(t),Error(t)}return r.json()},aC=(0,aw.createQueryKeys)("guardrails");function aS(e){var t;let a=e.litellm_params??{},l=e.guardrail_info??{},r=a.headers,i=Array.isArray(r)?r.map(e=>({key:(e.key??e.name??"").toString(),value:String(e.value??"")})):"object"==typeof r&&null!==r?Object.entries(r).map(([e,t])=>({key:e,value:String(t??"")})):[],s=a.api_base??a.url??"",n=l.model??a.model??"—",o=a.forward_api_key??!0,d=Array.isArray(a.extra_headers)?a.extra_headers.filter(e=>"string"==typeof e):[];return{id:e.guardrail_id,team:e.team_id??"—",name:e.guardrail_name,endpoint:s,status:"pending_review"===(t=e.status)?"pending":"active"===t||"rejected"===t?t:"active",model:n,forwardKey:o,description:l.description??"",method:a.method??"POST",customHeaders:i,extraHeaders:d,submittedAt:function(e){if(!e)return"—";try{let t=new Date(e);return isNaN(t.getTime())?e:t.toISOString().slice(0,10)}catch{return e}}(e.submitted_at),submittedBy:e.submitted_by_email??e.submitted_by_user_id??"—",mode:a.mode,unreachable_fallback:a.unreachable_fallback,additionalProviderParams:a.additional_provider_specific_params,guardrailType:a.guardrail}}let ak={active:{label:"Active",bg:"bg-green-50",text:"text-green-700",dot:"bg-green-500"},pending:{label:"Pending Review",bg:"bg-yellow-50",text:"text-yellow-700",dot:"bg-yellow-500"},rejected:{label:"Rejected",bg:"bg-red-50",text:"text-red-700",dot:"bg-red-500"}},aI={"ML Platform":"bg-purple-100 text-purple-700","Data Science":"bg-blue-100 text-blue-700",Security:"bg-red-100 text-red-700","Customer Success":"bg-orange-100 text-orange-700",Legal:"bg-gray-100 text-gray-700",Finance:"bg-green-100 text-green-700"};function aA({label:e,value:t,color:a}){return(0,l.jsxs)("div",{className:"bg-white border border-gray-200 rounded-lg px-4 py-3",children:[(0,l.jsx)("div",{className:`text-2xl font-bold ${a}`,children:t}),(0,l.jsx)("div",{className:"text-xs text-gray-500 mt-0.5",children:e})]})}function aO({enabled:e,onToggle:t}){return(0,l.jsx)("button",{type:"button",onClick:t,role:"switch","aria-checked":e,className:`relative inline-flex h-5 w-9 items-center rounded-full transition-colors focus:outline-hidden focus:ring-2 focus:ring-blue-500 focus:ring-offset-1 ${e?"bg-blue-500":"bg-gray-200"}`,children:(0,l.jsx)("span",{className:`inline-block h-3.5 w-3.5 transform rounded-full bg-white shadow transition-transform ${e?"translate-x-4":"translate-x-0.5"}`})})}function aT({guardrail:e,isSelected:t,isHeadersExpanded:a,onSelect:r,onToggleForwardKey:i,onToggleHeaders:s,onApprove:n,onReject:o}){let d=ak[e.status],c=aI[e.team]??"bg-gray-100 text-gray-700";return(0,l.jsxs)("div",{className:`bg-white border rounded-lg p-4 transition-all ${t?"border-blue-400 ring-1 ring-blue-200":"border-gray-200"}`,children:[(0,l.jsxs)("div",{className:"flex items-start justify-between gap-4",children:[(0,l.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,l.jsxs)("div",{className:"flex items-center gap-2 mb-1.5 flex-wrap",children:[(0,l.jsxs)("span",{className:`text-xs font-medium px-2 py-0.5 rounded-full ${c}`,children:["Team: ",e.team]}),(0,l.jsxs)("span",{className:`inline-flex items-center gap-1.5 text-xs font-medium px-2 py-0.5 rounded-full ${d.bg} ${d.text}`,children:[(0,l.jsx)("span",{className:`w-1.5 h-1.5 rounded-full ${d.dot}`}),d.label]})]}),(0,l.jsx)("h3",{className:"text-sm font-semibold text-gray-900 mb-1",children:e.name}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mb-2 line-clamp-1",children:e.description}),(0,l.jsxs)("div",{className:"flex items-center gap-1.5 mb-2",children:[(0,l.jsx)(ax.ServerIcon,{className:"h-3.5 w-3.5 text-gray-400 shrink-0"}),(0,l.jsx)("code",{className:"text-xs text-gray-500 font-mono truncate",children:e.endpoint})]}),(0,l.jsxs)("div",{className:"flex items-center gap-4 text-xs text-gray-500",children:[(0,l.jsxs)("span",{children:["Model: ",(0,l.jsx)("span",{className:"font-medium text-gray-700",children:e.model})]}),(0,l.jsxs)("span",{children:["Submitted: ",(0,l.jsx)("span",{className:"font-medium text-gray-700",children:e.submittedAt})]})]})]}),(0,l.jsxs)("div",{className:"flex flex-col items-end gap-2 shrink-0",children:[(0,l.jsxs)("div",{className:"flex items-center gap-2",children:[(0,l.jsx)("span",{className:"text-xs text-gray-500 whitespace-nowrap",children:"Forward API Key"}),(0,l.jsx)(aO,{enabled:e.forwardKey,onToggle:i})]}),(0,l.jsxs)("div",{className:"flex items-center gap-2 mt-1",children:[(0,l.jsx)("button",{type:"button",onClick:r,className:"text-xs border border-gray-300 text-gray-600 hover:bg-gray-50 px-3 py-1.5 rounded-md transition-colors font-medium",children:t?"Close":"Review"}),"pending"===e.status&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("button",{type:"button",onClick:n,className:"text-xs bg-green-500 hover:bg-green-600 text-white px-3 py-1.5 rounded-md transition-colors font-medium",children:"Approve"}),(0,l.jsx)("button",{type:"button",onClick:o,className:"text-xs border border-red-300 text-red-600 hover:bg-red-50 px-3 py-1.5 rounded-md transition-colors font-medium",children:"Reject"})]})]})]})]}),(0,l.jsxs)("div",{className:"mt-3 pt-3 border-t border-gray-100",children:[(0,l.jsxs)("button",{type:"button",onClick:s,className:"flex items-center gap-1.5 text-xs text-gray-500 hover:text-gray-700 transition-colors",children:[a?(0,l.jsx)(am.ChevronUpIcon,{className:"h-3.5 w-3.5"}):(0,l.jsx)(ac.ChevronDownIcon,{className:"h-3.5 w-3.5"}),"Static headers",e.customHeaders.length>0&&(0,l.jsx)("span",{className:"ml-1 bg-gray-100 text-gray-600 rounded-full px-1.5 py-0.5 text-xs",children:e.customHeaders.length})]}),a&&(0,l.jsx)("div",{className:"mt-2",children:0===e.customHeaders.length?(0,l.jsx)("p",{className:"text-xs text-gray-400 italic",children:"No static headers configured."}):(0,l.jsx)("div",{className:"space-y-1",children:e.customHeaders.map((e,t)=>(0,l.jsxs)("div",{className:"flex items-center gap-2 text-xs font-mono",children:[(0,l.jsx)("span",{className:"text-gray-500 bg-gray-50 border border-gray-200 rounded-sm px-2 py-0.5",children:e.key}),(0,l.jsx)("span",{className:"text-gray-400",children:":"}),(0,l.jsx)("span",{className:"text-gray-700 bg-gray-50 border border-gray-200 rounded-sm px-2 py-0.5",children:e.value})]},`${e.key}-${t}`))})})]})]})}function aP({label:e,children:t}){return(0,l.jsxs)("div",{children:[(0,l.jsx)("div",{className:"text-xs font-semibold text-gray-500 mb-1",children:e}),(0,l.jsx)("div",{children:t})]})}function aL({guardrail:e,onClose:t,onApprove:a,onReject:i,onToggleForwardKey:s,onUpdateCustomHeaders:n,onUpdateExtraHeaders:o}){let[d,c]=(0,r.useState)(!1),[m,u]=(0,r.useState)(""),[p,g]=(0,r.useState)(""),[x,h]=(0,r.useState)(""),f=ak[e.status],y=aI[e.team]??"bg-gray-100 text-gray-700";return(0,l.jsx)("div",{className:"w-96 shrink-0 bg-white overflow-auto",children:(0,l.jsxs)("div",{className:"p-5",children:[(0,l.jsxs)("div",{className:"flex items-start justify-between mb-4",children:[(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{className:"flex items-center gap-2 mb-1",children:[(0,l.jsxs)("span",{className:`text-xs font-medium px-2 py-0.5 rounded-full ${y}`,children:["Team: ",e.team]}),(0,l.jsxs)("span",{className:`inline-flex items-center gap-1.5 text-xs font-medium px-2 py-0.5 rounded-full ${f.bg} ${f.text}`,children:[(0,l.jsx)("span",{className:`w-1.5 h-1.5 rounded-full ${f.dot}`}),f.label]})]}),(0,l.jsx)("h2",{className:"text-base font-semibold text-gray-900",children:e.name}),(0,l.jsxs)("p",{className:"text-xs text-gray-500 mt-0.5",children:["Submitted by ",e.submittedBy," on ",e.submittedAt]})]}),(0,l.jsx)("button",{type:"button",onClick:t,className:"text-gray-400 hover:text-gray-600 transition-colors","aria-label":"Close detail panel",children:(0,l.jsx)(au.XIcon,{className:"h-4 w-4"})})]}),(0,l.jsx)("p",{className:"text-sm text-gray-600 mb-5",children:e.description}),(0,l.jsxs)("div",{className:"space-y-4",children:[(0,l.jsx)(aP,{label:"Endpoint",children:(0,l.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,l.jsx)("code",{className:"text-xs font-mono text-gray-700 break-all",children:e.endpoint}),(0,l.jsx)("a",{href:e.endpoint,target:"_blank",rel:"noopener noreferrer",className:"text-gray-400 hover:text-blue-500 shrink-0",children:(0,l.jsx)(ap.ExternalLinkIcon,{className:"h-3.5 w-3.5"})})]})}),(0,l.jsx)(aP,{label:"Method",children:(0,l.jsx)("span",{className:"text-xs font-mono font-medium text-gray-700 bg-gray-100 px-2 py-0.5 rounded-sm",children:e.method})}),(0,l.jsxs)("div",{className:"border border-blue-100 bg-blue-50 rounded-lg p-3",children:[(0,l.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,l.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,l.jsx)(ag.KeyIcon,{className:"h-3.5 w-3.5 text-blue-500"}),(0,l.jsx)("span",{className:"text-xs font-semibold text-blue-800",children:"Forward LiteLLM API Key"})]}),(0,l.jsx)(aO,{enabled:e.forwardKey,onToggle:s})]}),(0,l.jsxs)("p",{className:"text-xs text-blue-700 leading-relaxed",children:["When enabled, the caller's LiteLLM API key is forwarded as an"," ",(0,l.jsx)("code",{className:"font-mono bg-blue-100 px-1 rounded-sm",children:"Authorization"}),"header to your guardrail endpoint. This allows your guardrail to authenticate model calls using the original caller's credentials."]})]}),(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{className:"flex items-center gap-1.5 mb-2",children:[(0,l.jsx)("span",{className:"text-xs font-semibold text-gray-700",children:"Static headers"}),e.customHeaders.length>0&&(0,l.jsx)("span",{className:"bg-gray-100 text-gray-600 rounded-full px-1.5 py-0.5 text-xs",children:e.customHeaders.length})]}),(0,l.jsx)("p",{className:"text-xs text-gray-400 mb-2",children:"Sent with every request to the guardrail."}),0===e.customHeaders.length?(0,l.jsx)("p",{className:"text-xs text-gray-400 italic mb-2",children:"No static headers configured."}):(0,l.jsx)("ul",{className:"list-none space-y-1 mb-2",children:e.customHeaders.map((t,a)=>(0,l.jsxs)("li",{className:"flex items-center justify-between gap-2 text-xs font-mono bg-gray-50 border border-gray-200 rounded-sm px-2 py-1.5",children:[(0,l.jsxs)("span",{className:"text-gray-700 truncate",children:[t.key,": ",t.value]}),(0,l.jsx)("button",{type:"button",onClick:()=>n(e.customHeaders.filter((e,t)=>t!==a)),className:"text-gray-400 hover:text-red-600 shrink-0","aria-label":`Remove ${t.key}`,children:(0,l.jsx)(au.XIcon,{className:"h-3.5 w-3.5"})})]},`${t.key}-${a}`))}),(0,l.jsxs)("div",{className:"flex flex-col gap-2 sm:flex-row sm:items-end",children:[(0,l.jsx)("input",{type:"text",value:p,onChange:e=>g(e.target.value),placeholder:"Header name (e.g. X-API-Key)",className:"flex-1 min-w-0 text-xs font-mono border border-gray-200 rounded-sm px-2 py-1.5 text-gray-700 placeholder-gray-400 focus:outline-hidden focus:ring-1 focus:ring-blue-500",onKeyDown:t=>{if("Enter"===t.key){t.preventDefault();let a=p.trim(),l=x.trim();a&&!e.customHeaders.some(e=>e.key.toLowerCase()===a.toLowerCase())&&(n([...e.customHeaders,{key:a,value:l}]),g(""),h(""))}}}),(0,l.jsx)("input",{type:"text",value:x,onChange:e=>h(e.target.value),placeholder:"Value",className:"flex-1 min-w-0 text-xs font-mono border border-gray-200 rounded-sm px-2 py-1.5 text-gray-700 placeholder-gray-400 focus:outline-hidden focus:ring-1 focus:ring-blue-500",onKeyDown:t=>{if("Enter"===t.key){t.preventDefault();let a=p.trim(),l=x.trim();a&&!e.customHeaders.some(e=>e.key.toLowerCase()===a.toLowerCase())&&(n([...e.customHeaders,{key:a,value:l}]),g(""),h(""))}}}),(0,l.jsx)("button",{type:"button",onClick:()=>{let t=p.trim(),a=x.trim();t&&!e.customHeaders.some(e=>e.key.toLowerCase()===t.toLowerCase())&&(n([...e.customHeaders,{key:t,value:a}]),g(""),h(""))},className:"text-xs font-medium text-blue-600 hover:text-blue-700 border border-blue-200 bg-blue-50 hover:bg-blue-100 px-2 py-1.5 rounded-sm transition-colors shrink-0",children:"Add"})]})]}),(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{className:"flex items-center gap-1.5 mb-2",children:[(0,l.jsx)("span",{className:"text-xs font-semibold text-gray-700",children:"Forward client headers"}),e.extraHeaders.length>0&&(0,l.jsx)("span",{className:"bg-gray-100 text-gray-600 rounded-full px-1.5 py-0.5 text-xs",children:e.extraHeaders.length})]}),(0,l.jsx)("p",{className:"text-xs text-gray-400 mb-2",children:"Allowed header names to forward from the client request to the guardrail (e.g. x-request-id)."}),0===e.extraHeaders.length?(0,l.jsx)("p",{className:"text-xs text-gray-400 italic mb-2",children:"No forward client headers configured."}):(0,l.jsx)("ul",{className:"list-none space-y-1 mb-2",children:e.extraHeaders.map((t,a)=>(0,l.jsxs)("li",{className:"flex items-center justify-between gap-2 text-xs font-mono bg-gray-50 border border-gray-200 rounded-sm px-2 py-1.5",children:[(0,l.jsx)("span",{className:"text-gray-700 truncate",children:t}),(0,l.jsx)("button",{type:"button",onClick:()=>o(e.extraHeaders.filter((e,t)=>t!==a)),className:"text-gray-400 hover:text-red-600 shrink-0","aria-label":`Remove ${t}`,children:(0,l.jsx)(au.XIcon,{className:"h-3.5 w-3.5"})})]},`${t}-${a}`))}),(0,l.jsxs)("div",{className:"flex gap-2",children:[(0,l.jsx)("input",{type:"text",value:m,onChange:e=>u(e.target.value),placeholder:"e.g. x-request-id",className:"flex-1 min-w-0 text-xs font-mono border border-gray-200 rounded-sm px-2 py-1.5 text-gray-700 placeholder-gray-400 focus:outline-hidden focus:ring-1 focus:ring-blue-500",onKeyDown:t=>{if("Enter"===t.key){t.preventDefault();let a=m.trim().toLowerCase();a&&!e.extraHeaders.map(e=>e.toLowerCase()).includes(a)&&(o([...e.extraHeaders,a]),u(""))}}}),(0,l.jsx)("button",{type:"button",onClick:()=>{let t=m.trim().toLowerCase();t&&!e.extraHeaders.map(e=>e.toLowerCase()).includes(t)&&(o([...e.extraHeaders,t]),u(""))},className:"text-xs font-medium text-blue-600 hover:text-blue-700 border border-blue-200 bg-blue-50 hover:bg-blue-100 px-2 py-1.5 rounded-sm transition-colors",children:"Add"})]})]}),(0,l.jsxs)("div",{className:"border border-gray-200 rounded-lg overflow-hidden",children:[(0,l.jsxs)("button",{type:"button",onClick:()=>c(!d),className:"w-full flex items-center justify-between px-3 py-2 text-left text-xs font-semibold text-gray-700 bg-gray-50 hover:bg-gray-100 transition-colors",children:[(0,l.jsx)("span",{children:"Equivalent config"}),d?(0,l.jsx)(am.ChevronUpIcon,{className:"h-3.5 w-3.5 text-gray-500"}):(0,l.jsx)(ac.ChevronDownIcon,{className:"h-3.5 w-3.5 text-gray-500"})]}),d&&(0,l.jsx)("pre",{className:"p-3 text-xs font-mono text-gray-700 bg-white border-t border-gray-200 overflow-x-auto whitespace-pre-wrap break-all",children:function(e){let t=["litellm_settings:"," guardrails:",` - guardrail_name: "${e.name.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`," litellm_params:",` guardrail: ${e.guardrailType??"generic_guardrail_api"}`,` mode: ${e.mode??"pre_call"} # or post_call, during_call`,` api_base: ${e.endpoint||"https://your-guardrail-api.com"}`," api_key: os.environ/YOUR_GUARDRAIL_API_KEY # optional",` unreachable_fallback: ${e.unreachable_fallback??"fail_closed"} # default: fail_closed. Set to fail_open to proceed if the guardrail endpoint is unreachable.`,` forward_api_key: ${e.forwardKey}`];if(e.model&&"—"!==e.model&&t.push(` model: "${e.model}" # LLM model name sent to the guardrail for context`),e.customHeaders.length>0)for(let a of(t.push(" headers: # static headers (sent with every request)"),e.customHeaders))t.push(` ${a.key}: "${String(a.value).replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`);if(e.extraHeaders.length>0)for(let a of(t.push(" extra_headers: # forward these client request headers to the guardrail"),e.extraHeaders))t.push(` - ${a}`);if(e.additionalProviderParams&&Object.keys(e.additionalProviderParams).length>0)for(let[a,l]of(t.push(" additional_provider_specific_params:"),Object.entries(e.additionalProviderParams))){let e="string"==typeof l?`"${l}"`:String(l);t.push(` ${a}: ${e}`)}return t.join("\n")}(e)})]}),(0,l.jsxs)("div",{className:"flex items-start gap-2 bg-gray-50 border border-gray-200 rounded-lg p-3",children:[(0,l.jsx)(af.InfoIcon,{className:"h-3.5 w-3.5 text-gray-400 shrink-0 mt-0.5"}),(0,l.jsxs)("p",{className:"text-xs text-gray-500 leading-relaxed",children:["This guardrail runs on a separate instance. It receives the user request and forwards the result to the next step in the pipeline. See"," ",(0,l.jsx)("a",{href:"https://docs.litellm.ai/docs/adding_provider/generic_guardrail_api",target:"_blank",rel:"noopener noreferrer",className:"text-blue-500 hover:underline",children:"LiteLLM Generic Guardrail API docs"})," ","for configuration details."]})]})]}),(0,l.jsxs)("div",{className:"mt-5 pt-4 border-t border-gray-100 space-y-2",children:[(0,l.jsxs)("button",{type:"button",className:"w-full flex items-center justify-center gap-2 border border-gray-300 text-gray-700 hover:bg-gray-50 text-sm font-medium py-2 rounded-md transition-colors",children:[(0,l.jsx)(ap.ExternalLinkIcon,{className:"h-4 w-4"}),"Test Endpoint"]}),"pending"===e.status&&(0,l.jsxs)("div",{className:"flex gap-2",children:[(0,l.jsxs)("button",{type:"button",onClick:a,className:"flex-1 flex items-center justify-center gap-1.5 bg-green-500 hover:bg-green-600 text-white text-sm font-medium py-2 rounded-md transition-colors",children:[(0,l.jsx)(tN.CheckIcon,{className:"h-4 w-4"}),"Approve"]}),(0,l.jsxs)("button",{type:"button",onClick:i,className:"flex-1 flex items-center justify-center gap-1.5 border border-red-300 text-red-600 hover:bg-red-50 text-sm font-medium py-2 rounded-md transition-colors",children:[(0,l.jsx)(au.XIcon,{className:"h-4 w-4"}),"Reject"]})]})]})]})})}function aB({action:e,guardrailName:t,onConfirm:a,onCancel:r}){let i="approve"===e;return(0,l.jsx)("div",{className:"fixed inset-0 bg-black/30 flex items-center justify-center z-50",children:(0,l.jsxs)("div",{className:"bg-white rounded-xl shadow-xl p-6 max-w-sm w-full mx-4",children:[(0,l.jsx)("div",{className:`w-10 h-10 rounded-full flex items-center justify-center mb-4 ${i?"bg-green-100":"bg-red-100"}`,children:i?(0,l.jsx)(tN.CheckIcon,{className:"h-5 w-5 text-green-600"}):(0,l.jsx)(ah.AlertCircleIcon,{className:"h-5 w-5 text-red-600"})}),(0,l.jsx)("h3",{className:"text-base font-semibold text-gray-900 mb-1",children:i?"Approve Guardrail":"Reject Guardrail"}),(0,l.jsxs)("p",{className:"text-sm text-gray-500 mb-5",children:["Are you sure you want to ",e," ",(0,l.jsxs)("span",{className:"font-medium text-gray-700",children:['"',t,'"']}),"?"," ",i?"This will make it active and available for use.":"This will mark it as rejected and notify the team."]}),(0,l.jsxs)("div",{className:"flex gap-3",children:[(0,l.jsx)("button",{type:"button",onClick:r,className:"flex-1 border border-gray-300 text-gray-700 hover:bg-gray-50 text-sm font-medium py-2 rounded-md transition-colors",children:"Cancel"}),(0,l.jsx)("button",{type:"button",onClick:a,className:`flex-1 text-white text-sm font-medium py-2 rounded-md transition-colors ${i?"bg-green-500 hover:bg-green-600":"bg-red-500 hover:bg-red-600"}`,children:i?"Approve":"Reject"})]})]})})}function aF({accessToken:e}){let[t,a]=(0,r.useState)([]),[i,s]=(0,r.useState)({total:0,pending_review:0,active:0,rejected:0}),[n,o]=(0,r.useState)(""),[d,c]=(0,r.useState)("all"),[h,f]=(0,r.useState)(null),[j,_]=(0,r.useState)(new Set),[b,v]=(0,r.useState)(null),[w,N]=(0,r.useState)(!0),[C,S]=(0,r.useState)(null),[k,I]=(0,r.useState)(""),[A,O]=(0,r.useState)(!1),[T]=u.Form.useForm(),P=(()=>{let{accessToken:e}=(0,av.default)(),t=(0,a_.useQueryClient)();return(0,aj.useMutation)({mutationFn:async t=>{if(!e)throw Error("Access token is required");return aN(e,t)},onSuccess:()=>{t.invalidateQueries({queryKey:aC.all})}})})();(0,r.useEffect)(()=>{let e=setTimeout(()=>I(n),300);return()=>clearTimeout(e)},[n]);let L=(0,r.useCallback)(async()=>{if(!e)return void N(!1);N(!0),S(null);try{let t="all"===d?void 0:"pending"===d?"pending_review":d,l=await (0,m.listGuardrailSubmissions)(e,{status:t,search:k.trim()||void 0});a(l.submissions.map(aS)),s(l.summary)}catch(e){S(e instanceof Error?e.message:"Failed to load submissions"),a([])}finally{N(!1)}},[e,d,k]);(0,r.useEffect)(()=>{L()},[L]);let B=t.find(e=>e.id===h)??null,F=i.total,$=i.pending_review,E=i.active,M=i.rejected;async function R(l){if(!e)return;let r=t.find(e=>e.id===l);if(!r)return;let i=!r.forwardKey;try{await (0,m.updateGuardrailCall)(e,l,{litellm_params:{forward_api_key:i}}),a(e=>e.map(e=>e.id===l?{...e,forwardKey:i}:e)),y.default.success(i?"Forward API key enabled":"Forward API key disabled")}catch{y.default.fromBackend("Failed to update forward API key")}}async function G(t,l){if(!e)return;let r={};for(let{key:e,value:t}of l)e.trim()&&(r[e.trim()]=t);try{await (0,m.updateGuardrailCall)(e,t,{litellm_params:{headers:r}}),a(e=>e.map(e=>e.id===t?{...e,customHeaders:l.filter(e=>e.key.trim())}:e)),y.default.success("Static headers updated")}catch{y.default.fromBackend("Failed to update static headers")}}async function z(t,l){if(e)try{await (0,m.updateGuardrailCall)(e,t,{litellm_params:{extra_headers:l}}),a(e=>e.map(e=>e.id===t?{...e,extraHeaders:l}:e)),y.default.success("Forward client headers updated")}catch{y.default.fromBackend("Failed to update forward client headers")}}async function D(t){if(e)try{await (0,m.approveGuardrailSubmission)(e,t),v(null),h===t&&f(null),await L(),y.default.success("Guardrail approved")}catch{y.default.fromBackend("Failed to approve guardrail")}}async function K(t){if(e)try{await (0,m.rejectGuardrailSubmission)(e,t),v(null),h===t&&f(null),await L(),y.default.success("Guardrail rejected")}catch{y.default.fromBackend("Failed to reject guardrail")}}return(0,l.jsxs)("div",{className:"flex h-full",children:[(0,l.jsxs)("div",{className:`flex-1 min-w-0 p-6 overflow-auto ${B?"border-r border-gray-200":""}`,children:[(0,l.jsxs)("div",{className:"grid grid-cols-4 gap-4 mb-6",children:[(0,l.jsx)(aA,{label:"Total Submitted",value:F,color:"text-gray-900"}),(0,l.jsx)(aA,{label:"Pending Review",value:$,color:"text-yellow-600"}),(0,l.jsx)(aA,{label:"Active",value:E,color:"text-green-600"}),(0,l.jsx)(aA,{label:"Rejected",value:M,color:"text-red-600"})]}),(0,l.jsxs)("div",{className:"flex items-center gap-3 mb-5",children:[(0,l.jsxs)("div",{className:"relative flex-1 max-w-xs",children:[(0,l.jsx)(ao.SearchIcon,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400"}),(0,l.jsx)("input",{type:"text",placeholder:"Search guardrails...",value:n,onChange:e=>o(e.target.value),className:"w-full pl-9 pr-4 py-2 border border-gray-200 rounded-md text-sm text-gray-700 placeholder-gray-400 focus:outline-hidden focus:ring-1 focus:ring-blue-500 focus:border-blue-500"})]}),(0,l.jsxs)("select",{value:d,onChange:e=>c(e.target.value),className:"border border-gray-200 rounded-md px-3 py-2 text-sm text-gray-700 focus:outline-hidden focus:ring-1 focus:ring-blue-500 focus:border-blue-500 bg-white",children:[(0,l.jsx)("option",{value:"all",children:"All Status"}),(0,l.jsx)("option",{value:"pending",children:"Pending Review"}),(0,l.jsx)("option",{value:"active",children:"Active"}),(0,l.jsx)("option",{value:"rejected",children:"Rejected"})]}),(0,l.jsxs)("button",{type:"button",onClick:()=>O(!0),className:"ml-auto flex items-center gap-2 bg-blue-500 hover:bg-blue-600 text-white text-sm font-medium px-4 py-2 rounded-md transition-colors",children:[(0,l.jsx)(ad.PlusIcon,{className:"h-4 w-4"}),"Add Guardrail"]})]}),(0,l.jsxs)("div",{className:"space-y-3",children:[w&&(0,l.jsx)("div",{className:"text-center py-12 text-gray-500 text-sm",children:"Loading submissions…"}),C&&(0,l.jsx)("div",{className:"text-center py-12 text-red-600 text-sm",children:C}),!w&&!C&&0===t.length&&(0,l.jsx)("div",{className:"text-center py-12 text-gray-400 text-sm",children:"No guardrails match your filters."}),!w&&!C&&t.map(e=>(0,l.jsx)(aT,{guardrail:e,isSelected:h===e.id,isHeadersExpanded:j.has(e.id),onSelect:()=>f(h===e.id?null:e.id),onToggleForwardKey:()=>R(e.id),onToggleHeaders:()=>{var t;return t=e.id,void _(e=>{let a=new Set(e);return a.has(t)?a.delete(t):a.add(t),a})},onApprove:()=>v({id:e.id,action:"approve"}),onReject:()=>v({id:e.id,action:"reject"})},e.id))]})]}),B&&(0,l.jsx)(aL,{guardrail:B,onClose:()=>f(null),onApprove:()=>v({id:B.id,action:"approve"}),onReject:()=>v({id:B.id,action:"reject"}),onToggleForwardKey:()=>R(B.id),onUpdateCustomHeaders:e=>G(B.id,e),onUpdateExtraHeaders:e=>z(B.id,e)}),b&&(0,l.jsx)(aB,{action:b.action,guardrailName:t.find(e=>e.id===b.id)?.name??"",onConfirm:()=>"approve"===b.action?D(b.id):K(b.id),onCancel:()=>v(null)}),(0,l.jsxs)(g.Modal,{title:"Submit Guardrail for Review",open:A,onCancel:()=>{O(!1),T.resetFields()},onOk:()=>T.submit(),okText:"Submit for Review",children:[(0,l.jsx)("div",{className:"rounded-md bg-blue-50 border border-blue-200 px-4 py-3 text-sm text-blue-800 mb-4",children:"Your guardrail will be sent for admin review before it becomes active."}),(0,l.jsxs)(u.Form,{form:T,layout:"vertical",initialValues:{mode:"pre_call"},onFinish:async e=>{let t={...e.extra_litellm_params?JSON.parse(e.extra_litellm_params):{},guardrail:"generic_guardrail_api",mode:e.mode,api_base:e.api_base};try{await P.mutateAsync({team_id:e.team_id,guardrail_name:e.guardrail_name,litellm_params:t,guardrail_info:e.guardrail_info?JSON.parse(e.guardrail_info):void 0}),y.default.success("Guardrail submitted for review"),O(!1),T.resetFields(),L()}catch{}},children:[(0,l.jsx)(u.Form.Item,{label:"Team",name:"team_id",rules:[{required:!0,message:"Select a team"}],children:(0,l.jsx)(ay.default,{})}),(0,l.jsx)(u.Form.Item,{label:"Guardrail Name",name:"guardrail_name",rules:[{required:!0,message:"Enter a guardrail name"}],children:(0,l.jsx)(p.Input,{placeholder:"e.g. pii-detection"})}),(0,l.jsx)(u.Form.Item,{label:"Mode",name:"mode",rules:[{required:!0,message:"Select a mode"}],children:(0,l.jsxs)(x.Select,{children:[(0,l.jsx)(x.Select.Option,{value:"pre_call",children:"Pre Call"}),(0,l.jsx)(x.Select.Option,{value:"post_call",children:"Post Call"}),(0,l.jsx)(x.Select.Option,{value:"during_call",children:"During Call"})]})}),(0,l.jsx)(u.Form.Item,{label:"API Base URL",name:"api_base",rules:[{required:!0,message:"Enter the API base URL"},{type:"url",message:"Must be a valid URL"}],children:(0,l.jsx)(p.Input,{placeholder:"https://your-guardrail-api.com/v1/check",className:"font-mono"})}),(0,l.jsx)(u.Form.Item,{label:"Additional litellm_params (optional)",name:"extra_litellm_params",tooltip:"JSON object merged into litellm_params. e.g. forward_api_key, headers, model, unreachable_fallback",rules:[{validator:(e,t)=>{if(!t)return Promise.resolve();try{let e=JSON.parse(t);if("object"!=typeof e||Array.isArray(e))return Promise.reject("Must be a JSON object");return Promise.resolve()}catch{return Promise.reject("Invalid JSON")}}}],children:(0,l.jsx)(p.Input.TextArea,{rows:3,className:"font-mono text-xs",placeholder:'{"forward_api_key": true, "headers": {"X-Custom": "value"}}'})}),(0,l.jsx)(u.Form.Item,{label:"Guardrail Info (optional)",name:"guardrail_info",rules:[{validator:(e,t)=>{if(!t)return Promise.resolve();try{return JSON.parse(t),Promise.resolve()}catch{return Promise.reject("Invalid JSON")}}}],children:(0,l.jsx)(p.Input.TextArea,{rows:3,className:"font-mono text-xs",placeholder:'{"description": "Detects PII in requests"}'})})]})]})]})}let a$=({accessToken:e,userRole:t})=>{let[a,u]=(0,r.useState)([]),[p,g]=(0,r.useState)(!1),[x,h]=(0,r.useState)(!1),[f,j]=(0,r.useState)(!1),[_,b]=(0,r.useState)(!1),[v,w]=(0,r.useState)(null),[N,C]=(0,r.useState)(!1),[S,k]=(0,r.useState)(null),I=!!t&&(0,tg.isAdminRole)(t),A=async()=>{if(e){j(!0);try{let t=await (0,m.getGuardrailsList)(e);u(t.guardrails)}catch(e){console.error("Error fetching guardrails:",e)}finally{j(!1)}}};(0,r.useEffect)(()=>{A()},[e]);let O=()=>{A()},T=async()=>{if(v&&e){b(!0);try{await (0,m.deleteGuardrailCall)(e,v.guardrail_id),y.default.success(`Guardrail "${v.guardrail_name}" deleted successfully`),await A()}catch(e){console.error("Error deleting guardrail:",e),y.default.fromBackend("Failed to delete guardrail")}finally{b(!1),C(!1),w(null)}}},P=v&&v.litellm_params?eg(v.litellm_params.guardrail).displayName:void 0;return(0,l.jsx)("div",{className:"w-full mx-auto flex-auto overflow-y-auto m-8 p-2",children:(0,l.jsx)(n.Tabs,{defaultActiveKey:"guardrails",items:[...I?[{key:"garden",label:"Guardrail Garden",children:(0,l.jsx)(an,{accessToken:e,onGuardrailCreated:O})},{key:"guardrails",label:"Guardrails",children:(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("div",{className:"flex justify-between items-center mb-4",children:(0,l.jsx)(s.Dropdown,{menu:{items:[{key:"provider",icon:(0,l.jsx)(d.PlusOutlined,{}),label:"Add Provider Guardrail",onClick:()=>{S&&k(null),g(!0)}},{key:"custom_code",icon:(0,l.jsx)(c.CodeOutlined,{}),label:"Create Custom Code Guardrail",onClick:()=>{S&&k(null),h(!0)}}]},trigger:["click"],disabled:!e,children:(0,l.jsxs)(i.Button,{disabled:!e,children:["+ Add New Guardrail ",(0,l.jsx)(o.DownOutlined,{className:"ml-2"})]})})}),S?(0,l.jsx)(tW,{guardrailId:S,onClose:()=>k(null),accessToken:e,isAdmin:I}):(0,l.jsx)(tp,{guardrailsList:a,isLoading:f,onDeleteClick:(e,t)=>{w(a.find(t=>t.guardrail_id===e)||null),C(!0)},accessToken:e,onGuardrailUpdated:A,isAdmin:I,onGuardrailClick:e=>k(e)}),(0,l.jsx)(e1,{visible:p,onClose:()=>{g(!1)},accessToken:e,onSuccess:O}),(0,l.jsx)(tJ,{visible:x,onClose:()=>{h(!1)},accessToken:e,onSuccess:O}),(0,l.jsx)(t3.default,{isOpen:N,title:"Delete Guardrail",message:`Are you sure you want to delete guardrail: ${v?.guardrail_name}? This action cannot be undone.`,resourceInformationTitle:"Guardrail Information",resourceInformation:[{label:"Name",value:v?.guardrail_name},{label:"ID",value:v?.guardrail_id,code:!0},{label:"Provider",value:P},{label:"Mode",value:v?.litellm_params.mode},{label:"Default On",value:v?.litellm_params.default_on?"Yes":"No"}],onCancel:()=>{C(!1),w(null)},onOk:T,confirmLoading:_})]})},{key:"playground",label:"Test Playground",disabled:!e,children:(0,l.jsx)(t6,{guardrailsList:a,isLoading:f,accessToken:e,onClose:()=>{}})}]:[],{key:"submitted",label:"Submitted Guardrails",children:(0,l.jsx)(aF,{accessToken:e})}]})})};e.s(["default",0,function(){let{accessToken:e,userRole:t}=(0,av.default)();return(0,l.jsx)(a$,{accessToken:e,userRole:t})}],509345)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0.bx44y-6~tug.js b/litellm/proxy/_experimental/out/_next/static/chunks/0.bx44y-6~tug.js new file mode 100644 index 00000000000..343688035a1 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/0.bx44y-6~tug.js @@ -0,0 +1,10 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,954616,e=>{"use strict";var t=e.i(271645),n=e.i(114272),i=e.i(540143),l=e.i(915823),r=e.i(619273),a=class extends l.Subscribable{#e;#t=void 0;#n;#i;constructor(e,t){super(),this.#e=e,this.setOptions(t),this.bindMethods(),this.#l()}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(e){let t=this.options;this.options=this.#e.defaultMutationOptions(e),(0,r.shallowEqualObjects)(this.options,t)||this.#e.getMutationCache().notify({type:"observerOptionsUpdated",mutation:this.#n,observer:this}),t?.mutationKey&&this.options.mutationKey&&(0,r.hashKey)(t.mutationKey)!==(0,r.hashKey)(this.options.mutationKey)?this.reset():this.#n?.state.status==="pending"&&this.#n.setOptions(this.options)}onUnsubscribe(){this.hasListeners()||this.#n?.removeObserver(this)}onMutationUpdate(e){this.#l(),this.#r(e)}getCurrentResult(){return this.#t}reset(){this.#n?.removeObserver(this),this.#n=void 0,this.#l(),this.#r()}mutate(e,t){return this.#i=t,this.#n?.removeObserver(this),this.#n=this.#e.getMutationCache().build(this.#e,this.options),this.#n.addObserver(this),this.#n.execute(e)}#l(){let e=this.#n?.state??(0,n.getDefaultState)();this.#t={...e,isPending:"pending"===e.status,isSuccess:"success"===e.status,isError:"error"===e.status,isIdle:"idle"===e.status,mutate:this.mutate,reset:this.reset}}#r(e){i.notifyManager.batch(()=>{if(this.#i&&this.hasListeners()){let t=this.#t.variables,n=this.#t.context,i={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};if(e?.type==="success"){try{this.#i.onSuccess?.(e.data,t,n,i)}catch(e){Promise.reject(e)}try{this.#i.onSettled?.(e.data,null,t,n,i)}catch(e){Promise.reject(e)}}else if(e?.type==="error"){try{this.#i.onError?.(e.error,t,n,i)}catch(e){Promise.reject(e)}try{this.#i.onSettled?.(void 0,e.error,t,n,i)}catch(e){Promise.reject(e)}}}this.listeners.forEach(e=>{e(this.#t)})})}},o=e.i(912598);e.s(["useMutation",0,function(e,n){let l=(0,o.useQueryClient)(n),[s]=t.useState(()=>new a(l,e));t.useEffect(()=>{s.setOptions(e)},[s,e]);let c=t.useSyncExternalStore(t.useCallback(e=>s.subscribe(i.notifyManager.batchCalls(e)),[s]),()=>s.getCurrentResult(),()=>s.getCurrentResult()),d=t.useCallback((e,t)=>{s.mutate(e,t).catch(r.noop)},[s]);if(c.error&&(0,r.shouldThrowError)(s.options.throwOnError,[c.error]))throw c.error;return{...c,mutate:d,mutateAsync:c.mutate}}],954616)},270377,e=>{"use strict";e.i(247167);var t=e.i(931067),n=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"}},{tag:"path",attrs:{d:"M464 688a48 48 0 1096 0 48 48 0 10-96 0zm24-112h48c4.4 0 8-3.6 8-8V296c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8z"}}]},name:"exclamation-circle",theme:"outlined"};var l=e.i(9583),r=n.forwardRef(function(e,r){return n.createElement(l.default,(0,t.default)({},e,{ref:r,icon:i}))});e.s(["ExclamationCircleOutlined",0,r],270377)},175712,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(343794),i=e.i(529681),l=e.i(242064),r=e.i(517455),a=e.i(185793),o=e.i(721369),s=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,i=Object.getOwnPropertySymbols(e);lt.indexOf(i[l])&&Object.prototype.propertyIsEnumerable.call(e,i[l])&&(n[i[l]]=e[i[l]]);return n};let c=e=>{var{prefixCls:i,className:r,hoverable:a=!0}=e,o=s(e,["prefixCls","className","hoverable"]);let{getPrefixCls:c}=t.useContext(l.ConfigContext),d=c("card",i),u=(0,n.default)(`${d}-grid`,r,{[`${d}-grid-hoverable`]:a});return t.createElement("div",Object.assign({},o,{className:u}))};e.i(296059);var d=e.i(915654),u=e.i(183293),g=e.i(246422),b=e.i(838378);let p=(0,g.genStyleHooks)("Card",e=>{let t=(0,b.mergeToken)(e,{cardShadow:e.boxShadowCard,cardHeadPadding:e.padding,cardPaddingBase:e.paddingLG,cardActionsIconSize:e.fontSize});return[(e=>{let{componentCls:t,cardShadow:n,cardHeadPadding:i,colorBorderSecondary:l,boxShadowTertiary:r,bodyPadding:a,extraColor:o}=e;return{[t]:Object.assign(Object.assign({},(0,u.resetComponent)(e)),{position:"relative",background:e.colorBgContainer,borderRadius:e.borderRadiusLG,[`&:not(${t}-bordered)`]:{boxShadow:r},[`${t}-head`]:(e=>{let{antCls:t,componentCls:n,headerHeight:i,headerPadding:l,tabsMarginBottom:r}=e;return Object.assign(Object.assign({display:"flex",justifyContent:"center",flexDirection:"column",minHeight:i,marginBottom:-1,padding:`0 ${(0,d.unit)(l)}`,color:e.colorTextHeading,fontWeight:e.fontWeightStrong,fontSize:e.headerFontSize,background:e.headerBg,borderBottom:`${(0,d.unit)(e.lineWidth)} ${e.lineType} ${e.colorBorderSecondary}`,borderRadius:`${(0,d.unit)(e.borderRadiusLG)} ${(0,d.unit)(e.borderRadiusLG)} 0 0`},(0,u.clearFix)()),{"&-wrapper":{width:"100%",display:"flex",alignItems:"center"},"&-title":Object.assign(Object.assign({display:"inline-block",flex:1},u.textEllipsis),{[` + > ${n}-typography, + > ${n}-typography-edit-content + `]:{insetInlineStart:0,marginTop:0,marginBottom:0}}),[`${t}-tabs-top`]:{clear:"both",marginBottom:r,color:e.colorText,fontWeight:"normal",fontSize:e.fontSize,"&-bar":{borderBottom:`${(0,d.unit)(e.lineWidth)} ${e.lineType} ${e.colorBorderSecondary}`}}})})(e),[`${t}-extra`]:{marginInlineStart:"auto",color:o,fontWeight:"normal",fontSize:e.fontSize},[`${t}-body`]:{padding:a,borderRadius:`0 0 ${(0,d.unit)(e.borderRadiusLG)} ${(0,d.unit)(e.borderRadiusLG)}`},[`${t}-grid`]:(e=>{let{cardPaddingBase:t,colorBorderSecondary:n,cardShadow:i,lineWidth:l}=e;return{width:"33.33%",padding:t,border:0,borderRadius:0,boxShadow:` + ${(0,d.unit)(l)} 0 0 0 ${n}, + 0 ${(0,d.unit)(l)} 0 0 ${n}, + ${(0,d.unit)(l)} ${(0,d.unit)(l)} 0 0 ${n}, + ${(0,d.unit)(l)} 0 0 0 ${n} inset, + 0 ${(0,d.unit)(l)} 0 0 ${n} inset; + `,transition:`all ${e.motionDurationMid}`,"&-hoverable:hover":{position:"relative",zIndex:1,boxShadow:i}}})(e),[`${t}-cover`]:{"> *":{display:"block",width:"100%",borderRadius:`${(0,d.unit)(e.borderRadiusLG)} ${(0,d.unit)(e.borderRadiusLG)} 0 0`}},[`${t}-actions`]:(e=>{let{componentCls:t,iconCls:n,actionsLiMargin:i,cardActionsIconSize:l,colorBorderSecondary:r,actionsBg:a}=e;return Object.assign(Object.assign({margin:0,padding:0,listStyle:"none",background:a,borderTop:`${(0,d.unit)(e.lineWidth)} ${e.lineType} ${r}`,display:"flex",borderRadius:`0 0 ${(0,d.unit)(e.borderRadiusLG)} ${(0,d.unit)(e.borderRadiusLG)}`},(0,u.clearFix)()),{"& > li":{margin:i,color:e.colorTextDescription,textAlign:"center","> span":{position:"relative",display:"block",minWidth:e.calc(e.cardActionsIconSize).mul(2).equal(),fontSize:e.fontSize,lineHeight:e.lineHeight,cursor:"pointer","&:hover":{color:e.colorPrimary,transition:`color ${e.motionDurationMid}`},[`a:not(${t}-btn), > ${n}`]:{display:"inline-block",width:"100%",color:e.colorIcon,lineHeight:(0,d.unit)(e.fontHeight),transition:`color ${e.motionDurationMid}`,"&:hover":{color:e.colorPrimary}},[`> ${n}`]:{fontSize:l,lineHeight:(0,d.unit)(e.calc(l).mul(e.lineHeight).equal())}},"&:not(:last-child)":{borderInlineEnd:`${(0,d.unit)(e.lineWidth)} ${e.lineType} ${r}`}}})})(e),[`${t}-meta`]:Object.assign(Object.assign({margin:`${(0,d.unit)(e.calc(e.marginXXS).mul(-1).equal())} 0`,display:"flex"},(0,u.clearFix)()),{"&-avatar":{paddingInlineEnd:e.padding},"&-detail":{overflow:"hidden",flex:1,"> div:not(:last-child)":{marginBottom:e.marginXS}},"&-title":Object.assign({color:e.colorTextHeading,fontWeight:e.fontWeightStrong,fontSize:e.fontSizeLG},u.textEllipsis),"&-description":{color:e.colorTextDescription}})}),[`${t}-bordered`]:{border:`${(0,d.unit)(e.lineWidth)} ${e.lineType} ${l}`,[`${t}-cover`]:{marginTop:-1,marginInlineStart:-1,marginInlineEnd:-1}},[`${t}-hoverable`]:{cursor:"pointer",transition:`box-shadow ${e.motionDurationMid}, border-color ${e.motionDurationMid}`,"&:hover":{borderColor:"transparent",boxShadow:n}},[`${t}-contain-grid`]:{borderRadius:`${(0,d.unit)(e.borderRadiusLG)} ${(0,d.unit)(e.borderRadiusLG)} 0 0 `,[`${t}-body`]:{display:"flex",flexWrap:"wrap"},[`&:not(${t}-loading) ${t}-body`]:{marginBlockStart:e.calc(e.lineWidth).mul(-1).equal(),marginInlineStart:e.calc(e.lineWidth).mul(-1).equal(),padding:0}},[`${t}-contain-tabs`]:{[`> div${t}-head`]:{minHeight:0,[`${t}-head-title, ${t}-extra`]:{paddingTop:i}}},[`${t}-type-inner`]:(e=>{let{componentCls:t,colorFillAlter:n,headerPadding:i,bodyPadding:l}=e;return{[`${t}-head`]:{padding:`0 ${(0,d.unit)(i)}`,background:n,"&-title":{fontSize:e.fontSize}},[`${t}-body`]:{padding:`${(0,d.unit)(e.padding)} ${(0,d.unit)(l)}`}}})(e),[`${t}-loading`]:(e=>{let{componentCls:t}=e;return{overflow:"hidden",[`${t}-body`]:{userSelect:"none"}}})(e),[`${t}-rtl`]:{direction:"rtl"}}})(t),(e=>{let{componentCls:t,bodyPaddingSM:n,headerPaddingSM:i,headerHeightSM:l,headerFontSizeSM:r}=e;return{[`${t}-small`]:{[`> ${t}-head`]:{minHeight:l,padding:`0 ${(0,d.unit)(i)}`,fontSize:r,[`> ${t}-head-wrapper`]:{[`> ${t}-extra`]:{fontSize:e.fontSize}}},[`> ${t}-body`]:{padding:n}},[`${t}-small${t}-contain-tabs`]:{[`> ${t}-head`]:{[`${t}-head-title, ${t}-extra`]:{paddingTop:0,display:"flex",alignItems:"center"}}}}})(t)]},e=>{var t,n;return{headerBg:"transparent",headerFontSize:e.fontSizeLG,headerFontSizeSM:e.fontSize,headerHeight:e.fontSizeLG*e.lineHeightLG+2*e.padding,headerHeightSM:e.fontSize*e.lineHeight+2*e.paddingXS,actionsBg:e.colorBgContainer,actionsLiMargin:`${e.paddingSM}px 0`,tabsMarginBottom:-e.padding-e.lineWidth,extraColor:e.colorText,bodyPaddingSM:12,headerPaddingSM:12,bodyPadding:null!=(t=e.bodyPadding)?t:e.paddingLG,headerPadding:null!=(n=e.headerPadding)?n:e.paddingLG}});var m=e.i(792812),h=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,i=Object.getOwnPropertySymbols(e);lt.indexOf(i[l])&&Object.prototype.propertyIsEnumerable.call(e,i[l])&&(n[i[l]]=e[i[l]]);return n};let f=e=>{let{actionClasses:n,actions:i=[],actionStyle:l}=e;return t.createElement("ul",{className:n,style:l},i.map((e,n)=>{let l=`action-${n}`;return t.createElement("li",{style:{width:`${100/i.length}%`},key:l},t.createElement("span",null,e))}))},y=t.forwardRef((e,s)=>{let d,{prefixCls:u,className:g,rootClassName:b,style:y,extra:$,headStyle:v={},bodyStyle:O={},title:x,loading:j,bordered:S,variant:C,size:E,type:w,cover:N,actions:z,tabList:M,children:P,activeTabKey:B,defaultActiveTabKey:T,tabBarExtraContent:k,hoverable:R,tabProps:L={},classNames:G,styles:I}=e,H=h(e,["prefixCls","className","rootClassName","style","extra","headStyle","bodyStyle","title","loading","bordered","variant","size","type","cover","actions","tabList","children","activeTabKey","defaultActiveTabKey","tabBarExtraContent","hoverable","tabProps","classNames","styles"]),{getPrefixCls:W,direction:D,card:A}=t.useContext(l.ConfigContext),[F]=(0,m.default)("card",C,S),X=e=>{var t;return(0,n.default)(null==(t=null==A?void 0:A.classNames)?void 0:t[e],null==G?void 0:G[e])},K=e=>{var t;return Object.assign(Object.assign({},null==(t=null==A?void 0:A.styles)?void 0:t[e]),null==I?void 0:I[e])},q=t.useMemo(()=>{let e=!1;return t.Children.forEach(P,t=>{(null==t?void 0:t.type)===c&&(e=!0)}),e},[P]),U=W("card",u),[Q,V,_]=p(U),J=t.createElement(a.default,{loading:!0,active:!0,paragraph:{rows:4},title:!1},P),Y=void 0!==B,Z=Object.assign(Object.assign({},L),{[Y?"activeKey":"defaultActiveKey"]:Y?B:T,tabBarExtraContent:k}),ee=(0,r.default)(E),et=ee&&"default"!==ee?ee:"large",en=M?t.createElement(o.default,Object.assign({size:et},Z,{className:`${U}-head-tabs`,onChange:t=>{var n;null==(n=e.onTabChange)||n.call(e,t)},items:M.map(e=>{var{tab:t}=e;return Object.assign({label:t},h(e,["tab"]))})})):null;if(x||$||en){let e=(0,n.default)(`${U}-head`,X("header")),i=(0,n.default)(`${U}-head-title`,X("title")),l=(0,n.default)(`${U}-extra`,X("extra")),r=Object.assign(Object.assign({},v),K("header"));d=t.createElement("div",{className:e,style:r},t.createElement("div",{className:`${U}-head-wrapper`},x&&t.createElement("div",{className:i,style:K("title")},x),$&&t.createElement("div",{className:l,style:K("extra")},$)),en)}let ei=(0,n.default)(`${U}-cover`,X("cover")),el=N?t.createElement("div",{className:ei,style:K("cover")},N):null,er=(0,n.default)(`${U}-body`,X("body")),ea=Object.assign(Object.assign({},O),K("body")),eo=t.createElement("div",{className:er,style:ea},j?J:P),es=(0,n.default)(`${U}-actions`,X("actions")),ec=(null==z?void 0:z.length)?t.createElement(f,{actionClasses:es,actionStyle:K("actions"),actions:z}):null,ed=(0,i.default)(H,["onTabChange"]),eu=(0,n.default)(U,null==A?void 0:A.className,{[`${U}-loading`]:j,[`${U}-bordered`]:"borderless"!==F,[`${U}-hoverable`]:R,[`${U}-contain-grid`]:q,[`${U}-contain-tabs`]:null==M?void 0:M.length,[`${U}-${ee}`]:ee,[`${U}-type-${w}`]:!!w,[`${U}-rtl`]:"rtl"===D},g,b,V,_),eg=Object.assign(Object.assign({},null==A?void 0:A.style),y);return Q(t.createElement("div",Object.assign({ref:s},ed,{className:eu,style:eg}),d,el,eo,ec))});var $=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,i=Object.getOwnPropertySymbols(e);lt.indexOf(i[l])&&Object.prototype.propertyIsEnumerable.call(e,i[l])&&(n[i[l]]=e[i[l]]);return n};y.Grid=c,y.Meta=e=>{let{prefixCls:i,className:r,avatar:a,title:o,description:s}=e,c=$(e,["prefixCls","className","avatar","title","description"]),{getPrefixCls:d}=t.useContext(l.ConfigContext),u=d("card",i),g=(0,n.default)(`${u}-meta`,r),b=a?t.createElement("div",{className:`${u}-meta-avatar`},a):null,p=o?t.createElement("div",{className:`${u}-meta-title`},o):null,m=s?t.createElement("div",{className:`${u}-meta-description`},s):null,h=p||m?t.createElement("div",{className:`${u}-meta-detail`},p,m):null;return t.createElement("div",Object.assign({},c,{className:g}),b,h)},e.s(["Card",0,y],175712)},869216,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(343794),i=e.i(908206),l=e.i(242064),r=e.i(517455),a=e.i(150073);let o={xxl:3,xl:3,lg:3,md:3,sm:2,xs:1},s=t.default.createContext({});var c=e.i(876556),d=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,i=Object.getOwnPropertySymbols(e);lt.indexOf(i[l])&&Object.prototype.propertyIsEnumerable.call(e,i[l])&&(n[i[l]]=e[i[l]]);return n},u=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,i=Object.getOwnPropertySymbols(e);lt.indexOf(i[l])&&Object.prototype.propertyIsEnumerable.call(e,i[l])&&(n[i[l]]=e[i[l]]);return n};let g=e=>{let{itemPrefixCls:i,component:l,span:r,className:a,style:o,labelStyle:c,contentStyle:d,bordered:u,label:g,content:b,colon:p,type:m,styles:h}=e,{classNames:f}=t.useContext(s),y=Object.assign(Object.assign({},c),null==h?void 0:h.label),$=Object.assign(Object.assign({},d),null==h?void 0:h.content);if(u)return t.createElement(l,{colSpan:r,style:o,className:(0,n.default)(a,{[`${i}-item-${m}`]:"label"===m||"content"===m,[null==f?void 0:f.label]:(null==f?void 0:f.label)&&"label"===m,[null==f?void 0:f.content]:(null==f?void 0:f.content)&&"content"===m})},null!=g&&t.createElement("span",{style:y},g),null!=b&&t.createElement("span",{style:$},b));return t.createElement(l,{colSpan:r,style:o,className:(0,n.default)(`${i}-item`,a)},t.createElement("div",{className:`${i}-item-container`},null!=g&&t.createElement("span",{style:y,className:(0,n.default)(`${i}-item-label`,null==f?void 0:f.label,{[`${i}-item-no-colon`]:!p})},g),null!=b&&t.createElement("span",{style:$,className:(0,n.default)(`${i}-item-content`,null==f?void 0:f.content)},b)))};function b(e,{colon:n,prefixCls:i,bordered:l},{component:r,type:a,showLabel:o,showContent:s,labelStyle:c,contentStyle:d,styles:u}){return e.map(({label:e,children:b,prefixCls:p=i,className:m,style:h,labelStyle:f,contentStyle:y,span:$=1,key:v,styles:O},x)=>"string"==typeof r?t.createElement(g,{key:`${a}-${v||x}`,className:m,style:h,styles:{label:Object.assign(Object.assign(Object.assign(Object.assign({},c),null==u?void 0:u.label),f),null==O?void 0:O.label),content:Object.assign(Object.assign(Object.assign(Object.assign({},d),null==u?void 0:u.content),y),null==O?void 0:O.content)},span:$,colon:n,component:r,itemPrefixCls:p,bordered:l,label:o?e:null,content:s?b:null,type:a}):[t.createElement(g,{key:`label-${v||x}`,className:m,style:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},c),null==u?void 0:u.label),h),f),null==O?void 0:O.label),span:1,colon:n,component:r[0],itemPrefixCls:p,bordered:l,label:e,type:"label"}),t.createElement(g,{key:`content-${v||x}`,className:m,style:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},d),null==u?void 0:u.content),h),y),null==O?void 0:O.content),span:2*$-1,component:r[1],itemPrefixCls:p,bordered:l,content:b,type:"content"})])}let p=e=>{let n=t.useContext(s),{prefixCls:i,vertical:l,row:r,index:a,bordered:o}=e;return l?t.createElement(t.Fragment,null,t.createElement("tr",{key:`label-${a}`,className:`${i}-row`},b(r,e,Object.assign({component:"th",type:"label",showLabel:!0},n))),t.createElement("tr",{key:`content-${a}`,className:`${i}-row`},b(r,e,Object.assign({component:"td",type:"content",showContent:!0},n)))):t.createElement("tr",{key:a,className:`${i}-row`},b(r,e,Object.assign({component:o?["th","td"]:"td",type:"item",showLabel:!0,showContent:!0},n)))};e.i(296059);var m=e.i(915654),h=e.i(183293),f=e.i(246422),y=e.i(838378);let $=(0,f.genStyleHooks)("Descriptions",e=>(e=>{let{componentCls:t,extraColor:n,itemPaddingBottom:i,itemPaddingEnd:l,colonMarginRight:r,colonMarginLeft:a,titleMarginBottom:o}=e;return{[t]:Object.assign(Object.assign(Object.assign({},(0,h.resetComponent)(e)),(e=>{let{componentCls:t,labelBg:n}=e;return{[`&${t}-bordered`]:{[`> ${t}-view`]:{border:`${(0,m.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,"> table":{tableLayout:"auto"},[`${t}-row`]:{borderBottom:`${(0,m.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,"&:first-child":{"> th:first-child, > td:first-child":{borderStartStartRadius:e.borderRadiusLG}},"&:last-child":{borderBottom:"none","> th:first-child, > td:first-child":{borderEndStartRadius:e.borderRadiusLG}},[`> ${t}-item-label, > ${t}-item-content`]:{padding:`${(0,m.unit)(e.padding)} ${(0,m.unit)(e.paddingLG)}`,borderInlineEnd:`${(0,m.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,"&:last-child":{borderInlineEnd:"none"}},[`> ${t}-item-label`]:{color:e.colorTextSecondary,backgroundColor:n,"&::after":{display:"none"}}}},[`&${t}-middle`]:{[`${t}-row`]:{[`> ${t}-item-label, > ${t}-item-content`]:{padding:`${(0,m.unit)(e.paddingSM)} ${(0,m.unit)(e.paddingLG)}`}}},[`&${t}-small`]:{[`${t}-row`]:{[`> ${t}-item-label, > ${t}-item-content`]:{padding:`${(0,m.unit)(e.paddingXS)} ${(0,m.unit)(e.padding)}`}}}}}})(e)),{"&-rtl":{direction:"rtl"},[`${t}-header`]:{display:"flex",alignItems:"center",marginBottom:o},[`${t}-title`]:Object.assign(Object.assign({},h.textEllipsis),{flex:"auto",color:e.titleColor,fontWeight:e.fontWeightStrong,fontSize:e.fontSizeLG,lineHeight:e.lineHeightLG}),[`${t}-extra`]:{marginInlineStart:"auto",color:n,fontSize:e.fontSize},[`${t}-view`]:{width:"100%",borderRadius:e.borderRadiusLG,table:{width:"100%",tableLayout:"fixed",borderCollapse:"collapse"}},[`${t}-row`]:{"> th, > td":{paddingBottom:i,paddingInlineEnd:l},"> th:last-child, > td:last-child":{paddingInlineEnd:0},"&:last-child":{borderBottom:"none","> th, > td":{paddingBottom:0}}},[`${t}-item-label`]:{color:e.labelColor,fontWeight:"normal",fontSize:e.fontSize,lineHeight:e.lineHeight,textAlign:"start","&::after":{content:'":"',position:"relative",top:-.5,marginInline:`${(0,m.unit)(a)} ${(0,m.unit)(r)}`},[`&${t}-item-no-colon::after`]:{content:'""'}},[`${t}-item-no-label`]:{"&::after":{margin:0,content:'""'}},[`${t}-item-content`]:{display:"table-cell",flex:1,color:e.contentColor,fontSize:e.fontSize,lineHeight:e.lineHeight,wordBreak:"break-word",overflowWrap:"break-word"},[`${t}-item`]:{paddingBottom:0,verticalAlign:"top","&-container":{display:"flex",[`${t}-item-label`]:{display:"inline-flex",alignItems:"baseline"},[`${t}-item-content`]:{display:"inline-flex",alignItems:"baseline",minWidth:"1em"}}},"&-middle":{[`${t}-row`]:{"> th, > td":{paddingBottom:e.paddingSM}}},"&-small":{[`${t}-row`]:{"> th, > td":{paddingBottom:e.paddingXS}}}})}})((0,y.mergeToken)(e,{})),e=>({labelBg:e.colorFillAlter,labelColor:e.colorTextTertiary,titleColor:e.colorText,titleMarginBottom:e.fontSizeSM*e.lineHeightSM,itemPaddingBottom:e.padding,itemPaddingEnd:e.padding,colonMarginRight:e.marginXS,colonMarginLeft:e.marginXXS/2,contentColor:e.colorText,extraColor:e.colorText}));var v=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,i=Object.getOwnPropertySymbols(e);lt.indexOf(i[l])&&Object.prototype.propertyIsEnumerable.call(e,i[l])&&(n[i[l]]=e[i[l]]);return n};let O=e=>{let g,{prefixCls:b,title:m,extra:h,column:f,colon:y=!0,bordered:O,layout:x,children:j,className:S,rootClassName:C,style:E,size:w,labelStyle:N,contentStyle:z,styles:M,items:P,classNames:B}=e,T=v(e,["prefixCls","title","extra","column","colon","bordered","layout","children","className","rootClassName","style","size","labelStyle","contentStyle","styles","items","classNames"]),{getPrefixCls:k,direction:R,className:L,style:G,classNames:I,styles:H}=(0,l.useComponentConfig)("descriptions"),W=k("descriptions",b),D=(0,a.default)(),A=t.useMemo(()=>{var e;return"number"==typeof f?f:null!=(e=(0,i.matchScreen)(D,Object.assign(Object.assign({},o),f)))?e:3},[D,f]),F=(g=t.useMemo(()=>P||(0,c.default)(j).map(e=>Object.assign(Object.assign({},null==e?void 0:e.props),{key:e.key})),[P,j]),t.useMemo(()=>g.map(e=>{var{span:t}=e,n=d(e,["span"]);return"filled"===t?Object.assign(Object.assign({},n),{filled:!0}):Object.assign(Object.assign({},n),{span:"number"==typeof t?t:(0,i.matchScreen)(D,t)})}),[g,D])),X=(0,r.default)(w),K=((e,n)=>{let[i,l]=(0,t.useMemo)(()=>{let t,i,l,r;return t=[],i=[],l=!1,r=0,n.filter(e=>e).forEach(n=>{let{filled:a}=n,o=u(n,["filled"]);if(a){i.push(o),t.push(i),i=[],r=0;return}let s=e-r;(r+=n.span||1)>=e?(r>e?(l=!0,i.push(Object.assign(Object.assign({},o),{span:s}))):i.push(o),t.push(i),i=[],r=0):i.push(o)}),i.length>0&&t.push(i),[t=t.map(t=>{let n=t.reduce((e,t)=>e+(t.span||1),0);if(n({labelStyle:N,contentStyle:z,styles:{content:Object.assign(Object.assign({},H.content),null==M?void 0:M.content),label:Object.assign(Object.assign({},H.label),null==M?void 0:M.label)},classNames:{label:(0,n.default)(I.label,null==B?void 0:B.label),content:(0,n.default)(I.content,null==B?void 0:B.content)}}),[N,z,M,B,I,H]);return q(t.createElement(s.Provider,{value:V},t.createElement("div",Object.assign({className:(0,n.default)(W,L,I.root,null==B?void 0:B.root,{[`${W}-${X}`]:X&&"default"!==X,[`${W}-bordered`]:!!O,[`${W}-rtl`]:"rtl"===R},S,C,U,Q),style:Object.assign(Object.assign(Object.assign(Object.assign({},G),H.root),null==M?void 0:M.root),E)},T),(m||h)&&t.createElement("div",{className:(0,n.default)(`${W}-header`,I.header,null==B?void 0:B.header),style:Object.assign(Object.assign({},H.header),null==M?void 0:M.header)},m&&t.createElement("div",{className:(0,n.default)(`${W}-title`,I.title,null==B?void 0:B.title),style:Object.assign(Object.assign({},H.title),null==M?void 0:M.title)},m),h&&t.createElement("div",{className:(0,n.default)(`${W}-extra`,I.extra,null==B?void 0:B.extra),style:Object.assign(Object.assign({},H.extra),null==M?void 0:M.extra)},h)),t.createElement("div",{className:`${W}-view`},t.createElement("table",null,t.createElement("tbody",null,K.map((e,n)=>t.createElement(p,{key:n,index:n,colon:y,prefixCls:W,vertical:"vertical"===x,bordered:O,row:e}))))))))};O.Item=({children:e})=>e,e.s(["Descriptions",0,O],869216)},368869,e=>{"use strict";e.i(296059);var t=e.i(868297),n=e.i(732961),i=e.i(289882),l=e.i(170517),r=e.i(628882),a=e.i(320890),o=e.i(104458),s=e.i(722319),c=e.i(8398),d=e.i(279728);e.i(765846);var u=e.i(602716),g=e.i(328052),b=e.i(135551);let p=(e,t)=>new b.FastColor(e).setA(t).toRgbString(),m=(e,t)=>new b.FastColor(e).lighten(t).toHexString(),h=e=>{let t=(0,u.generate)(e,{theme:"dark"});return{1:t[0],2:t[1],3:t[2],4:t[3],5:t[6],6:t[5],7:t[4],8:t[6],9:t[5],10:t[4]}},f=(e,t)=>{let n=e||"#000",i=t||"#fff";return{colorBgBase:n,colorTextBase:i,colorText:p(i,.85),colorTextSecondary:p(i,.65),colorTextTertiary:p(i,.45),colorTextQuaternary:p(i,.25),colorFill:p(i,.18),colorFillSecondary:p(i,.12),colorFillTertiary:p(i,.08),colorFillQuaternary:p(i,.04),colorBgSolid:p(i,.95),colorBgSolidHover:p(i,1),colorBgSolidActive:p(i,.9),colorBgElevated:m(n,12),colorBgContainer:m(n,8),colorBgLayout:m(n,0),colorBgSpotlight:m(n,26),colorBgBlur:p(i,.04),colorBorder:m(n,26),colorBorderSecondary:m(n,19)}},y={defaultSeed:a.defaultConfig.token,useToken:function(){let[e,t,n]=(0,o.useToken)();return{theme:e,token:t,hashId:n}},defaultAlgorithm:s.default,darkAlgorithm:(e,t)=>{let n=Object.keys(l.defaultPresetColors).map(t=>{let n=(0,u.generate)(e[t],{theme:"dark"});return Array.from({length:10},()=>1).reduce((e,i,l)=>(e[`${t}-${l+1}`]=n[l],e[`${t}${l+1}`]=n[l],e),{})}).reduce((e,t)=>e=Object.assign(Object.assign({},e),t),{}),i=null!=t?t:(0,s.default)(e),r=(0,g.default)(e,{generateColorPalettes:h,generateNeutralColorPalettes:f});return Object.assign(Object.assign(Object.assign(Object.assign({},i),n),r),{colorPrimaryBg:r.colorPrimaryBorder,colorPrimaryBgHover:r.colorPrimaryBorderHover})},compactAlgorithm:(e,t)=>{let n=null!=t?t:(0,s.default)(e),i=n.fontSizeSM,l=n.controlHeight-4;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},n),function(e){let{sizeUnit:t,sizeStep:n}=e,i=n-2;return{sizeXXL:t*(i+10),sizeXL:t*(i+6),sizeLG:t*(i+2),sizeMD:t*(i+2),sizeMS:t*(i+1),size:t*i,sizeSM:t*i,sizeXS:t*(i-1),sizeXXS:t*(i-1)}}(null!=t?t:e)),(0,d.default)(i)),{controlHeight:l}),(0,c.default)(Object.assign(Object.assign({},n),{controlHeight:l})))},getDesignToken:e=>{let a=(null==e?void 0:e.algorithm)?(0,t.createTheme)(e.algorithm):i.default,o=Object.assign(Object.assign({},l.default),null==e?void 0:e.token);return(0,n.getComputedToken)(o,{override:null==e?void 0:e.token},a,r.default)},defaultConfig:a.defaultConfig,_internalContext:a.DesignTokenContext};e.s(["theme",0,y],368869)},127952,e=>{"use strict";var t=e.i(843476),n=e.i(560445),i=e.i(175712),l=e.i(869216),r=e.i(311451),a=e.i(212931),o=e.i(898586),s=e.i(368869),c=e.i(270377),d=e.i(271645);e.s(["default",0,function({isOpen:e,title:u,alertMessage:g,message:b,resourceInformationTitle:p,resourceInformation:m,onCancel:h,onOk:f,confirmLoading:y,requiredConfirmation:$}){let{Title:v,Text:O}=o.Typography,{token:x}=s.theme.useToken(),[j,S]=(0,d.useState)("");return(0,d.useEffect)(()=>{e&&S("")},[e]),(0,t.jsx)(a.Modal,{title:u,open:e,onOk:f,onCancel:h,confirmLoading:y,okText:y?"Deleting...":"Delete",cancelText:"Cancel",okButtonProps:{danger:!0,disabled:!!$&&j!==$||y},cancelButtonProps:{disabled:y},children:(0,t.jsxs)("div",{className:"space-y-4",children:[g&&(0,t.jsx)(n.Alert,{message:g,type:"warning"}),(0,t.jsx)(i.Card,{title:p,className:"mt-4",styles:{body:{padding:"16px"},header:{backgroundColor:x.colorErrorBg,borderColor:x.colorErrorBorder}},style:{backgroundColor:x.colorErrorBg,borderColor:x.colorErrorBorder},children:(0,t.jsx)(l.Descriptions,{column:1,size:"small",children:m&&m.map(({label:e,value:n,...i})=>(0,t.jsx)(l.Descriptions.Item,{label:(0,t.jsx)("span",{className:"font-semibold",children:e}),children:(0,t.jsx)(O,{...i,children:n??"-"})},e))})}),(0,t.jsx)("div",{children:(0,t.jsx)(O,{children:b})}),$&&(0,t.jsxs)("div",{className:"mb-6 mt-4 pt-4 border-t border-gray-200 dark:border-gray-700",children:[(0,t.jsxs)(O,{className:"block text-base font-medium text-gray-700 dark:text-gray-300 mb-2",children:[(0,t.jsx)(O,{children:"Type "}),(0,t.jsx)(O,{strong:!0,type:"danger",children:$}),(0,t.jsx)(O,{children:" to confirm deletion:"})]}),(0,t.jsx)(r.Input,{value:j,onChange:e=>S(e.target.value),placeholder:$,className:"rounded-md",prefix:(0,t.jsx)(c.ExclamationCircleOutlined,{style:{color:x.colorError}}),autoFocus:!0})]})]})})}])},525720,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(343794),i=e.i(529681),l=e.i(908286),r=e.i(242064),a=e.i(246422),o=e.i(838378);let s=["wrap","nowrap","wrap-reverse"],c=["flex-start","flex-end","start","end","center","space-between","space-around","space-evenly","stretch","normal","left","right"],d=["center","start","end","flex-start","flex-end","self-start","self-end","baseline","normal","stretch"],u=function(e,t){let i,l,r;return(0,n.default)(Object.assign(Object.assign(Object.assign({},(i=!0===t.wrap?"wrap":t.wrap,{[`${e}-wrap-${i}`]:i&&s.includes(i)})),(l={},d.forEach(n=>{l[`${e}-align-${n}`]=t.align===n}),l[`${e}-align-stretch`]=!t.align&&!!t.vertical,l)),(r={},c.forEach(n=>{r[`${e}-justify-${n}`]=t.justify===n}),r)))},g=(0,a.genStyleHooks)("Flex",e=>{let{paddingXS:t,padding:n,paddingLG:i}=e,l=(0,o.mergeToken)(e,{flexGapSM:t,flexGap:n,flexGapLG:i});return[(e=>{let{componentCls:t}=e;return{[t]:{display:"flex",margin:0,padding:0,"&-vertical":{flexDirection:"column"},"&-rtl":{direction:"rtl"},"&:empty":{display:"none"}}}})(l),(e=>{let{componentCls:t}=e;return{[t]:{"&-gap-small":{gap:e.flexGapSM},"&-gap-middle":{gap:e.flexGap},"&-gap-large":{gap:e.flexGapLG}}}})(l),(e=>{let{componentCls:t}=e,n={};return s.forEach(e=>{n[`${t}-wrap-${e}`]={flexWrap:e}}),n})(l),(e=>{let{componentCls:t}=e,n={};return d.forEach(e=>{n[`${t}-align-${e}`]={alignItems:e}}),n})(l),(e=>{let{componentCls:t}=e,n={};return c.forEach(e=>{n[`${t}-justify-${e}`]={justifyContent:e}}),n})(l)]},()=>({}),{resetStyle:!1});var b=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,i=Object.getOwnPropertySymbols(e);lt.indexOf(i[l])&&Object.prototype.propertyIsEnumerable.call(e,i[l])&&(n[i[l]]=e[i[l]]);return n};let p=t.default.forwardRef((e,a)=>{let{prefixCls:o,rootClassName:s,className:c,style:d,flex:p,gap:m,vertical:h=!1,component:f="div",children:y}=e,$=b(e,["prefixCls","rootClassName","className","style","flex","gap","vertical","component","children"]),{flex:v,direction:O,getPrefixCls:x}=t.default.useContext(r.ConfigContext),j=x("flex",o),[S,C,E]=g(j),w=null!=h?h:null==v?void 0:v.vertical,N=(0,n.default)(c,s,null==v?void 0:v.className,j,C,E,u(j,e),{[`${j}-rtl`]:"rtl"===O,[`${j}-gap-${m}`]:(0,l.isPresetSize)(m),[`${j}-vertical`]:w}),z=Object.assign(Object.assign({},null==v?void 0:v.style),d);return p&&(z.flex=p),m&&!(0,l.isPresetSize)(m)&&(z.gap=m),S(t.default.createElement(f,Object.assign({ref:a,className:N,style:z},(0,i.default)($,["justify","wrap","align"])),y))});e.s(["Flex",0,p],525720)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0.w8~sa9q0n_s.js b/litellm/proxy/_experimental/out/_next/static/chunks/0.w8~sa9q0n_s.js new file mode 100644 index 00000000000..6994bde5e6d --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/0.w8~sa9q0n_s.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,207082,e=>{"use strict";var t=e.i(619273),s=e.i(266027),l=e.i(243652),a=e.i(602869),r=e.i(431703),i=e.i(135214);let n=(0,l.createQueryKeys)("keys"),o=async(e,t,s,l={})=>{try{let i=(0,a.getProxyBaseUrl)(),n=new URLSearchParams(Object.entries({team_id:l.teamID,project_id:l.projectID,agent_id:l.agentID,organization_id:l.organizationID,key_alias:l.selectedKeyAlias,key_hash:l.keyHash,user_id:l.userID,page:t,size:s,sort_by:l.sortBy,sort_order:l.sortOrder,expand:l.expand,status:l.status,return_full_object:"true",include_team_keys:"true",include_created_by_keys:"true",substring_matching:"true"}).filter(([,e])=>null!=e).map(([e,t])=>[e,String(t)])),o=`${i?`${i}/key/list`:"/key/list"}?${n}`,d=await fetch(o,{method:"GET",headers:{[(0,a.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!d.ok){let e=await d.json(),t=(0,r.deriveErrorMessage)(e);throw(0,a.handleError)(t),Error(t)}return await d.json()}catch(e){throw console.error("Failed to list keys:",e),e}},d=(0,l.createQueryKeys)("deletedKeys");e.s(["keyKeys",0,n,"useDeletedKeys",0,(e,l,a={})=>{let{accessToken:r}=(0,i.default)();return(0,s.useQuery)({queryKey:d.list({page:e,limit:l,...a}),queryFn:async()=>await o(r,e,l,{...a,status:"deleted"}),enabled:!!r,staleTime:3e4,placeholderData:t.keepPreviousData})},"useKeys",0,(e,l,a={})=>{let{accessToken:r}=(0,i.default)();return(0,s.useQuery)({queryKey:n.list({page:e,limit:l,...a}),queryFn:async()=>await o(r,e,l,a),enabled:!!r,staleTime:3e4,placeholderData:t.keepPreviousData})}])},510674,e=>{"use strict";var t=e.i(266027),s=e.i(243652),l=e.i(602869),a=e.i(431703),r=e.i(135214),i=e.i(708347);let n=(0,s.createQueryKeys)("projects"),o=[...i.all_admin_roles,...i.internalUserRoles],d=async e=>{let t=(0,l.getProxyBaseUrl)(),s=`${t}/project/list`,r=await fetch(s,{method:"GET",headers:{[(0,l.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!r.ok){let e=await r.json(),t=(0,a.deriveErrorMessage)(e);throw(0,l.handleError)(t),Error(t)}return r.json()};e.s(["projectKeys",0,n,"useProjects",0,()=>{let{accessToken:e,userRole:s}=(0,r.default)();return(0,t.useQuery)({queryKey:n.list({}),queryFn:async()=>d(e),enabled:!!e&&o.includes(s)})}])},109034,e=>{"use strict";var t=e.i(266027),s=e.i(243652),l=e.i(602869),a=e.i(135214);let r=(0,s.createQueryKeys)("tags");e.s(["useTags",0,()=>{let{accessToken:e,userId:s,userRole:i}=(0,a.default)();return(0,t.useQuery)({queryKey:r.list({}),queryFn:async()=>await (0,l.tagListCall)(e),enabled:!!(e&&s&&i)})}])},552130,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(199133),a=e.i(602869);e.s(["default",0,({onChange:e,value:r,className:i,accessToken:n,placeholder:o="Select agents",disabled:d=!1})=>{let[c,u]=(0,s.useState)([]),[m,p]=(0,s.useState)([]),[g,h]=(0,s.useState)(!1);(0,s.useEffect)(()=>{(async()=>{if(n){h(!0);try{let e=await (0,a.getAgentsList)(n),t=e?.agents||[];u(t);let s=new Set;t.forEach(e=>{let t=e.agent_access_groups;t&&Array.isArray(t)&&t.forEach(e=>s.add(e))}),p(Array.from(s))}catch(e){console.error("Error fetching agents:",e)}finally{h(!1)}}})()},[n]);let x=[...m.map(e=>({label:e,value:`group:${e}`,isAccessGroup:!0,searchText:`${e} Access Group`})),...c.map(e=>({label:`${e.agent_name||e.agent_id}`,value:e.agent_id,isAccessGroup:!1,searchText:`${e.agent_name||e.agent_id} ${e.agent_id} Agent`}))],y=[...r?.agents||[],...(r?.accessGroups||[]).map(e=>`group:${e}`)];return(0,t.jsx)("div",{children:(0,t.jsx)(l.Select,{mode:"multiple",placeholder:o,onChange:t=>{e({agents:t.filter(e=>!e.startsWith("group:")),accessGroups:t.filter(e=>e.startsWith("group:")).map(e=>e.replace("group:",""))})},value:y,loading:g,className:i,allowClear:!0,showSearch:!0,style:{width:"100%"},disabled:d,filterOption:(e,t)=>(x.find(e=>e.value===t?.value)?.searchText||"").toLowerCase().includes(e.toLowerCase()),children:x.map(e=>(0,t.jsx)(l.Select.Option,{value:e.value,label:e.label,children:(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[(0,t.jsx)("span",{style:{display:"inline-block",width:8,height:8,borderRadius:"50%",background:e.isAccessGroup?"#52c41a":"#722ed1",flexShrink:0}}),(0,t.jsx)("span",{style:{flex:1},children:e.label}),(0,t.jsx)("span",{style:{color:e.isAccessGroup?"#52c41a":"#722ed1",fontSize:"12px",fontWeight:500,opacity:.8},children:e.isAccessGroup?"Access Group":"Agent"})]})},e.value))})})}])},557662,e=>{"use strict";let t="/ui/assets/logos/",s=[{id:"arize",displayName:"Arize",logo:`${t}arize.png`,supports_key_team_logging:!0,dynamic_params:{arize_api_key:"password",arize_space_id:"password"},description:"Arize Logging Integration"},{id:"braintrust",displayName:"Braintrust",logo:`${t}braintrust.png`,supports_key_team_logging:!1,dynamic_params:{braintrust_api_key:"password",braintrust_project_name:"text"},description:"Braintrust Logging Integration"},{id:"custom_callback_api",displayName:"Custom Callback API",logo:`${t}custom.svg`,supports_key_team_logging:!0,dynamic_params:{custom_callback_api_url:"text",custom_callback_api_headers:"text"},description:"Custom Callback API Logging Integration"},{id:"galileo",displayName:"Galileo",logo:`${t}galileo.ico`,supports_key_team_logging:!1,dynamic_params:{GALILEO_API_KEY:"password",GALILEO_PROJECT_ID:"text",GALILEO_LOG_STREAM_ID:"text",GALILEO_BASE_URL:"text",GALILEO_USERNAME:"text",GALILEO_PASSWORD:"password"},description:"Galileo AI Observability Integration"},{id:"datadog",displayName:"Datadog",logo:`${t}datadog.png`,supports_key_team_logging:!1,dynamic_params:{dd_api_key:"password",dd_site:"text"},description:"Datadog Logging Integration"},{id:"lago",displayName:"Lago",logo:`${t}lago.svg`,supports_key_team_logging:!1,dynamic_params:{lago_api_url:"text",lago_api_key:"password"},description:"Lago Billing Logging Integration"},{id:"langfuse",displayName:"Langfuse",logo:`${t}langfuse.png`,supports_key_team_logging:!0,dynamic_params:{langfuse_public_key:"text",langfuse_secret_key:"password",langfuse_host:"text"},description:"Langfuse v2 Logging Integration"},{id:"langfuse_otel",displayName:"Langfuse OTEL",logo:`${t}langfuse.png`,supports_key_team_logging:!0,dynamic_params:{langfuse_public_key:"text",langfuse_secret_key:"password",langfuse_host:"text"},description:"Langfuse v3 OTEL Logging Integration"},{id:"langsmith",displayName:"LangSmith",logo:`${t}langsmith.png`,supports_key_team_logging:!0,dynamic_params:{langsmith_api_key:"password",langsmith_project:"text",langsmith_base_url:"text",langsmith_sampling_rate:"number"},description:"Langsmith Logging Integration"},{id:"openmeter",displayName:"OpenMeter",logo:`${t}openmeter.png`,supports_key_team_logging:!1,dynamic_params:{openmeter_api_key:"password",openmeter_base_url:"text"},description:"OpenMeter Logging Integration"},{id:"otel",displayName:"Open Telemetry",logo:`${t}otel.png`,supports_key_team_logging:!1,dynamic_params:{otel_endpoint:"text",otel_headers:"text"},description:"OpenTelemetry Logging Integration"},{id:"s3",displayName:"S3",logo:`${t}aws.svg`,supports_key_team_logging:!1,dynamic_params:{s3_bucket_name:"text",aws_access_key_id:"password",aws_secret_access_key:"password",aws_region:"text"},description:"S3 Bucket (AWS) Logging Integration"},{id:"SQS",displayName:"SQS",logo:`${t}aws.svg`,supports_key_team_logging:!1,dynamic_params:{sqs_queue_url:"text",aws_access_key_id:"password",aws_secret_access_key:"password",aws_region:"text"},description:"SQS Queue (AWS) Logging Integration"}],l=s.reduce((e,t)=>(e[t.displayName]=t,e),{}),a=s.reduce((e,t)=>(e[t.displayName]=t.id,e),{}),r=s.reduce((e,t)=>(e[t.id]=t.displayName,e),{});e.s(["callbackInfo",0,l,"callback_map",0,a,"mapDisplayToInternalNames",0,e=>e.map(e=>a[e]||e),"mapInternalToDisplayNames",0,e=>e.map(e=>r[e]||e),"reverse_callback_map",0,r])},9314,e=>{"use strict";var t=e.i(843476),s=e.i(199133),l=e.i(981339),a=e.i(645526),r=e.i(599724),i=e.i(263147);e.s(["default",0,({value:e,onChange:n,placeholder:o="Select access groups",disabled:d=!1,style:c,className:u,showLabel:m=!1,labelText:p="Access Group",allowClear:g=!0})=>{let{data:h,isLoading:x,isError:y}=(0,i.useAccessGroups)();if(x)return(0,t.jsxs)("div",{children:[m&&(0,t.jsxs)(r.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,t.jsx)(a.TeamOutlined,{className:"mr-2"})," ",p]}),(0,t.jsx)(l.Skeleton.Input,{active:!0,block:!0,style:{height:32,...c}})]});let f=(h??[]).map(e=>({label:(0,t.jsxs)("span",{children:[(0,t.jsx)("span",{className:"font-medium",children:e.access_group_name})," ",(0,t.jsxs)("span",{className:"text-gray-400 text-xs",children:["(",e.access_group_id,")"]})]}),value:e.access_group_id,selectedLabel:e.access_group_name,searchText:`${e.access_group_name} ${e.access_group_id}`}));return(0,t.jsxs)("div",{children:[m&&(0,t.jsxs)(r.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,t.jsx)(a.TeamOutlined,{className:"mr-2"})," ",p]}),(0,t.jsx)(s.Select,{mode:"multiple",value:e,placeholder:o,onChange:n,disabled:d,allowClear:g,showSearch:!0,style:{width:"100%",...c},className:`rounded-md ${u??""}`,notFoundContent:y?(0,t.jsx)("span",{className:"text-red-500",children:"Failed to load access groups"}):"No access groups found",filterOption:(e,t)=>(f.find(e=>e.value===t?.value)?.searchText??"").toLowerCase().includes(e.toLowerCase()),optionLabelProp:"selectedLabel",options:f.map(e=>({label:e.label,value:e.value,selectedLabel:e.selectedLabel}))})]})}])},392110,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(199133),a=e.i(592968),r=e.i(312361),i=e.i(790848),n=e.i(536916),o=e.i(827252),d=e.i(779241);let{Option:c}=l.Select;e.s(["default",0,({form:e,autoRotationEnabled:u,onAutoRotationChange:m,rotationInterval:p,onRotationIntervalChange:g,isCreateMode:h=!1,neverExpire:x=!1,onNeverExpireChange:y})=>{let f=p&&!["7d","30d","90d","180d","365d"].includes(p),[b,_]=(0,s.useState)(f),[j,v]=(0,s.useState)(f?p:""),[w,N]=(0,s.useState)(e?.getFieldValue?.("duration")||"");return(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Key Expiry Settings"}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,t.jsx)("span",{children:"Expire Key"}),(0,t.jsx)(a.Tooltip,{title:"Set when this key should expire. Format: 30s (seconds), 30m (minutes), 30h (hours), 30d (days). Leave empty to keep the current expiry unchanged.",children:(0,t.jsx)(o.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})}),!h&&y&&(0,t.jsx)(n.Checkbox,{checked:x,onChange:t=>{let s=t.target.checked;y(s),s&&(N(""),e&&"function"==typeof e.setFieldValue?e.setFieldValue("duration",""):e&&"function"==typeof e.setFieldsValue&&e.setFieldsValue({duration:""}))},className:"ml-2 text-sm font-normal text-gray-600",children:"Never Expire"})]}),(0,t.jsx)(d.TextInput,{name:"duration",placeholder:h?"e.g., 30d or leave empty to never expire":"e.g., 30d",className:"w-full",value:w,onValueChange:t=>{N(t),e&&"function"==typeof e.setFieldValue?e.setFieldValue("duration",t):e&&"function"==typeof e.setFieldsValue&&e.setFieldsValue({duration:t})},disabled:!h&&x})]})]}),(0,t.jsx)(r.Divider,{}),(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Auto-Rotation Settings"}),(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,t.jsx)("span",{children:"Enable Auto-Rotation"}),(0,t.jsx)(a.Tooltip,{title:"Key will automatically regenerate at the specified interval for enhanced security.",children:(0,t.jsx)(o.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})})]}),(0,t.jsx)(i.Switch,{checked:u,onChange:m,size:"default",className:u?"":"bg-gray-400"})]}),u&&(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,t.jsx)("span",{children:"Rotation Interval"}),(0,t.jsx)(a.Tooltip,{title:"How often the key should be automatically rotated. Choose the interval that best fits your security requirements.",children:(0,t.jsx)(o.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)(l.Select,{value:b?"custom":p,onChange:e=>{"custom"===e?_(!0):(_(!1),v(""),g(e))},className:"w-full",placeholder:"Select interval",children:[(0,t.jsx)(c,{value:"7d",children:"7 days"}),(0,t.jsx)(c,{value:"30d",children:"30 days"}),(0,t.jsx)(c,{value:"90d",children:"90 days"}),(0,t.jsx)(c,{value:"180d",children:"180 days"}),(0,t.jsx)(c,{value:"365d",children:"365 days"}),(0,t.jsx)(c,{value:"custom",children:"Custom interval"})]}),b&&(0,t.jsxs)("div",{className:"space-y-1",children:[(0,t.jsx)(d.TextInput,{value:j,onChange:e=>{let t=e.target.value;v(t),g(t)},placeholder:"e.g., 1s, 5m, 2h, 14d"}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Supported formats: seconds (s), minutes (m), hours (h), days (d)"})]})]})]})]}),u&&(0,t.jsx)("div",{className:"bg-blue-50 p-3 rounded-md text-sm text-blue-700",children:"When rotation occurs, you'll receive a notification with the new key. The old key will be deactivated after a brief grace period."})]})]})}])},533882,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(250980),a=e.i(797672),r=e.i(68155),i=e.i(304967),n=e.i(629569),o=e.i(599724),d=e.i(269200),c=e.i(427612),u=e.i(64848),m=e.i(942232),p=e.i(496020),g=e.i(977572),h=e.i(992619),x=e.i(727749);e.s(["default",0,({accessToken:e,initialModelAliases:y={},onAliasUpdate:f,showExampleConfig:b=!0})=>{let[_,j]=(0,s.useState)([]),[v,w]=(0,s.useState)({aliasName:"",targetModel:""}),[N,k]=(0,s.useState)(null);(0,s.useEffect)(()=>{j(Object.entries(y).map(([e,t],s)=>({id:`${s}-${e}`,aliasName:e,targetModel:t})))},[y]);let S=()=>{if(!N)return;if(!N.aliasName||!N.targetModel)return void x.default.fromBackend("Please provide both alias name and target model");if(_.some(e=>e.id!==N.id&&e.aliasName===N.aliasName))return void x.default.fromBackend("An alias with this name already exists");let e=_.map(e=>e.id===N.id?N:e);j(e),k(null);let t={};e.forEach(e=>{t[e.aliasName]=e.targetModel}),f&&f(t),x.default.success("Alias updated successfully")},C=()=>{k(null)},T=_.reduce((e,t)=>(e[t.aliasName]=t.targetModel,e),{});return(0,t.jsxs)("div",{className:"mt-4",children:[(0,t.jsxs)("div",{className:"mb-6",children:[(0,t.jsx)(o.Text,{className:"text-sm font-medium text-gray-700 mb-2",children:"Add New Alias"}),(0,t.jsxs)("div",{className:"grid grid-cols-3 gap-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Alias Name"}),(0,t.jsx)("input",{type:"text",value:v.aliasName,onChange:e=>w({...v,aliasName:e.target.value}),placeholder:"e.g., gpt-4o",className:"w-full px-3 py-2 border border-gray-300 rounded-md text-sm"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Target Model"}),(0,t.jsx)(h.default,{accessToken:e,value:v.targetModel,placeholder:"Select target model",onChange:e=>w({...v,targetModel:e}),showLabel:!1})]}),(0,t.jsx)("div",{className:"flex items-end",children:(0,t.jsxs)("button",{onClick:()=>{if(!v.aliasName||!v.targetModel)return void x.default.fromBackend("Please provide both alias name and target model");if(_.some(e=>e.aliasName===v.aliasName))return void x.default.fromBackend("An alias with this name already exists");let e=[..._,{id:`${Date.now()}-${v.aliasName}`,aliasName:v.aliasName,targetModel:v.targetModel}];j(e),w({aliasName:"",targetModel:""});let t={};e.forEach(e=>{t[e.aliasName]=e.targetModel}),f&&f(t),x.default.success("Alias added successfully")},disabled:!v.aliasName||!v.targetModel,className:`flex items-center px-4 py-2 rounded-md text-sm ${!v.aliasName||!v.targetModel?"bg-gray-300 text-gray-500 cursor-not-allowed":"bg-green-600 text-white hover:bg-green-700"}`,children:[(0,t.jsx)(l.PlusCircleIcon,{className:"w-4 h-4 mr-1"}),"Add Alias"]})})]})]}),(0,t.jsx)(o.Text,{className:"text-sm font-medium text-gray-700 mb-2",children:"Manage Existing Aliases"}),(0,t.jsx)("div",{className:"rounded-lg custom-border relative mb-6",children:(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsxs)(d.Table,{className:"[&_td]:py-0.5 [&_th]:py-1",children:[(0,t.jsx)(c.TableHead,{children:(0,t.jsxs)(p.TableRow,{children:[(0,t.jsx)(u.TableHeaderCell,{className:"py-1 h-8",children:"Alias Name"}),(0,t.jsx)(u.TableHeaderCell,{className:"py-1 h-8",children:"Target Model"}),(0,t.jsx)(u.TableHeaderCell,{className:"py-1 h-8",children:"Actions"})]})}),(0,t.jsxs)(m.TableBody,{children:[_.map(s=>(0,t.jsx)(p.TableRow,{className:"h-8",children:N&&N.id===s.id?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(g.TableCell,{className:"py-0.5",children:(0,t.jsx)("input",{type:"text",value:N.aliasName,onChange:e=>k({...N,aliasName:e.target.value}),className:"w-full px-2 py-1 border border-gray-300 rounded-md text-sm"})}),(0,t.jsx)(g.TableCell,{className:"py-0.5",children:(0,t.jsx)(h.default,{accessToken:e,value:N.targetModel,onChange:e=>k({...N,targetModel:e}),showLabel:!1,style:{height:"32px"}})}),(0,t.jsx)(g.TableCell,{className:"py-0.5 whitespace-nowrap",children:(0,t.jsxs)("div",{className:"flex space-x-2",children:[(0,t.jsx)("button",{onClick:S,className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded-sm hover:bg-blue-100",children:"Save"}),(0,t.jsx)("button",{onClick:C,className:"text-xs bg-gray-50 text-gray-600 px-2 py-1 rounded-sm hover:bg-gray-100",children:"Cancel"})]})})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(g.TableCell,{className:"py-0.5 text-sm text-gray-900",children:s.aliasName}),(0,t.jsx)(g.TableCell,{className:"py-0.5 text-sm text-gray-500",children:s.targetModel}),(0,t.jsx)(g.TableCell,{className:"py-0.5 whitespace-nowrap",children:(0,t.jsxs)("div",{className:"flex space-x-2",children:[(0,t.jsx)("button",{onClick:()=>{k({...s})},className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded-sm hover:bg-blue-100",children:(0,t.jsx)(a.PencilIcon,{className:"w-3 h-3"})}),(0,t.jsx)("button",{onClick:()=>{var e;let t,l;return e=s.id,j(t=_.filter(t=>t.id!==e)),l={},void(t.forEach(e=>{l[e.aliasName]=e.targetModel}),f&&f(l),x.default.success("Alias deleted successfully"))},className:"text-xs bg-red-50 text-red-600 px-2 py-1 rounded-sm hover:bg-red-100",children:(0,t.jsx)(r.TrashIcon,{className:"w-3 h-3"})})]})})]})},s.id)),0===_.length&&(0,t.jsx)(p.TableRow,{children:(0,t.jsx)(g.TableCell,{colSpan:3,className:"py-0.5 text-sm text-gray-500 text-center",children:"No aliases added yet. Add a new alias above."})})]})]})})}),b&&(0,t.jsxs)(i.Card,{children:[(0,t.jsx)(n.Title,{className:"mb-4",children:"Configuration Example"}),(0,t.jsx)(o.Text,{className:"text-gray-600 mb-4",children:"Here's how your current aliases would look in the config:"}),(0,t.jsx)("div",{className:"bg-gray-100 rounded-lg p-4 font-mono text-sm",children:(0,t.jsxs)("div",{className:"text-gray-700",children:["model_aliases:",0===Object.keys(T).length?(0,t.jsxs)("span",{className:"text-gray-500",children:[(0,t.jsx)("br",{}),"  # No aliases configured yet"]}):Object.entries(T).map(([e,s])=>(0,t.jsxs)("span",{children:[(0,t.jsx)("br",{}),'  "',e,'": "',s,'"']},e))]})})]})]})}])},844565,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(199133),a=e.i(602869);e.s(["default",0,({onChange:e,value:r,className:i,accessToken:n,placeholder:o="Select pass through routes",disabled:d=!1,teamId:c})=>{let[u,m]=(0,s.useState)([]),[p,g]=(0,s.useState)(!1);return(0,s.useEffect)(()=>{(async()=>{if(n){g(!0);try{let e=await (0,a.getPassThroughEndpointsCall)(n,c);if(e.endpoints){let t=e.endpoints.flatMap(e=>{let t=e.path,s=e.methods;return s&&s.length>0?s.map(e=>({label:`${e} ${t}`,value:t})):[{label:t,value:t}]});m(t)}}catch(e){console.error("Error fetching pass through routes:",e)}finally{g(!1)}}})()},[n,c]),(0,t.jsx)(l.Select,{mode:"tags",placeholder:o,onChange:e,value:r,loading:p,className:i,allowClear:!0,options:u,optionFilterProp:"label",showSearch:!0,style:{width:"100%"},disabled:d})}])},810757,477386,e=>{"use strict";var t=e.i(271645);let s=t.forwardRef(function(e,s){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:s},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"}),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"}))});e.s(["CogIcon",0,s],810757);let l=t.forwardRef(function(e,s){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:s},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"}))});e.s(["BanIcon",0,l],477386)},266484,e=>{"use strict";var t=e.i(843476),s=e.i(199133),l=e.i(592968),a=e.i(312361),r=e.i(827252),i=e.i(994388),n=e.i(304967),o=e.i(779241),d=e.i(988297),c=e.i(68155),u=e.i(810757),m=e.i(477386),p=e.i(557662),g=e.i(555987),h=e.i(435451);let{Option:x}=s.Select;e.s(["default",0,({value:e=[],onChange:y,disabledCallbacks:f=[],onDisabledCallbacksChange:b})=>{let _=Object.entries(p.callbackInfo).filter(([e,t])=>t.supports_key_team_logging).map(([e,t])=>e),j=Object.keys(p.callbackInfo),v=e=>{y?.(e)},w=(t,s,l)=>{let a=[...e];if("callback_name"===s){let e=p.callback_map[l]||l;a[t]={...a[t],[s]:e,callback_vars:{}}}else a[t]={...a[t],[s]:l};v(a)},N=(t,s,l)=>{let a=[...e];a[t]={...a[t],callback_vars:{...a[t].callback_vars,[s]:l}},v(a)};return(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)(m.BanIcon,{className:"w-5 h-5 text-red-500"}),(0,t.jsx)("span",{className:"text-base font-semibold text-gray-800",children:"Disabled Callbacks"}),(0,t.jsx)(l.Tooltip,{title:"Select callbacks to disable for this key. Disabled callbacks will not receive any logging data.",children:(0,t.jsx)(r.InfoCircleOutlined,{className:"text-gray-400 cursor-help"})})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Disabled Callbacks"}),(0,t.jsx)(s.Select,{mode:"multiple",placeholder:"Select callbacks to disable",value:f,onChange:e=>{let t=(0,p.mapDisplayToInternalNames)(e);b?.(t)},style:{width:"100%"},optionLabelProp:"label",children:j.map(e=>{let s=(0,g.resolveLogoSrc)(p.callbackInfo[e]?.logo),a=p.callbackInfo[e]?.description;return(0,t.jsx)(x,{value:e,label:e,children:(0,t.jsx)(l.Tooltip,{title:a,placement:"right",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[s&&(0,t.jsx)("img",{src:s,alt:e,className:"w-4 h-4 object-contain",onError:t=>{let s=t.target,l=s.parentElement;if(l){let t=document.createElement("div");t.className="w-4 h-4 rounded-full bg-gray-200 flex items-center justify-center text-xs",t.textContent=e.charAt(0),l.replaceChild(t,s)}}}),(0,t.jsx)("span",{children:e})]})})},e)})}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Select callbacks that should be disabled for this key. These callbacks will not receive any logging data."})]})]}),(0,t.jsx)(a.Divider,{}),(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)(u.CogIcon,{className:"w-5 h-5 text-blue-500"}),(0,t.jsx)("span",{className:"text-base font-semibold text-gray-800",children:"Logging Integrations"}),(0,t.jsx)(l.Tooltip,{title:"Configure callback logging integrations for this team.",children:(0,t.jsx)(r.InfoCircleOutlined,{className:"text-gray-400 cursor-help"})})]}),(0,t.jsx)(i.Button,{variant:"secondary",onClick:()=>{v([...e,{callback_name:"",callback_type:"success",callback_vars:{}}])},icon:d.PlusIcon,size:"sm",className:"hover:border-blue-400 hover:text-blue-500",type:"button",children:"Add Integration"})]}),(0,t.jsx)("div",{className:"space-y-4",children:e.map((a,d)=>{let u=a.callback_name?Object.entries(p.callback_map).find(([e,t])=>t===a.callback_name)?.[0]:void 0,m=u?(0,g.resolveLogoSrc)(p.callbackInfo[u]?.logo):null;return(0,t.jsxs)(n.Card,{className:"border border-gray-200 shadow-xs hover:shadow-md transition-shadow duration-200",decoration:"top",decorationColor:"blue",children:[(0,t.jsxs)("div",{className:"flex justify-between items-start mb-4",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[m&&(0,t.jsx)("img",{src:m,alt:u,className:"w-5 h-5 object-contain"}),(0,t.jsxs)("span",{className:"text-sm font-medium",children:[u||"New Integration"," Configuration"]})]}),(0,t.jsx)(i.Button,{variant:"light",onClick:()=>{v(e.filter((e,t)=>t!==d))},icon:c.TrashIcon,size:"xs",color:"red",className:"hover:bg-red-50",type:"button",children:"Remove"})]}),(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Integration Type"}),(0,t.jsx)(s.Select,{value:u,placeholder:"Select integration",onChange:e=>w(d,"callback_name",e),className:"w-full",optionLabelProp:"label",children:_.map(e=>{let s=(0,g.resolveLogoSrc)(p.callbackInfo[e]?.logo),a=p.callbackInfo[e]?.description;return(0,t.jsx)(x,{value:e,label:e,children:(0,t.jsx)(l.Tooltip,{title:a,placement:"right",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[s&&(0,t.jsx)("img",{src:s,alt:e,className:"w-4 h-4 object-contain",onError:t=>{let s=t.target,l=s.parentElement;if(l){let t=document.createElement("div");t.className="w-4 h-4 rounded-full bg-gray-200 flex items-center justify-center text-xs",t.textContent=e.charAt(0),l.replaceChild(t,s)}}}),(0,t.jsx)("span",{children:e})]})})},e)})})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Event Type"}),(0,t.jsxs)(s.Select,{value:a.callback_type,onChange:e=>w(d,"callback_type",e),className:"w-full",children:[(0,t.jsx)(x,{value:"success",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("div",{className:"w-2 h-2 bg-green-500 rounded-full"}),(0,t.jsx)("span",{children:"Success Only"})]})}),(0,t.jsx)(x,{value:"failure",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("div",{className:"w-2 h-2 bg-red-500 rounded-full"}),(0,t.jsx)("span",{children:"Failure Only"})]})}),(0,t.jsx)(x,{value:"success_and_failure",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("div",{className:"w-2 h-2 bg-blue-500 rounded-full"}),(0,t.jsx)("span",{children:"Success & Failure"})]})})]})]})]}),((e,s)=>{if(!e.callback_name)return null;let a=Object.entries(p.callback_map).find(([t,s])=>s===e.callback_name)?.[0];if(!a)return null;let i=p.callbackInfo[a]?.dynamic_params||{};return 0===Object.keys(i).length?null:(0,t.jsxs)("div",{className:"mt-6 pt-4 border-t border-gray-100",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2 mb-4",children:[(0,t.jsx)("div",{className:"w-3 h-3 bg-blue-100 rounded-full flex items-center justify-center",children:(0,t.jsx)("div",{className:"w-1.5 h-1.5 bg-blue-500 rounded-full"})}),(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Integration Parameters"})]}),(0,t.jsx)("div",{className:"grid grid-cols-1 gap-4",children:Object.entries(i).map(([a,i])=>(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 capitalize flex items-center space-x-1",children:[(0,t.jsx)("span",{children:a.replace(/_/g," ")}),(0,t.jsx)(l.Tooltip,{title:`Environment variable reference recommended: os.environ/${a.toUpperCase()}`,children:(0,t.jsx)(r.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})}),"password"===i&&(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-medium bg-yellow-100 text-yellow-800",children:"Sensitive"}),"number"===i&&(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-medium bg-yellow-100 text-yellow-800",children:"Number"})]}),"number"===i&&(0,t.jsx)("span",{className:"text-xs text-gray-500",children:"Value must be between 0 and 1"}),"number"===i?(0,t.jsx)(h.default,{step:.01,width:400,placeholder:`os.environ/${a.toUpperCase()}`,value:e.callback_vars[a]||"",onChange:e=>N(s,a,e.target.value)}):(0,t.jsx)(o.TextInput,{type:"password"===i?"password":"text",placeholder:`os.environ/${a.toUpperCase()}`,value:e.callback_vars[a]||"",onChange:e=>N(s,a,e.target.value)})]},a))})]})})(a,d)]})]},d)})}),0===e.length&&(0,t.jsxs)("div",{className:"text-center py-12 text-gray-500 border-2 border-dashed border-gray-200 rounded-lg bg-gray-50/50",children:[(0,t.jsx)(u.CogIcon,{className:"w-12 h-12 text-gray-300 mb-3 mx-auto"}),(0,t.jsx)("div",{className:"text-base font-medium mb-1",children:"No logging integrations configured"}),(0,t.jsx)("div",{className:"text-sm text-gray-400",children:'Click "Add Integration" to configure logging for this team'})]})]})}])},651904,e=>{"use strict";var t=e.i(843476),s=e.i(599724),l=e.i(266484);e.s(["default",0,function({value:e,onChange:a,premiumUser:r=!1,disabledCallbacks:i=[],onDisabledCallbacksChange:n}){return r?(0,t.jsx)(l.default,{value:e,onChange:a,disabledCallbacks:i,onDisabledCallbacksChange:n}):(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex flex-wrap gap-2 mb-3",children:[(0,t.jsx)("div",{className:"inline-flex items-center px-3 py-1.5 rounded-lg bg-green-50 border border-green-200 text-green-800 text-sm font-medium opacity-50",children:"✨ langfuse-logging"}),(0,t.jsx)("div",{className:"inline-flex items-center px-3 py-1.5 rounded-lg bg-green-50 border border-green-200 text-green-800 text-sm font-medium opacity-50",children:"✨ datadog-logging"})]}),(0,t.jsx)("div",{className:"p-3 bg-yellow-50 border border-yellow-200 rounded-lg",children:(0,t.jsxs)(s.Text,{className:"text-sm text-yellow-800",children:["Setting Key/Team logging settings is a LiteLLM Enterprise feature. Global Logging Settings are available for all free users. Get a trial key"," ",(0,t.jsx)("a",{href:"https://www.litellm.ai/#pricing",target:"_blank",rel:"noopener noreferrer",className:"underline",children:"here"}),"."]})})]})}])},939510,e=>{"use strict";var t=e.i(843476),s=e.i(808613),l=e.i(199133),a=e.i(592968),r=e.i(827252);let{Option:i}=l.Select;e.s(["default",0,({type:e,name:n,showDetailedDescriptions:o=!0,className:d="",initialValue:c=null,form:u,onChange:m})=>{let p=e.toUpperCase(),g=e.toLowerCase(),h=`Select 'guaranteed_throughput' to prevent overallocating ${p} limit when the key belongs to a Team with specific ${p} limits.`;return(0,t.jsx)(s.Form.Item,{label:(0,t.jsxs)("span",{children:[p," Rate Limit Type"," ",(0,t.jsx)(a.Tooltip,{title:h,children:(0,t.jsx)(r.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:n,initialValue:c,className:d,children:(0,t.jsx)(l.Select,{defaultValue:o?"default":void 0,placeholder:"Select rate limit type",style:{width:"100%"},optionLabelProp:o?"label":void 0,onChange:e=>{u&&u.setFieldValue(n,e),m&&m(e)},children:o?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i,{value:"best_effort_throughput",label:"Default",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)("div",{style:{fontWeight:500},children:"Default"}),(0,t.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["Best effort throughput - no error if we're overallocating ",g," (Team/Key Limits checked at runtime)."]})]})}),(0,t.jsx)(i,{value:"guaranteed_throughput",label:"Guaranteed throughput",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)("div",{style:{fontWeight:500},children:"Guaranteed throughput"}),(0,t.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["Guaranteed throughput - raise an error if we're overallocating ",g," (also checks model-specific limits)"]})]})}),(0,t.jsx)(i,{value:"dynamic",label:"Dynamic",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)("div",{style:{fontWeight:500},children:"Dynamic"}),(0,t.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["If the key has a set ",p," (e.g. 2 ",p,") and there are no 429 errors, it can dynamically exceed the limit when the model being called is not erroring."]})]})})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i,{value:"best_effort_throughput",children:"Best effort throughput"}),(0,t.jsx)(i,{value:"guaranteed_throughput",children:"Guaranteed throughput"}),(0,t.jsx)(i,{value:"dynamic",children:"Dynamic"})]})})})}])},460285,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(404206),a=e.i(723731),r=e.i(653824),i=e.i(881073),n=e.i(197647),o=e.i(602869),d=e.i(158392),c=e.i(419470),u=e.i(695411);let m=(0,s.forwardRef)(({accessToken:e,value:m,onChange:p,modelData:g},h)=>{let[x,y]=(0,s.useState)({routerSettings:{},selectedStrategy:null,enableTagFiltering:!1}),[f,b]=(0,s.useState)([]),[_,j]=(0,s.useState)([]),[v,w]=(0,s.useState)([]),[N,k]=(0,s.useState)([]),[S,C]=(0,s.useState)({}),[T,I]=(0,s.useState)({}),A=(0,s.useRef)(!1),L=(0,s.useRef)(null);(0,s.useEffect)(()=>{let e=m?.router_settings?JSON.stringify({routing_strategy:m.router_settings.routing_strategy,fallbacks:m.router_settings.fallbacks,enable_tag_filtering:m.router_settings.enable_tag_filtering}):null;if(A.current&&e===L.current){A.current=!1;return}if(A.current&&e!==L.current&&(A.current=!1),e!==L.current)if(L.current=e,m?.router_settings){let e=m.router_settings,{fallbacks:t,...s}=e;y({routerSettings:s,selectedStrategy:e.routing_strategy||null,enableTagFiltering:e.enable_tag_filtering??!1});let l=e.fallbacks||[];b(l),j(l&&0!==l.length?l.map((e,t)=>{let[s,l]=Object.entries(e)[0];return{id:(t+1).toString(),primaryModel:s||null,fallbackModels:l||[]}}):[{id:"1",primaryModel:null,fallbackModels:[]}])}else y({routerSettings:{},selectedStrategy:null,enableTagFiltering:!1}),b([]),j([{id:"1",primaryModel:null,fallbackModels:[]}])},[m]),(0,s.useEffect)(()=>{e&&(0,o.getRouterSettingsCall)(e).then(e=>{if(e.fields){let t={};e.fields.forEach(e=>{t[e.field_name]={ui_field_name:e.ui_field_name,field_description:e.field_description,options:e.options,link:e.link}}),C(t);let s=e.fields.find(e=>"routing_strategy"===e.field_name);s?.options&&k(s.options),e.routing_strategy_descriptions&&I(e.routing_strategy_descriptions)}})},[e]),(0,s.useEffect)(()=>{e&&(async()=>{try{let t=await (0,u.fetchAvailableModels)(e);w(t)}catch(e){console.error("Error fetching model info for fallbacks:",e)}})()},[e]);let F=()=>{let e=new Set(["allowed_fails","cooldown_time","num_retries","timeout","retry_after"]),t=new Set(["model_group_alias","retry_policy"]),s=Object.fromEntries(Object.entries({...x.routerSettings,enable_tag_filtering:x.enableTagFiltering,routing_strategy:x.selectedStrategy,fallbacks:f.length>0?f:null}).map(([s,l])=>{if("routing_strategy_args"!==s&&"routing_strategy"!==s&&"enable_tag_filtering"!==s&&"fallbacks"!==s){let a=document.querySelector(`input[name="${s}"]`);if(a){if(void 0!==a.value&&""!==a.value){let r=((s,l,a)=>{if(null==l)return a;let r=String(l).trim();if(""===r||"null"===r.toLowerCase())return null;if(e.has(s)){let e=Number(r);return Number.isNaN(e)?a:e}if(t.has(s)){if(""===r)return null;try{return JSON.parse(r)}catch{return a}}return"true"===r.toLowerCase()||"false"!==r.toLowerCase()&&r})(s,a.value,l);return[s,r]}return[s,null]}}else if("routing_strategy"===s)return[s,x.selectedStrategy];else if("enable_tag_filtering"===s)return[s,x.enableTagFiltering];else if("fallbacks"===s)return[s,f.length>0?f:null];else if("routing_strategy_args"===s&&"latency-based-routing"===x.selectedStrategy){let e=document.querySelector('input[name="lowest_latency_buffer"]'),t=document.querySelector('input[name="ttl"]'),s={};return e?.value&&(s.lowest_latency_buffer=Number(e.value)),t?.value&&(s.ttl=Number(t.value)),["routing_strategy_args",Object.keys(s).length>0?s:null]}return[s,l]}).filter(e=>null!=e)),l=(e,t=!1)=>null==e||"object"==typeof e&&!Array.isArray(e)&&0===Object.keys(e).length||t&&("number"!=typeof e||Number.isNaN(e))?null:e;return{routing_strategy:l(s.routing_strategy),allowed_fails:l(s.allowed_fails,!0),cooldown_time:l(s.cooldown_time,!0),num_retries:l(s.num_retries,!0),timeout:l(s.timeout,!0),retry_after:l(s.retry_after,!0),fallbacks:f.length>0?f:null,context_window_fallbacks:l(s.context_window_fallbacks),retry_policy:l(s.retry_policy),model_group_alias:l(s.model_group_alias),enable_tag_filtering:x.enableTagFiltering,routing_strategy_args:l(s.routing_strategy_args)}};(0,s.useEffect)(()=>{if(!p)return;let e=setTimeout(()=>{A.current=!0,p({router_settings:F()})},100);return()=>clearTimeout(e)},[x,f]);let M=Array.from(new Set(v.map(e=>e.model_group))).sort();return((0,s.useImperativeHandle)(h,()=>({getValue:()=>({router_settings:F()})})),e)?(0,t.jsx)("div",{className:"w-full",children:(0,t.jsxs)(r.TabGroup,{className:"w-full",children:[(0,t.jsxs)(i.TabList,{variant:"line",defaultValue:"1",className:"px-8 pt-4",children:[(0,t.jsx)(n.Tab,{value:"1",children:"Loadbalancing"}),(0,t.jsx)(n.Tab,{value:"2",children:"Fallbacks"})]}),(0,t.jsxs)(a.TabPanels,{className:"px-8 py-6",children:[(0,t.jsx)(l.TabPanel,{children:(0,t.jsx)(d.default,{value:x,onChange:y,routerFieldsMetadata:S,availableRoutingStrategies:N,routingStrategyDescriptions:T})}),(0,t.jsx)(l.TabPanel,{children:(0,t.jsx)(c.FallbackSelectionForm,{groups:_,onGroupsChange:e=>{j(e),b(e.filter(e=>e.primaryModel&&e.fallbackModels.length>0).map(e=>({[e.primaryModel]:e.fallbackModels})))},availableModels:M,maxGroups:5})})]})]})}):null});m.displayName="RouterSettingsAccordion",e.s(["default",0,m])},363256,e=>{"use strict";var t=e.i(843476),s=e.i(199133);let{Text:l}=e.i(898586).Typography;e.s(["default",0,({organizations:e,value:a,onChange:r,disabled:i,loading:n,style:o})=>(0,t.jsx)(s.Select,{showSearch:!0,placeholder:"All Organizations",value:a,onChange:r,disabled:i,loading:n,allowClear:!0,style:{minWidth:280,...o},filterOption:(t,s)=>{if(!s)return!1;let l=e?.find(e=>e.organization_id===s.key);if(!l)return!1;let a=t.toLowerCase().trim(),r=(l.organization_alias||"").toLowerCase(),i=(l.organization_id||"").toLowerCase();return r.includes(a)||i.includes(a)},children:e?.map(e=>(0,t.jsxs)(s.Select.Option,{value:e.organization_id,children:[(0,t.jsx)("span",{className:"font-medium",children:e.organization_alias})," ",(0,t.jsxs)(l,{type:"secondary",children:["(",e.organization_id,")"]})]},e.organization_id))})])},575260,e=>{"use strict";var t=e.i(843476),s=e.i(199133),l=e.i(482725),a=e.i(56456);e.s(["default",0,({projects:e,value:r,onChange:i,disabled:n,loading:o,teamId:d})=>{let c=d?e?.filter(e=>e.team_id===d):e;return(0,t.jsx)(s.Select,{showSearch:!0,placeholder:"Search or select a project",value:r,onChange:i,disabled:n,loading:o,allowClear:!0,notFoundContent:o?(0,t.jsx)(l.Spin,{indicator:(0,t.jsx)(a.LoadingOutlined,{spin:!0}),size:"small"}):void 0,filterOption:(e,t)=>{if(!t)return!1;let s=c?.find(e=>e.project_id===t.key);if(!s)return!1;let l=e.toLowerCase().trim(),a=(s.project_alias||"").toLowerCase(),r=(s.project_id||"").toLowerCase();return a.includes(l)||r.includes(l)},optionFilterProp:"children",children:!o&&c?.map(e=>(0,t.jsxs)(s.Select.Option,{value:e.project_id,children:[(0,t.jsx)("span",{className:"font-medium",children:e.project_alias||e.project_id})," ",(0,t.jsxs)("span",{className:"text-gray-500",children:["(",e.project_id,")"]})]},e.project_id))})}])},128233,319312,e=>{"use strict";var t=e.i(843476),s=e.i(464571),l=e.i(199133),a=e.i(592968),r=e.i(425063),i=e.i(107233),n=e.i(37727),o=e.i(271645);e.s(["BudgetFallbacksEditor",0,function({value:e,onChange:d,availableModels:c}){let[u,m]=(0,o.useState)(()=>{let t;return 0===(t=Object.keys(e)).length?[]:t.map((t,s)=>({id:String(s+1),primaryModel:t,fallbackModels:e[t]}))}),p=e=>{m(e),d(Object.fromEntries(e.filter(e=>null!==e.primaryModel&&e.fallbackModels.length>0).map(e=>[e.primaryModel,e.fallbackModels])))},g=()=>{p([...u,{id:Date.now().toString(),primaryModel:null,fallbackModels:[]}])},h=(e,t)=>{p(u.map(s=>s.id===e?{...s,...t}:s))},x=new Set(u.map(e=>e.primaryModel).filter(Boolean));return 0===u.length?(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-xs text-gray-500 mb-2",children:"When a model exceeds its per-model budget, requests automatically reroute to fallback models"}),(0,t.jsx)(s.Button,{size:"small",onClick:g,icon:(0,t.jsx)(i.Plus,{className:"w-3 h-3"}),children:"Add Budget Fallback"})]}):(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"When a model exceeds its per-model budget, requests automatically reroute to fallback models"}),u.map(e=>{let s=c.filter(t=>t===e.primaryModel||!x.has(t)),i=c.filter(t=>t!==e.primaryModel);return(0,t.jsxs)("div",{className:"relative rounded-lg border border-gray-200 bg-gray-50 p-4",children:[(0,t.jsx)("button",{type:"button",onClick:()=>{var t;return t=e.id,void p(u.filter(e=>e.id!==t))},className:"absolute top-2 right-2 text-gray-400 hover:text-red-500 transition-colors p-1",children:(0,t.jsx)(n.X,{className:"w-4 h-4"})}),(0,t.jsxs)("div",{className:"mb-3",children:[(0,t.jsx)("label",{className:"block text-xs font-medium text-gray-600 mb-1",children:"Primary Model"}),(0,t.jsx)(l.Select,{className:"w-full",placeholder:"Select model",value:e.primaryModel,onChange:t=>{let s=e.fallbackModels.filter(e=>e!==t);h(e.id,{primaryModel:t,fallbackModels:s})},showSearch:!0,filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase()),options:s.map(e=>({label:e,value:e})),getPopupContainer:e=>e.parentElement||document.body})]}),(0,t.jsx)("div",{className:"flex items-center justify-center -my-1 mb-2",children:(0,t.jsxs)("div",{className:"bg-amber-50 text-amber-600 px-3 py-0.5 rounded-full text-[10px] font-bold border border-amber-100 flex items-center gap-1",children:[(0,t.jsx)(r.ArrowDown,{className:"w-3 h-3"}),"IF BUDGET EXCEEDED, TRY"]})}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs font-medium text-gray-600 mb-1",children:"Fallback Models"}),(0,t.jsx)(l.Select,{mode:"multiple",className:"w-full",placeholder:e.primaryModel?"Select fallback models":"Select a primary model first",value:e.fallbackModels,onChange:t=>h(e.id,{fallbackModels:t}),disabled:!e.primaryModel,showSearch:!0,filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase()),options:i.map(e=>({label:e,value:e})),getPopupContainer:e=>e.parentElement||document.body,maxTagCount:"responsive",maxTagPlaceholder:e=>(0,t.jsx)(a.Tooltip,{styles:{root:{pointerEvents:"none"}},title:e.map(({value:e})=>e).join(", "),children:(0,t.jsxs)("span",{children:["+",e.length," more"]})})}),e.fallbackModels.length>1&&(0,t.jsx)("div",{className:"text-[10px] text-gray-400 mt-1 ml-1",children:"Tried in order; first model still within its own budget is used"})]})]},e.id)}),(0,t.jsx)(s.Button,{size:"small",onClick:g,icon:(0,t.jsx)(i.Plus,{className:"w-3 h-3"}),children:"Add Budget Fallback"})]})}],128233);var d=e.i(28651);let c=[{value:"1h",label:"Hourly",resetHint:"Resets every hour"},{value:"24h",label:"Daily",resetHint:"Resets daily at midnight UTC"},{value:"7d",label:"Weekly",resetHint:"Resets every Sunday at midnight UTC"},{value:"30d",label:"Monthly",resetHint:"Resets on the 1st of every month at midnight UTC"}];e.s(["BudgetWindowsEditor",0,function({value:e,onChange:a}){let r=(t,s,l)=>{a(e.map((e,a)=>a===t?{...e,[s]:l}:e))};return(0,t.jsxs)("div",{children:[e.map((i,n)=>{let o=c.find(e=>e.value===i.budget_duration)?.resetHint;return(0,t.jsxs)("div",{style:{marginBottom:12},children:[(0,t.jsxs)("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[(0,t.jsx)(l.Select,{value:i.budget_duration,onChange:e=>r(n,"budget_duration",e),style:{width:130},options:c.map(e=>({value:e.value,label:e.label}))}),(0,t.jsx)(d.InputNumber,{step:.01,min:0,precision:2,value:i.max_budget??void 0,onChange:e=>r(n,"max_budget",e??null),placeholder:"Max spend ($)",style:{width:160},prefix:"$"}),(0,t.jsx)(s.Button,{type:"text",danger:!0,size:"small",onClick:()=>{a(e.filter((e,t)=>t!==n))},style:{padding:"0 4px"},children:"✕"})]}),o&&(0,t.jsxs)("div",{style:{fontSize:11,color:"#888",marginTop:3,marginLeft:2},children:["↻ ",o]})]},n)}),(0,t.jsx)(s.Button,{size:"small",onClick:t=>{t.preventDefault(),a([...e,{budget_duration:"24h",max_budget:null}])},children:"+ Add Budget Window"})]})}],319312)},390605,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(602869),a=e.i(599724),r=e.i(482725),i=e.i(91739),n=e.i(500727),o=e.i(531516),d=e.i(696609);e.s(["default",0,({accessToken:e,selectedServers:c,toolPermissions:u,onChange:m,disabled:p=!1})=>{let{data:g=[]}=(0,n.useMCPServers)(),[h,x]=(0,s.useState)({}),[y,f]=(0,s.useState)({}),[b,_]=(0,s.useState)({}),[j,v]=(0,s.useState)({}),w=(0,s.useRef)(u);(0,s.useEffect)(()=>{w.current=u},[u]);let N=(0,s.useMemo)(()=>0===c.length?[]:g.filter(e=>c.includes(e.server_id)),[g,c]),k=async(e,t)=>{f(t=>({...t,[e]:!0})),_(t=>({...t,[e]:""}));try{let s=await (0,l.listMCPTools)(t,e);if(s.error)_(t=>({...t,[e]:s.message||"Failed to fetch tools"})),x(t=>({...t,[e]:[]}));else{let t=s.tools||[];x(s=>({...s,[e]:t}));let l=w.current;if(!l[e]&&t.length>0){let s=t.filter(e=>"delete"!==(0,d.classifyToolOp)(e.name,e.description||"")).map(e=>e.name);m({...l,[e]:s})}}}catch(t){console.error(`Error fetching tools for server ${e}:`,t),_(t=>({...t,[e]:"Failed to fetch tools"})),x(t=>({...t,[e]:[]}))}finally{f(t=>({...t,[e]:!1}))}};(0,s.useEffect)(()=>{N.forEach(t=>{h[t.server_id]||y[t.server_id]||k(t.server_id,e)})},[N,e]);let S=(e,t)=>{m({...u,[e]:t})};return 0===c.length?null:(0,t.jsx)("div",{className:"space-y-4",children:N.map(e=>{let s=e.server_name||e.alias||e.server_id,l=h[e.server_id]||[],n=u[e.server_id]||[],d=y[e.server_id],c=b[e.server_id],g=j[e.server_id]??"crud";return(0,t.jsxs)("div",{className:"border rounded-lg bg-gray-50",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between p-4 border-b bg-white rounded-t-lg",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(a.Text,{className:"font-semibold text-gray-900",children:s}),e.description&&(0,t.jsx)(a.Text,{className:"text-sm text-gray-500",children:e.description})]}),(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[!p&&l.length>0&&(0,t.jsx)(i.Radio.Group,{value:g,onChange:t=>v(s=>({...s,[e.server_id]:t.target.value})),size:"small",optionType:"button",buttonStyle:"solid",options:[{label:"Risk Groups",value:"crud"},{label:"Flat List",value:"flat"}]}),!p&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("button",{type:"button",className:"text-sm text-blue-600 hover:text-blue-700 font-medium",onClick:()=>{var t;let s;return s=h[t=e.server_id]||[],void m({...u,[t]:s.map(e=>e.name)})},disabled:d,children:"Select All"}),(0,t.jsx)("button",{type:"button",className:"text-sm text-blue-600 hover:text-blue-700 font-medium",onClick:()=>{var t;return t=e.server_id,void m({...u,[t]:[]})},disabled:d,children:"Deselect All"})]})]})]}),(0,t.jsxs)("div",{className:"p-4",children:[d&&(0,t.jsxs)("div",{className:"flex items-center justify-center py-8",children:[(0,t.jsx)(r.Spin,{size:"large"}),(0,t.jsx)(a.Text,{className:"ml-3 text-gray-500",children:"Loading tools..."})]}),c&&!d&&(0,t.jsxs)("div",{className:"p-4 bg-red-50 border border-red-200 rounded-lg text-center",children:[(0,t.jsx)(a.Text,{className:"text-red-600 font-medium",children:"Unable to load tools"}),(0,t.jsx)(a.Text,{className:"text-sm text-red-500 mt-1",children:c})]}),!d&&!c&&l.length>0&&"crud"===g&&(0,t.jsx)(o.default,{tools:l,value:u[e.server_id]?n:void 0,onChange:t=>S(e.server_id,t),readOnly:p}),!d&&!c&&l.length>0&&"flat"===g&&(0,t.jsx)("div",{className:"space-y-2",children:l.map(s=>{let l=n.includes(s.name);return(0,t.jsxs)("div",{className:"flex items-start gap-2",children:[(0,t.jsx)("input",{type:"checkbox",checked:l,onChange:()=>{if(p)return;let t=l?n.filter(e=>e!==s.name):[...n,s.name];S(e.server_id,t)},disabled:p,className:"mt-0.5"}),(0,t.jsx)("div",{className:"flex-1 min-w-0",children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(a.Text,{className:"font-medium text-gray-900",children:s.name}),(0,t.jsxs)(a.Text,{className:"text-sm text-gray-500",children:["- ",s.description||"No description"]})]})})]},s.name)})}),!d&&!c&&0===l.length&&(0,t.jsx)("div",{className:"text-center py-6",children:(0,t.jsx)(a.Text,{className:"text-gray-500",children:"No tools available"})})]})]},e.server_id)})})}])},364769,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(237016),a=e.i(464571),r=e.i(888259);e.s(["default",0,({apiKey:e})=>{let[i,n]=(0,s.useState)(!1);return(0,t.jsxs)("div",{children:[(0,t.jsxs)("p",{className:"mb-2",children:["Please save this secret key somewhere safe and accessible. For security reasons,"," ",(0,t.jsx)("b",{children:"you will not be able to view it again"})," through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]}),(0,t.jsx)("p",{className:"text-sm text-gray-600 mt-3 mb-1",children:"Virtual Key:"}),(0,t.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,t.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal",margin:0},children:e})}),(0,t.jsx)(l.CopyToClipboard,{text:e,onCopy:()=>{n(!0),r.default.success("Key copied to clipboard"),setTimeout(()=>n(!1),2e3)},children:(0,t.jsx)(a.Button,{type:"primary",style:{marginTop:12},children:i?"Copied!":"Copy Virtual Key"})})]})}])},702597,e=>{"use strict";var t=e.i(843476),s=e.i(207082),l=e.i(109799),a=e.i(510674),r=e.i(109034),i=e.i(292639),n=e.i(135214),o=e.i(500330),d=e.i(827252),c=e.i(912598),u=e.i(677667),m=e.i(130643),p=e.i(898667),g=e.i(994388),h=e.i(309426),x=e.i(350967),y=e.i(599724),f=e.i(779241),b=e.i(629569),_=e.i(464571),j=e.i(808613),v=e.i(311451),w=e.i(212931),N=e.i(91739),k=e.i(199133),S=e.i(790848),C=e.i(262218),T=e.i(592968),I=e.i(898586),A=e.i(374009),L=e.i(271645),F=e.i(708347),M=e.i(552130),O=e.i(557662),E=e.i(9314),P=e.i(860585),B=e.i(82946),$=e.i(392110),R=e.i(533882),D=e.i(844565),V=e.i(651904),z=e.i(939510),U=e.i(460285),G=e.i(663435),K=e.i(363256),q=e.i(575260),W=e.i(371455),H=e.i(128233),Q=e.i(319312),J=e.i(355619),Y=e.i(75921),X=e.i(234713),Z=e.i(390605),ee=e.i(727749),et=e.i(602869),es=e.i(364769),el=e.i(435451),ea=e.i(916940);let{Option:er}=k.Select,ei=async(e,t,s,l)=>{try{if(null===e||null===t)return[];if(null!==s)return(await (0,et.modelAvailableCall)(s,e,t,!0,l,!0)).data.map(e=>e.id);return[]}catch(e){return console.error("Error fetching user models:",e),[]}},en=async(e,t,s,l)=>{try{if(null===e||null===t)return;if(null!==s){let a=(await (0,et.modelAvailableCall)(s,e,t)).data.map(e=>e.id);l(a)}}catch(e){console.error("Error fetching user models:",e)}};e.s(["default",0,({team:e,teams:eo,data:ed,addKey:ec,autoOpenCreate:eu,prefillData:em})=>{let{accessToken:ep,userId:eg,userRole:eh,premiumUser:ex}=(0,n.default)(),ey=ex||null!=eh&&F.rolesWithWriteAccess.includes(eh),{data:ef,isLoading:eb}=(0,l.useOrganizations)(),{data:e_,isLoading:ej}=(0,a.useProjects)(),{data:ev}=(0,i.useUISettings)(),{data:ew}=(0,r.useTags)(),eN=!!ev?.values?.enable_projects_ui,ek=!!ev?.values?.disable_custom_api_keys,eS=ew?Object.values(ew).map(e=>({value:e.name,label:e.name})):[],eC=(0,c.useQueryClient)(),[eT]=j.Form.useForm(),[eI,eA]=(0,L.useState)(!1),[eL,eF]=(0,L.useState)(null),[eM,eO]=(0,L.useState)(null),[eE,eP]=(0,L.useState)([]),[eB,e$]=(0,L.useState)([]),[eR,eD]=(0,L.useState)("you"),[eV,ez]=(0,L.useState)(!1),[eU,eG]=(0,L.useState)(null),[eK,eq]=(0,L.useState)([]),[eW,eH]=(0,L.useState)([]),[eQ,eJ]=(0,L.useState)([]),[eY,eX]=(0,L.useState)([]),[eZ,e0]=(0,L.useState)(e),[e1,e2]=(0,L.useState)(null),[e4,e3]=(0,L.useState)(null),[e5,e6]=(0,L.useState)(!1),[e7,e9]=(0,L.useState)(null),[e8,te]=(0,L.useState)({}),[tt,ts]=(0,L.useState)([]),[tl,ta]=(0,L.useState)(!1),[tr,ti]=(0,L.useState)([]),[tn,to]=(0,L.useState)([]),[td,tc]=(0,L.useState)("llm_api"),[tu,tm]=(0,L.useState)({}),[tp,tg]=(0,L.useState)(!1),[th,tx]=(0,L.useState)("30d"),[ty,tf]=(0,L.useState)(null),[tb,t_]=(0,L.useState)([]),[tj,tv]=(0,L.useState)({}),[tw,tN]=(0,L.useState)(0),[tk,tS]=(0,L.useState)(0),[tC,tT]=(0,L.useState)([]),[tI,tA]=(0,L.useState)(null),tL=()=>{eA(!1),eT.resetFields(),eX([]),to([]),tc("llm_api"),tm({}),tg(!1),tx("30d"),tf(null),tS(e=>e+1),tA(null),e2(null),e3(null),t_([]),tv({}),tN(e=>e+1)},tF=()=>{eA(!1),eF(null),e0(null),eT.resetFields(),eX([]),to([]),tc("llm_api"),tm({}),tg(!1),tx("30d"),tf(null),tS(e=>e+1),tA(null),e2(null),e3(null),t_([]),tv({}),tN(e=>e+1)};(0,L.useEffect)(()=>{eg&&eh&&ep&&en(eg,eh,ep,eP)},[ep,eg,eh]),(0,L.useEffect)(()=>{ep&&(0,et.getAgentsList)(ep).then(e=>tT(e?.agents||[])).catch(()=>tT([]))},[ep]),(0,L.useEffect)(()=>{let e=async()=>{try{let e=(await (0,et.getPoliciesList)(ep)).policies.map(e=>e.policy_name);eH(e)}catch(e){console.error("Failed to fetch policies:",e)}},t=async()=>{try{let e=await (0,et.getPromptsList)(ep);eJ(e.prompts.map(e=>e.prompt_id))}catch(e){console.error("Failed to fetch prompts:",e)}};(async()=>{try{let e=(await (0,et.getGuardrailsList)(ep)).guardrails.map(e=>e.guardrail_name);eq(e)}catch(e){console.error("Failed to fetch guardrails:",e)}})(),e(),t()},[ep]),(0,L.useEffect)(()=>{(async()=>{try{if(ep){let e=sessionStorage.getItem("possibleUserRoles");if(e)te(JSON.parse(e));else{let e=await (0,et.getPossibleUserRoles)(ep);sessionStorage.setItem("possibleUserRoles",JSON.stringify(e)),te(e)}}}catch(e){console.error("Error fetching possible user roles:",e)}})()},[ep]),(0,L.useEffect)(()=>{if(eu&&!eV&&eo&&eh&&F.rolesWithWriteAccess.includes(eh)&&(eA(!0),ez(!0),em)){if(em.owned_by&&("another_user"===em.owned_by&&"Admin"!==eh?eD("you"):eD(em.owned_by)),em.team_id){let e=eo?.find(e=>e.team_id===em.team_id)||null;e&&(e0(e),eT.setFieldsValue({team_id:em.team_id}))}em.key_alias&&eT.setFieldsValue({key_alias:em.key_alias}),em.models&&em.models.length>0&&eG(em.models),em.key_type&&(tc(em.key_type),eT.setFieldsValue({key_type:em.key_type}))}},[eu,em,eo,eV,eT,eh]);let tM=eB.includes("no-default-models")&&!eZ,tO=async e=>{try{let t,l=e?.key_alias??"",a=e?.team_id??null;if((ed?.filter(e=>e.team_id===a).map(e=>e.key_alias)??[]).includes(l))throw Error(`Key alias ${l} already exists for team with ID ${a}, please provide another key alias`);if(ee.default.info("Making API Call"),eA(!0),"you"===eR)e.user_id=eg;else if("agent"===eR){if(!tI)return void ee.default.fromBackend("Please select an agent");e.agent_id=tI}let r={};try{r=JSON.parse(e.metadata||"{}")}catch(e){console.error("Error parsing metadata:",e)}if("service_account"===eR&&(r.service_account_id=e.key_alias),eY.length>0&&(r={...r,logging:eY.filter(e=>e.callback_name)}),tn.length>0){let e=(0,O.mapDisplayToInternalNames)(tn);r={...r,litellm_disabled_callbacks:e}}if(tp&&(e.auto_rotate=!0,e.rotation_interval=th),e.duration&&""!==e.duration.trim()||(e.duration=null),e.metadata=JSON.stringify(r),e.disable_global_guardrails||delete e.disable_global_guardrails,e.allowed_vector_store_ids&&e.allowed_vector_store_ids.length>0&&(e.object_permission={vector_stores:e.allowed_vector_store_ids},delete e.allowed_vector_store_ids),e.allowed_mcp_servers_and_groups&&(e.allowed_mcp_servers_and_groups.servers?.length>0||e.allowed_mcp_servers_and_groups.accessGroups?.length>0)){e.object_permission||(e.object_permission={});let{servers:t,accessGroups:s}=e.allowed_mcp_servers_and_groups;t&&t.length>0&&(e.object_permission.mcp_servers=t),s&&s.length>0&&(e.object_permission.mcp_access_groups=s),delete e.allowed_mcp_servers_and_groups}let i=e.mcp_tool_permissions||{};if(Object.keys(i).length>0&&(e.object_permission||(e.object_permission={}),e.object_permission.mcp_tool_permissions=i),delete e.mcp_tool_permissions,e.allowed_mcp_access_groups&&e.allowed_mcp_access_groups.length>0&&(e.object_permission||(e.object_permission={}),e.object_permission.mcp_access_groups=e.allowed_mcp_access_groups,delete e.allowed_mcp_access_groups),e.allowed_agents_and_groups&&(e.allowed_agents_and_groups.agents?.length>0||e.allowed_agents_and_groups.accessGroups?.length>0)){e.object_permission||(e.object_permission={});let{agents:t,accessGroups:s}=e.allowed_agents_and_groups;t&&t.length>0&&(e.object_permission.agents=t),s&&s.length>0&&(e.object_permission.agent_access_groups=s),delete e.allowed_agents_and_groups}Object.keys(tu).length>0&&(e.aliases=JSON.stringify(tu)),ty?.router_settings&&Object.values(ty.router_settings).some(e=>null!=e&&""!==e)&&(e.router_settings=ty.router_settings);let n=tb.filter(e=>e.budget_duration&&null!==e.max_budget&&void 0!==e.max_budget);n.length>0&&(e.budget_limits=n),Object.keys(tj).length>0&&(e.budget_fallbacks=tj),t="service_account"===eR?await (0,et.keyCreateServiceAccountCall)(ep,e):await (0,et.keyCreateCall)(ep,eg,e),ec(t),eC.invalidateQueries({queryKey:s.keyKeys.lists()}),eF(t.key),eO(t.soft_budget),ee.default.success("Virtual Key Created"),eT.resetFields(),t_([]),tv({}),tN(e=>e+1),localStorage.removeItem("userData"+eg)}catch(t){let e=(e=>{let t;if(!(t=!e||"object"!=typeof e||e instanceof Error?String(e):JSON.stringify(e)).includes("/key/generate")&&!t.includes("KeyManagementRoutes.KEY_GENERATE"))return`Error creating the key: ${e}`;let s=t;try{if(!e||"object"!=typeof e||e instanceof Error){let e=t.match(/\{[\s\S]*\}/);if(e){let t=JSON.parse(e[0]),l=t?.error||t;l?.message&&(s=l.message)}}else{let t=e?.error||e;t?.message&&(s=t.message)}}catch(e){}return t.includes("team_member_permission_error")||s.includes("Team member does not have permissions")?"Team member does not have permission to generate key for this team. Ask your proxy admin to configure the team member permission settings.":`Error creating the key: ${e}`})(t);ee.default.fromBackend(e)}};(0,L.useEffect)(()=>{if(e4){let e=e_?.find(e=>e.project_id===e4);e$(e?.models??[]),eT.setFieldValue("models",[]);return}eg&&eh&&ep&&ei(eg,eh,ep,eZ?.team_id??null).then(e=>{e$(Array.from(new Set([...eZ?.models??[],...e])))}),eU||eT.setFieldValue("models",[]),eT.setFieldValue("allowed_mcp_servers_and_groups",{servers:[],accessGroups:[]})},[eZ,e4,ep,eg,eh,eT]),(0,L.useEffect)(()=>{if(!eU||0===eU.length||!eB||0===eB.length)return;let e=eU.filter(e=>eB.includes(e));e.length>0&&eT.setFieldsValue({models:e}),eG(null)},[eU,eB,eT]),(0,L.useEffect)(()=>{if(!e4||!eo)return;let e=e_?.find(e=>e.project_id===e4);if(!e?.team_id||eZ?.team_id===e.team_id)return;let t=eo.find(t=>t.team_id===e.team_id)||null;t&&(e0(t),eT.setFieldValue("team_id",t.team_id))},[eo,e4,e_]);let tE=async e=>{if(!e)return void ts([]);ta(!0);try{let t=new URLSearchParams;if(t.append("user_email",e),null==ep)return;let s=(await (0,et.userFilterUICall)(ep,t)).map(e=>({label:`${e.user_email} (${e.user_id})`,value:e.user_id,user:e}));ts(s)}catch(e){console.error("Error fetching users:",e),ee.default.fromBackend("Failed to search for users")}finally{ta(!1)}},tP=(0,L.useCallback)((0,A.default)(e=>tE(e),300),[ep]);return(0,t.jsxs)("div",{children:[eh&&F.rolesWithWriteAccess.includes(eh)&&(0,t.jsx)(g.Button,{className:"mx-auto",onClick:()=>eA(!0),"data-testid":"create-key-button",children:"+ Create New Key"}),(0,t.jsx)(w.Modal,{open:eI,width:1e3,footer:null,onOk:tL,onCancel:tF,children:(0,t.jsxs)(j.Form,{form:eT,onFinish:tO,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,t.jsxs)("div",{className:"mb-8",children:[(0,t.jsx)(b.Title,{className:"mb-4",children:"Key Ownership"}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Owned By"," ",(0,t.jsx)(T.Tooltip,{title:"Select who will own this Virtual Key",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),className:"mb-4",children:(0,t.jsxs)(N.Radio.Group,{onChange:e=>eD(e.target.value),value:eR,children:[(0,t.jsx)(N.Radio,{value:"you",children:"You"}),(0,t.jsx)(N.Radio,{value:"service_account",children:"Service Account"}),"Admin"===eh&&(0,t.jsx)(N.Radio,{value:"another_user",children:"Another User"}),(0,t.jsxs)(N.Radio,{value:"agent",children:["Agent ",(0,t.jsx)(C.Tag,{color:"purple",children:"New"})]})]})}),"another_user"===eR&&(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["User ID"," ",(0,t.jsx)(T.Tooltip,{title:"The user who will own this key and be responsible for its usage",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"user_id",className:"mt-4",rules:[{required:"another_user"===eR,message:"Please input the user ID of the user you are assigning the key to"}],children:(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{style:{display:"flex",marginBottom:"8px"},children:[(0,t.jsx)(k.Select,{showSearch:!0,placeholder:"Type email to search for users",filterOption:!1,onSearch:e=>{tP(e)},onSelect:(e,t)=>{let s;return s=t.user,void eT.setFieldsValue({user_id:s.user_id})},options:tt,loading:tl,allowClear:!0,style:{width:"100%"},notFoundContent:tl?"Searching...":"No users found"}),(0,t.jsx)(_.Button,{onClick:()=>e6(!0),style:{marginLeft:"8px"},children:"Create User"})]}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Search by email to find users"})]})}),"agent"===eR&&(0,t.jsxs)("div",{className:"mt-4 p-4 bg-purple-50 border border-purple-200 rounded-md",children:[(0,t.jsx)("div",{className:"mb-3",children:(0,t.jsxs)("span",{className:"text-sm font-medium text-gray-700",children:["Select Agent ",(0,t.jsx)("span",{className:"text-red-500",children:"*"})]})}),(0,t.jsx)(k.Select,{showSearch:!0,placeholder:"Select an agent",style:{width:"100%"},value:tI,onChange:e=>tA(e),filterOption:(e,t)=>t?.label?.toLowerCase().includes(e.toLowerCase()),options:tC.map(e=>({label:e.agent_name||e.agent_id,value:e.agent_id}))}),(0,t.jsx)("div",{className:"text-xs text-gray-500 mt-2",children:"This key will be used by the selected agent to make requests to LiteLLM"})]}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Organization"," ",(0,t.jsx)(T.Tooltip,{title:"The organization this key belongs to. Selecting an organization filters the available teams.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"organization_id",className:"mt-4",children:(0,t.jsx)(K.default,{organizations:ef,loading:eb,disabled:"Admin"!==eh,onChange:e=>{e2(e||null),e0(null),e3(null),eT.setFieldValue("team_id",void 0),eT.setFieldValue("project_id",void 0)}})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Team"," ",(0,t.jsx)(T.Tooltip,{title:"The team this key belongs to, which determines available models and budget limits",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"team_id",initialValue:e?e.team_id:null,className:"mt-4",rules:[{required:"service_account"===eR,message:"Please select a team for the service account"}],help:"service_account"===eR?"required":"",children:(0,t.jsx)(G.default,{disabled:null!==e4,organizationId:e1,onTeamSelect:e=>{e0(e),e3(null),eT.setFieldValue("project_id",void 0),e?.organization_id?(e2(e.organization_id),eT.setFieldValue("organization_id",e.organization_id)):e||(e2(null),eT.setFieldValue("organization_id",void 0))}})}),eN&&(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Project"," ",(0,t.jsx)(T.Tooltip,{title:"Assign this key to a project. Selecting a project will lock the team to the project's team.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"project_id",className:"mt-4",children:(0,t.jsx)(q.default,{projects:e_,teamId:eZ?.team_id,loading:ej||!eo,onChange:e=>{if(!e){e3(null),e0(null),eT.setFieldValue("team_id",void 0);return}e3(e)}})})]}),tM&&(0,t.jsx)("div",{className:"mb-8 p-4 bg-blue-50 border border-blue-200 rounded-md",children:(0,t.jsx)(y.Text,{className:"text-blue-800 text-sm",children:"Please select a team to continue configuring your Virtual Key. If you do not see any teams, please contact your Proxy Admin to either provide you with access to models or to add you to a team."})}),!tM&&(0,t.jsxs)("div",{className:"mb-8",children:[(0,t.jsx)(b.Title,{className:"mb-4",children:"Key Details"}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["you"===eR||"another_user"===eR?"Key Name":"Service Account ID"," ",(0,t.jsx)(T.Tooltip,{title:"you"===eR||"another_user"===eR?"A descriptive name to identify this key":"Unique identifier for this service account",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"key_alias",rules:[{required:!0,message:`Please input a ${"you"===eR?"key name":"service account ID"}`}],help:"required",children:(0,t.jsx)(f.TextInput,{placeholder:""})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Models"," ",(0,t.jsx)(T.Tooltip,{title:"Select which models this key can access. Choose 'All Team Models' to grant access to all models available to the team. Leave empty to allow access to all models.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"models",rules:[],help:"management"===td||"read_only"===td?"Models field is disabled for this key type":"optional - leave empty to allow access to all models",className:"mt-4",children:(0,t.jsxs)(k.Select,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},disabled:"management"===td||"read_only"===td,onChange:e=>{e.includes("all-team-models")&&eT.setFieldsValue({models:["all-team-models"]})},children:[!e4&&(0,t.jsx)(er,{value:"all-team-models",children:"All Team Models"},"all-team-models"),eB.map(e=>(0,t.jsx)(er,{value:e,children:(0,J.getModelDisplayName)(e)},e))]})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Key Type"," ",(0,t.jsx)(T.Tooltip,{title:"Select the type of key to determine what routes and operations this key can access",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"key_type",initialValue:"llm_api",className:"mt-4",children:(0,t.jsxs)(k.Select,{defaultValue:"llm_api",placeholder:"Select key type",style:{width:"100%"},optionLabelProp:"label",onChange:e=>{tc(e),("management"===e||"read_only"===e)&&eT.setFieldsValue({models:[]})},children:[(0,t.jsx)(er,{value:"llm_api",label:"AI APIs",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)(I.Typography.Text,{strong:!0,children:"AI APIs"}),(0,t.jsx)(I.Typography.Paragraph,{type:"secondary",style:{fontSize:11,margin:"2px 0 0"},children:"Can call only AI API routes (chat/completions, embeddings, etc.)"})]})}),(0,t.jsx)(er,{value:"management",label:"Management",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)(I.Typography.Text,{strong:!0,children:"Management"}),(0,t.jsx)(I.Typography.Paragraph,{type:"secondary",style:{fontSize:11,margin:"2px 0 0"},children:"Can call only management routes (user/team/key management)"})]})}),(0,t.jsx)(er,{value:"default",label:"Full Access",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)(I.Typography.Text,{strong:!0,children:"Full Access"}),(0,t.jsx)(I.Typography.Paragraph,{type:"secondary",style:{fontSize:11,margin:"2px 0 0"},children:"Can call all routes (AI APIs, Management, and read-only)"})]})})]})})]}),!tM&&(0,t.jsx)("div",{className:"mb-8",children:(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)(b.Title,{className:"m-0",children:"Optional Settings"})}),(0,t.jsxs)(m.AccordionBody,{children:[(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Max Budget (USD)"," ",(0,t.jsx)(T.Tooltip,{title:"Maximum amount in USD this key can spend. When reached, the key will be blocked from making further requests",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"max_budget",help:`Budget cannot exceed team max budget: $${e?.max_budget!==null&&e?.max_budget!==void 0?e?.max_budget:"unlimited"}`,rules:[{validator:async(t,s)=>{if(s&&e&&null!==e.max_budget&&s>e.max_budget)throw Error(`Budget cannot exceed team max budget: $${(0,o.formatNumberWithCommas)(e.max_budget,4)}`)}}],children:(0,t.jsx)(el.default,{step:.01,precision:2,width:200})}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Reset Budget"," ",(0,t.jsx)(T.Tooltip,{title:"How often the budget should reset. For example, setting 'daily' will reset the budget every 24 hours",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"budget_duration",help:`Team Reset Budget: ${e?.budget_duration!==null&&e?.budget_duration!==void 0?e?.budget_duration:"None"}`,children:(0,t.jsx)(P.default,{onChange:e=>eT.setFieldValue("budget_duration",e)})}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Budget Windows"," ",(0,t.jsx)(T.Tooltip,{title:"Set multiple independent budget windows (e.g., hourly $10 AND monthly $200). Each window tracks spend separately and resets on its own schedule.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),children:(0,t.jsx)(Q.BudgetWindowsEditor,{value:tb,onChange:t_})}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Budget Fallbacks"," ",(0,t.jsx)(T.Tooltip,{title:"When a model exceeds its per-model budget (model_max_budget), requests automatically reroute to fallback models instead of failing. Configure per-model budgets in Advanced Settings.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),children:(0,t.jsx)(H.BudgetFallbacksEditor,{value:tj,onChange:tv,availableModels:eB},tw)}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Tokens per minute Limit (TPM)"," ",(0,t.jsx)(T.Tooltip,{title:"Maximum number of tokens this key can process per minute. Helps control usage and costs",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"tpm_limit",help:`TPM cannot exceed team TPM limit: ${e?.tpm_limit!==null&&e?.tpm_limit!==void 0?e?.tpm_limit:"unlimited"}`,rules:[{validator:async(t,s)=>{if(s&&e&&null!==e.tpm_limit&&s>e.tpm_limit)throw Error(`TPM limit cannot exceed team TPM limit: ${e.tpm_limit}`)}}],children:(0,t.jsx)(el.default,{step:1,width:400})}),(0,t.jsx)(z.default,{type:"tpm",name:"tpm_limit_type",className:"mt-4",initialValue:null,form:eT,showDetailedDescriptions:!0}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Requests per minute Limit (RPM)"," ",(0,t.jsx)(T.Tooltip,{title:"Maximum number of API requests this key can make per minute. Helps prevent abuse and manage load",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"rpm_limit",help:`RPM cannot exceed team RPM limit: ${e?.rpm_limit!==null&&e?.rpm_limit!==void 0?e?.rpm_limit:"unlimited"}`,rules:[{validator:async(t,s)=>{if(s&&e&&null!==e.rpm_limit&&s>e.rpm_limit)throw Error(`RPM limit cannot exceed team RPM limit: ${e.rpm_limit}`)}}],children:(0,t.jsx)(el.default,{step:1,width:400})}),(0,t.jsx)(z.default,{type:"rpm",name:"rpm_limit_type",className:"mt-4",initialValue:null,form:eT,showDetailedDescriptions:!0}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Guardrails"," ",(0,t.jsx)(T.Tooltip,{title:"Apply safety guardrails to this key to filter content or enforce policies",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"guardrails",className:"mt-4",help:ey?"Select existing guardrails or enter new ones":"Premium feature - Upgrade to set guardrails by key",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},disabled:!ey,placeholder:ey?"Select or enter guardrails":"Premium feature - Upgrade to set guardrails by key",options:eK.map(e=>({value:e,label:e}))})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Disable Global Guardrails"," ",(0,t.jsx)(T.Tooltip,{title:"When enabled, this key will bypass any guardrails configured to run on every request (global guardrails)",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"disable_global_guardrails",className:"mt-4",valuePropName:"checked",help:ey?"Bypass global guardrails for this key":"Premium feature - Upgrade to disable global guardrails by key",children:(0,t.jsx)(S.Switch,{disabled:!ey,checkedChildren:"Yes",unCheckedChildren:"No"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Policies"," ",(0,t.jsx)(T.Tooltip,{title:"Apply policies to this key to control guardrails and other settings",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/guardrail_policies",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"policies",className:"mt-4",help:ex?"Select existing policies or enter new ones":"Premium feature - Upgrade to set policies by key",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},disabled:!ex,placeholder:ex?"Select or enter policies":"Premium feature - Upgrade to set policies by key",options:eW.map(e=>({value:e,label:e}))})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Prompts"," ",(0,t.jsx)(T.Tooltip,{title:"Allow this key to use specific prompt templates",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/prompt_management",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"prompts",className:"mt-4",help:ex?"Select existing prompts or enter new ones":"Premium feature - Upgrade to set prompts by key",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},disabled:!ex,placeholder:ex?"Select or enter prompts":"Premium feature - Upgrade to set prompts by key",options:eQ.map(e=>({value:e,label:e}))})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Access Groups"," ",(0,t.jsx)(T.Tooltip,{title:"Assign access groups to this key. Access groups control which models, MCP servers, and agents this key can use",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"access_group_ids",className:"mt-4",help:"Select access groups to assign to this key",children:(0,t.jsx)(E.default,{placeholder:"Select access groups (optional)"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Pass Through Routes"," ",(0,t.jsx)(T.Tooltip,{title:"Allow this key to use specific pass through routes",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/pass_through",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"allowed_passthrough_routes",className:"mt-4",help:ex?"Select existing pass through routes or enter new ones":"Premium feature - Upgrade to set pass through routes by key",children:(0,t.jsx)(D.default,{onChange:e=>eT.setFieldValue("allowed_passthrough_routes",e),value:eT.getFieldValue("allowed_passthrough_routes"),accessToken:ep,placeholder:ex?"Select or enter pass through routes":"Premium feature - Upgrade to set pass through routes by key",disabled:!ex,teamId:eZ?eZ.team_id:null})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Vector Stores"," ",(0,t.jsx)(T.Tooltip,{title:"Select which vector stores this key can access. If none selected, the key will have access to all available vector stores",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"allowed_vector_store_ids",className:"mt-4",help:"Select vector stores this key can access. Leave empty for access to all vector stores",children:(0,t.jsx)(ea.default,{onChange:e=>eT.setFieldValue("allowed_vector_store_ids",e),value:eT.getFieldValue("allowed_vector_store_ids"),accessToken:ep,placeholder:"Select vector stores (optional)"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Metadata"," ",(0,t.jsx)(T.Tooltip,{title:"JSON object with additional information about this key. Used for tracking or custom logic",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"metadata",className:"mt-4",children:(0,t.jsx)(v.Input.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Tags"," ",(0,t.jsx)(T.Tooltip,{title:"Tags for tracking spend and/or doing tag-based routing. Used for analytics and filtering",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"tags",className:"mt-4",help:"Tags for tracking spend and/or doing tag-based routing.",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},placeholder:"Select or enter tags",tokenSeparators:[","],options:eS})}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"MCP Settings"})}),(0,t.jsxs)(m.AccordionBody,{children:[(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed MCP Servers"," ",(0,t.jsx)(T.Tooltip,{title:"Select which MCP servers or access groups this key can access",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"allowed_mcp_servers_and_groups",help:"Select MCP servers or access groups this key can access",children:(0,t.jsx)(Y.default,{onChange:e=>eT.setFieldValue("allowed_mcp_servers_and_groups",e),value:eT.getFieldValue("allowed_mcp_servers_and_groups"),accessToken:ep,teamId:eZ?.team_id??null,placeholder:"Select MCP servers or access groups (optional)",allowNoMcpServers:!0})}),(0,t.jsx)(j.Form.Item,{name:"mcp_tool_permissions",initialValue:{},hidden:!0,children:(0,t.jsx)(v.Input,{type:"hidden"})}),(0,t.jsx)(j.Form.Item,{noStyle:!0,shouldUpdate:(e,t)=>e.allowed_mcp_servers_and_groups!==t.allowed_mcp_servers_and_groups||e.mcp_tool_permissions!==t.mcp_tool_permissions,children:()=>(0,t.jsx)("div",{className:"mt-6",children:(0,t.jsx)(Z.default,{accessToken:ep,selectedServers:(eT.getFieldValue("allowed_mcp_servers_and_groups")?.servers||[]).filter(e=>e!==X.NO_MCP_SERVERS_SENTINEL),toolPermissions:eT.getFieldValue("mcp_tool_permissions")||{},onChange:e=>eT.setFieldsValue({mcp_tool_permissions:e})})})})]})]}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Agent Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Agents"," ",(0,t.jsx)(T.Tooltip,{title:"Select which agents or access groups this key can access",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"allowed_agents_and_groups",help:"Select agents or access groups this key can access",children:(0,t.jsx)(M.default,{onChange:e=>eT.setFieldValue("allowed_agents_and_groups",e),value:eT.getFieldValue("allowed_agents_and_groups"),accessToken:ep,placeholder:"Select agents or access groups (optional)"})})})]}),ex?(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Logging Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(V.default,{value:eY,onChange:eX,premiumUser:!0,disabledCallbacks:tn,onDisabledCallbacksChange:to})})})]}):(0,t.jsx)(T.Tooltip,{title:(0,t.jsxs)("span",{children:["Key-level logging settings is an enterprise feature, get in touch -",(0,t.jsx)("a",{href:"https://www.litellm.ai/enterprise",target:"_blank",children:"https://www.litellm.ai/enterprise"})]}),placement:"top",children:(0,t.jsxs)("div",{style:{position:"relative"},children:[(0,t.jsx)("div",{style:{opacity:.5},children:(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Logging Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(V.default,{value:eY,onChange:eX,premiumUser:!1,disabledCallbacks:tn,onDisabledCallbacksChange:to})})})]})}),(0,t.jsx)("div",{style:{position:"absolute",inset:0,cursor:"not-allowed"}})]})}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Router Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4 w-full",children:(0,t.jsx)(U.default,{accessToken:ep||"",value:ty||void 0,onChange:tf,modelData:eE.length>0?{data:eE.map(e=>({model_name:e}))}:void 0},tk)})})]},`router-settings-accordion-${tk}`),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Model Aliases"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsxs)("div",{className:"mt-4",children:[(0,t.jsx)(y.Text,{className:"text-sm text-gray-600 mb-4",children:"Create custom aliases for models that can be used in API calls. This allows you to create shortcuts for specific models."}),(0,t.jsx)(R.default,{accessToken:ep,initialModelAliases:tu,onAliasUpdate:tm,showExampleConfig:!1})]})})]}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Key Lifecycle"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)($.default,{form:eT,autoRotationEnabled:tp,onAutoRotationChange:tg,rotationInterval:th,onRotationIntervalChange:tx,isCreateMode:!0})})}),(0,t.jsx)(j.Form.Item,{name:"duration",hidden:!0,initialValue:null,children:(0,t.jsx)(v.Input,{})})]}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("b",{children:"Advanced Settings"}),(0,t.jsx)(T.Tooltip,{title:(0,t.jsxs)("span",{children:["Learn more about advanced settings in our"," ",(0,t.jsx)("a",{href:et.proxyBaseUrl?`${et.proxyBaseUrl}/#/key%20management/generate_key_fn_key_generate_post`:"/#/key%20management/generate_key_fn_key_generate_post",target:"_blank",rel:"noopener noreferrer",className:"text-blue-400 hover:text-blue-300",children:"documentation"})]}),children:(0,t.jsx)(d.InfoCircleOutlined,{className:"text-gray-400 hover:text-gray-300 cursor-help"})})]})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)(B.default,{schemaComponent:"GenerateKeyRequest",form:eT,excludedFields:["key_alias","team_id","organization_id","models","duration","metadata","tags","guardrails","max_budget","budget_duration","tpm_limit","rpm_limit",...ek?["key"]:[]]})})]})]})]})}),(0,t.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,t.jsx)(_.Button,{htmlType:"submit",disabled:tM,style:{opacity:tM?.5:1},children:"Create Key"})})]})}),e5&&(0,t.jsx)(w.Modal,{title:"Create New User",open:e5,onCancel:()=>e6(!1),footer:null,width:800,children:(0,t.jsx)(W.CreateUserButton,{userID:eg,accessToken:ep,teams:eo,possibleUIRoles:e8,onUserCreated:e=>{e9(e),eT.setFieldsValue({user_id:e}),e6(!1)},isEmbedded:!0})}),eL&&(0,t.jsx)(w.Modal,{open:eI,onOk:tL,onCancel:tF,footer:null,children:(0,t.jsxs)(x.Grid,{numItems:1,className:"gap-2 w-full",children:[(0,t.jsx)(b.Title,{children:"Save your Key"}),(0,t.jsx)(h.Col,{numColSpan:1,children:null!=eL?(0,t.jsx)(es.default,{apiKey:eL}):(0,t.jsx)(y.Text,{children:"Key being created, this might take 30s"})})]})})]})},"fetchTeamModels",0,ei,"fetchUserModels",0,en],702597)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0.zblsr85hcyn.js b/litellm/proxy/_experimental/out/_next/static/chunks/0.zblsr85hcyn.js new file mode 100644 index 00000000000..db300569099 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/0.zblsr85hcyn.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,991124,e=>{"use strict";let t=(0,e.i(475254).default)("copy",[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]]);e.s(["default",0,t])},269200,e=>{"use strict";var t=e.i(290571),i=e.i(271645),r=e.i(444755);let o=(0,e.i(673706).makeClassName)("Table"),a=i.default.forwardRef((e,a)=>{let{children:n,className:l}=e,s=(0,t.__rest)(e,["children","className"]);return i.default.createElement("div",{className:(0,r.tremorTwMerge)(o("root"),"overflow-auto",l)},i.default.createElement("table",Object.assign({ref:a,className:(0,r.tremorTwMerge)(o("table"),"w-full text-tremor-default","text-tremor-content","dark:text-dark-tremor-content")},s),n))});a.displayName="Table",e.s(["Table",0,a],269200)},942232,e=>{"use strict";var t=e.i(290571),i=e.i(271645),r=e.i(444755);let o=(0,e.i(673706).makeClassName)("TableBody"),a=i.default.forwardRef((e,a)=>{let{children:n,className:l}=e,s=(0,t.__rest)(e,["children","className"]);return i.default.createElement(i.default.Fragment,null,i.default.createElement("tbody",Object.assign({ref:a,className:(0,r.tremorTwMerge)(o("root"),"align-top divide-y","divide-tremor-border","dark:divide-dark-tremor-border",l)},s),n))});a.displayName="TableBody",e.s(["TableBody",0,a],942232)},977572,e=>{"use strict";var t=e.i(290571),i=e.i(271645),r=e.i(444755);let o=(0,e.i(673706).makeClassName)("TableCell"),a=i.default.forwardRef((e,a)=>{let{children:n,className:l}=e,s=(0,t.__rest)(e,["children","className"]);return i.default.createElement(i.default.Fragment,null,i.default.createElement("td",Object.assign({ref:a,className:(0,r.tremorTwMerge)(o("root"),"align-middle whitespace-nowrap text-left p-4",l)},s),n))});a.displayName="TableCell",e.s(["TableCell",0,a],977572)},427612,e=>{"use strict";var t=e.i(290571),i=e.i(271645),r=e.i(444755);let o=(0,e.i(673706).makeClassName)("TableHead"),a=i.default.forwardRef((e,a)=>{let{children:n,className:l}=e,s=(0,t.__rest)(e,["children","className"]);return i.default.createElement(i.default.Fragment,null,i.default.createElement("thead",Object.assign({ref:a,className:(0,r.tremorTwMerge)(o("root"),"text-left","text-tremor-content","dark:text-dark-tremor-content",l)},s),n))});a.displayName="TableHead",e.s(["TableHead",0,a],427612)},64848,e=>{"use strict";var t=e.i(290571),i=e.i(271645),r=e.i(444755);let o=(0,e.i(673706).makeClassName)("TableHeaderCell"),a=i.default.forwardRef((e,a)=>{let{children:n,className:l}=e,s=(0,t.__rest)(e,["children","className"]);return i.default.createElement(i.default.Fragment,null,i.default.createElement("th",Object.assign({ref:a,className:(0,r.tremorTwMerge)(o("root"),"whitespace-nowrap text-left font-semibold top-0 px-4 py-3.5","text-tremor-content-strong","dark:text-dark-tremor-content-strong",l)},s),n))});a.displayName="TableHeaderCell",e.s(["TableHeaderCell",0,a],64848)},496020,e=>{"use strict";var t=e.i(290571),i=e.i(271645),r=e.i(444755);let o=(0,e.i(673706).makeClassName)("TableRow"),a=i.default.forwardRef((e,a)=>{let{children:n,className:l}=e,s=(0,t.__rest)(e,["children","className"]);return i.default.createElement(i.default.Fragment,null,i.default.createElement("tr",Object.assign({ref:a,className:(0,r.tremorTwMerge)(o("row"),l)},s),n))});a.displayName="TableRow",e.s(["TableRow",0,a],496020)},68155,e=>{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"}))});e.s(["TrashIcon",0,i],68155)},360820,e=>{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 15l7-7 7 7"}))});e.s(["ChevronUpIcon",0,i],360820)},871943,e=>{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"}))});e.s(["ChevronDownIcon",0,i],871943)},389083,e=>{"use strict";var t=e.i(290571),i=e.i(271645),r=e.i(829087),o=e.i(480731),a=e.i(95779),n=e.i(444755),l=e.i(673706);let s={xs:{paddingX:"px-2",paddingY:"py-0.5",fontSize:"text-xs"},sm:{paddingX:"px-2.5",paddingY:"py-0.5",fontSize:"text-sm"},md:{paddingX:"px-3",paddingY:"py-0.5",fontSize:"text-md"},lg:{paddingX:"px-3.5",paddingY:"py-0.5",fontSize:"text-lg"},xl:{paddingX:"px-4",paddingY:"py-1",fontSize:"text-xl"}},c={xs:{height:"h-4",width:"w-4"},sm:{height:"h-4",width:"w-4"},md:{height:"h-4",width:"w-4"},lg:{height:"h-5",width:"w-5"},xl:{height:"h-6",width:"w-6"}},d=(0,l.makeClassName)("Badge"),m=i.default.forwardRef((e,m)=>{let{color:g,icon:u,size:p=o.Sizes.SM,tooltip:h,className:f,children:b}=e,v=(0,t.__rest)(e,["color","icon","size","tooltip","className","children"]),$=u||null,{tooltipProps:A,getReferenceProps:C}=(0,r.useTooltip)();return i.default.createElement("span",Object.assign({ref:(0,l.mergeRefs)([m,A.refs.setReference]),className:(0,n.tremorTwMerge)(d("root"),"w-max shrink-0 inline-flex justify-center items-center cursor-default rounded-tremor-small ring-1 ring-inset",g?(0,n.tremorTwMerge)((0,l.getColorClassNames)(g,a.colorPalette.background).bgColor,(0,l.getColorClassNames)(g,a.colorPalette.iconText).textColor,(0,l.getColorClassNames)(g,a.colorPalette.iconRing).ringColor,"bg-opacity-10 ring-opacity-20","dark:bg-opacity-5 dark:ring-opacity-60"):(0,n.tremorTwMerge)("bg-tremor-brand-faint text-tremor-brand-emphasis ring-tremor-brand/20","dark:bg-dark-tremor-brand-muted/50 dark:text-dark-tremor-brand dark:ring-dark-tremor-subtle/20"),s[p].paddingX,s[p].paddingY,s[p].fontSize,f)},C,v),i.default.createElement(r.default,Object.assign({text:h},A)),$?i.default.createElement($,{className:(0,n.tremorTwMerge)(d("icon"),"shrink-0 -ml-1 mr-1.5",c[p].height,c[p].width)}):null,i.default.createElement("span",{className:(0,n.tremorTwMerge)(d("text"),"whitespace-nowrap")},b))});m.displayName="Badge",e.s(["Badge",0,m],389083)},94629,e=>{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"}))});e.s(["SwitchVerticalIcon",0,i],94629)},591935,e=>{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"}))});e.s(["PencilAltIcon",0,i],591935)},728889,e=>{"use strict";var t=e.i(290571),i=e.i(271645),r=e.i(829087),o=e.i(480731),a=e.i(444755),n=e.i(673706),l=e.i(95779);let s={xs:{paddingX:"px-1.5",paddingY:"py-1.5"},sm:{paddingX:"px-1.5",paddingY:"py-1.5"},md:{paddingX:"px-2",paddingY:"py-2"},lg:{paddingX:"px-2",paddingY:"py-2"},xl:{paddingX:"px-2.5",paddingY:"py-2.5"}},c={xs:{height:"h-3",width:"w-3"},sm:{height:"h-5",width:"w-5"},md:{height:"h-5",width:"w-5"},lg:{height:"h-7",width:"w-7"},xl:{height:"h-9",width:"w-9"}},d={simple:{rounded:"",border:"",ring:"",shadow:""},light:{rounded:"rounded-tremor-default",border:"",ring:"",shadow:""},shadow:{rounded:"rounded-tremor-default",border:"border",ring:"",shadow:"shadow-tremor-card dark:shadow-dark-tremor-card"},solid:{rounded:"rounded-tremor-default",border:"border-2",ring:"ring-1",shadow:""},outlined:{rounded:"rounded-tremor-default",border:"border",ring:"ring-2",shadow:""}},m=(0,n.makeClassName)("Icon"),g=i.default.forwardRef((e,g)=>{let{icon:u,variant:p="simple",tooltip:h,size:f=o.Sizes.SM,color:b,className:v}=e,$=(0,t.__rest)(e,["icon","variant","tooltip","size","color","className"]),A=((e,t)=>{switch(e){case"simple":return{textColor:t?(0,n.getColorClassNames)(t,l.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:"",borderColor:"",ringColor:""};case"light":return{textColor:t?(0,n.getColorClassNames)(t,l.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,a.tremorTwMerge)((0,n.getColorClassNames)(t,l.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-brand-muted dark:bg-dark-tremor-brand-muted",borderColor:"",ringColor:""};case"shadow":return{textColor:t?(0,n.getColorClassNames)(t,l.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,a.tremorTwMerge)((0,n.getColorClassNames)(t,l.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:"border-tremor-border dark:border-dark-tremor-border",ringColor:""};case"solid":return{textColor:t?(0,n.getColorClassNames)(t,l.colorPalette.text).textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:t?(0,a.tremorTwMerge)((0,n.getColorClassNames)(t,l.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-brand dark:bg-dark-tremor-brand",borderColor:"border-tremor-brand-inverted dark:border-dark-tremor-brand-inverted",ringColor:"ring-tremor-ring dark:ring-dark-tremor-ring"};case"outlined":return{textColor:t?(0,n.getColorClassNames)(t,l.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,a.tremorTwMerge)((0,n.getColorClassNames)(t,l.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:t?(0,n.getColorClassNames)(t,l.colorPalette.ring).borderColor:"border-tremor-brand-subtle dark:border-dark-tremor-brand-subtle",ringColor:t?(0,a.tremorTwMerge)((0,n.getColorClassNames)(t,l.colorPalette.ring).ringColor,"ring-opacity-40"):"ring-tremor-brand-muted dark:ring-dark-tremor-brand-muted"}}})(p,b),{tooltipProps:C,getReferenceProps:I}=(0,r.useTooltip)();return i.default.createElement("span",Object.assign({ref:(0,n.mergeRefs)([g,C.refs.setReference]),className:(0,a.tremorTwMerge)(m("root"),"inline-flex shrink-0 items-center justify-center",A.bgColor,A.textColor,A.borderColor,A.ringColor,d[p].rounded,d[p].border,d[p].shadow,d[p].ring,s[f].paddingX,s[f].paddingY,v)},I,$),i.default.createElement(r.default,Object.assign({text:h},C)),i.default.createElement(u,{className:(0,a.tremorTwMerge)(m("icon"),"shrink-0",c[f].height,c[f].width)}))});g.displayName="Icon",e.s(["default",0,g],728889)},752978,e=>{"use strict";var t=e.i(728889);e.s(["Icon",()=>t.default])},207670,e=>{"use strict";function t(){for(var e,t,i=0,r="",o=arguments.length;i{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"}))});e.s(["RefreshIcon",0,i],278587)},551332,e=>{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"}))});e.s(["ClipboardCopyIcon",0,i],551332)},122577,e=>{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"}),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M21 12a9 9 0 11-18 0 9 9 0 0118 0z"}))});e.s(["PlayIcon",0,i],122577)},434626,e=>{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"}))});e.s(["ExternalLinkIcon",0,i],434626)},902555,e=>{"use strict";var t=e.i(843476),i=e.i(591935),r=e.i(122577),o=e.i(278587),a=e.i(68155),n=e.i(360820),l=e.i(871943),s=e.i(434626),c=e.i(551332),d=e.i(592968),m=e.i(115504),g=e.i(752978);function u({icon:e,onClick:i,className:r,disabled:o,dataTestId:a}){return o?(0,t.jsx)(g.Icon,{icon:e,size:"sm",className:"opacity-50 cursor-not-allowed","data-testid":a}):(0,t.jsx)(g.Icon,{icon:e,size:"sm",onClick:i,className:(0,m.cx)("cursor-pointer",r),"data-testid":a})}let p={Edit:{icon:i.PencilAltIcon,className:"hover:text-blue-600"},Delete:{icon:a.TrashIcon,className:"hover:text-red-600"},Test:{icon:r.PlayIcon,className:"hover:text-blue-600"},Regenerate:{icon:o.RefreshIcon,className:"hover:text-green-600"},Up:{icon:n.ChevronUpIcon,className:"hover:text-blue-600"},Down:{icon:l.ChevronDownIcon,className:"hover:text-blue-600"},Open:{icon:s.ExternalLinkIcon,className:"hover:text-green-600"},Copy:{icon:c.ClipboardCopyIcon,className:"hover:text-blue-600"}};e.s(["default",0,function({onClick:e,tooltipText:i,disabled:r=!1,disabledTooltipText:o,dataTestId:a,variant:n}){let{icon:l,className:s}=p[n];return(0,t.jsx)(d.Tooltip,{title:r?o:i,children:(0,t.jsx)("span",{children:(0,t.jsx)(u,{icon:l,onClick:e,className:s,disabled:r,dataTestId:a})})})}],902555)},755151,e=>{"use strict";var t=e.i(247153);e.s(["DownOutlined",()=>t.default])},916925,e=>{"use strict";var t,i=e.i(555987),r=((t={}).A2A_Agent="A2A Agent",t.AI21="Ai21",t.AI21_CHAT="Ai21 Chat",t.AIML="AI/ML API",t.AIOHTTP_OPENAI="Aiohttp Openai",t.Anthropic="Anthropic",t.ANTHROPIC_TEXT="Anthropic Text",t.AssemblyAI="AssemblyAI",t.AUTO_ROUTER="Auto Router",t.Bedrock="Amazon Bedrock",t.BedrockMantle="Amazon Bedrock Mantle",t.SageMaker="AWS SageMaker",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Foundry (Studio)",t.AZURE_TEXT="Azure Text",t.BASETEN="Baseten",t.BYTEZ="Bytez",t.Cerebras="Cerebras",t.CLARIFAI="Clarifai",t.CLOUDFLARE="Cloudflare",t.CODESTRAL="Codestral",t.Cohere="Cohere",t.COHERE_CHAT="Cohere Chat",t.COMETAPI="Cometapi",t.COMPACTIFAI="Compactifai",t.Cursor="Cursor",t.Dashscope="Dashscope",t.Databricks="Databricks (Qwen API)",t.DATAROBOT="Datarobot",t.DeepInfra="DeepInfra",t.Deepgram="Deepgram",t.Deepseek="Deepseek",t.DOCKER_MODEL_RUNNER="Docker Model Runner",t.DOTPROMPT="Dotprompt",t.ElevenLabs="ElevenLabs",t.EMPOWER="Empower",t.FalAI="Fal AI",t.FEATHERLESS_AI="Featherless Ai",t.FireworksAI="Fireworks AI",t.FRIENDLIAI="Friendliai",t.GALADRIEL="Galadriel",t.GITHUB_COPILOT="Github Copilot",t.Google_AI_Studio="Google AI Studio",t.GradientAI="GradientAI",t.Groq="Groq",t.HEROKU="Heroku",t.Hosted_Vllm="vllm",t.HUGGINGFACE="Huggingface",t.HYPERBOLIC="Hyperbolic",t.Infinity="Infinity",t.JinaAI="Jina AI",t.LAMBDA_AI="Lambda Ai",t.LEMONADE="Lemonade",t.LLAMAFILE="Llamafile",t.LM_STUDIO="Lm Studio",t.LLAMA="Meta Llama",t.MARITALK="Maritalk",t.MiniMax="MiniMax",t.MistralAI="Mistral AI",t.MOONSHOT="Moonshot",t.MORPH="Morph",t.NEBIUS="Nebius",t.NLP_CLOUD="Nlp Cloud",t.NOVITA="Novita",t.NSCALE="Nscale",t.NVIDIA_NIM="Nvidia Nim",t.Ollama="Ollama",t.OLLAMA_CHAT="Ollama Chat",t.OOBABOOGA="Oobabooga",t.OpenAI="OpenAI",t.OPENAI_LIKE="Openai Like",t.OpenAI_Compatible="OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)",t.OpenAI_Text="OpenAI Text Completion",t.OpenAI_Text_Compatible="OpenAI-Compatible Completions (legacy /v1/completions)",t.Openrouter="Openrouter",t.Oracle="Oracle Cloud Infrastructure (OCI)",t.OVHCLOUD="Ovhcloud",t.Perplexity="Perplexity",t.PETALS="Petals",t.PG_VECTOR="Pg Vector",t.PREDIBASE="Predibase",t.RECRAFT="Recraft",t.REPLICATE="Replicate",t.RunwayML="RunwayML",t.SAGEMAKER_LEGACY="Sagemaker",t.Sambanova="Sambanova",t.SAP="SAP Generative AI Hub",t.Snowflake="Snowflake",t.Soniox="Soniox",t.TEXT_COMPLETION_CODESTRAL="Text-Completion-Codestral",t.TogetherAI="TogetherAI",t.TOPAZ="Topaz",t.Triton="Triton",t.V0="V0",t.VERCEL_AI_GATEWAY="Vercel Ai Gateway",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.VERTEX_AI_BETA="Vertex Ai Beta",t.VLLM="Vllm",t.VolcEngine="VolcEngine",t.Voyage="Voyage AI",t.WANDB="Wandb",t.WATSONX="Watsonx",t.WATSONX_TEXT="Watsonx Text",t.xAI="xAI",t.XINFERENCE="Xinference",t.ZAI="Z.AI (Zhipu AI)",t);let o={A2A_Agent:"a2a_agent",AI21:"ai21",AI21_CHAT:"ai21_chat",AIML:"aiml",AIOHTTP_OPENAI:"aiohttp_openai",Anthropic:"anthropic",ANTHROPIC_TEXT:"anthropic_text",AssemblyAI:"assemblyai",AUTO_ROUTER:"auto_router",Azure:"azure",Azure_AI_Studio:"azure_ai",AZURE_TEXT:"azure_text",BASETEN:"baseten",Bedrock:"bedrock",BedrockMantle:"bedrock_mantle",BYTEZ:"bytez",Cerebras:"cerebras",CLARIFAI:"clarifai",CLOUDFLARE:"cloudflare",CODESTRAL:"codestral",Cohere:"cohere",COHERE_CHAT:"cohere_chat",COMETAPI:"cometapi",COMPACTIFAI:"compactifai",Cursor:"cursor",Dashscope:"dashscope",Databricks:"databricks",DATAROBOT:"datarobot",DeepInfra:"deepinfra",Deepgram:"deepgram",Deepseek:"deepseek",DOCKER_MODEL_RUNNER:"docker_model_runner",DOTPROMPT:"dotprompt",ElevenLabs:"elevenlabs",EMPOWER:"empower",FalAI:"fal_ai",FEATHERLESS_AI:"featherless_ai",FireworksAI:"fireworks_ai",FRIENDLIAI:"friendliai",GALADRIEL:"galadriel",GITHUB_COPILOT:"github_copilot",Google_AI_Studio:"gemini",GradientAI:"gradient_ai",Groq:"groq",HEROKU:"heroku",Hosted_Vllm:"hosted_vllm",HUGGINGFACE:"huggingface",HYPERBOLIC:"hyperbolic",Infinity:"infinity",JinaAI:"jina_ai",LAMBDA_AI:"lambda_ai",LEMONADE:"lemonade",LLAMAFILE:"llamafile",LLAMA:"meta_llama",LM_STUDIO:"lm_studio",MARITALK:"maritalk",MiniMax:"minimax",MistralAI:"mistral",MOONSHOT:"moonshot",MORPH:"morph",NEBIUS:"nebius",NLP_CLOUD:"nlp_cloud",NOVITA:"novita",NSCALE:"nscale",NVIDIA_NIM:"nvidia_nim",Ollama:"ollama",OLLAMA_CHAT:"ollama_chat",OOBABOOGA:"oobabooga",OpenAI:"openai",OPENAI_LIKE:"openai_like",OpenAI_Compatible:"openai",OpenAI_Text:"text-completion-openai",OpenAI_Text_Compatible:"text-completion-openai",Openrouter:"openrouter",Oracle:"oci",OVHCLOUD:"ovhcloud",Perplexity:"perplexity",PETALS:"petals",PG_VECTOR:"pg_vector",PREDIBASE:"predibase",RECRAFT:"recraft",REPLICATE:"replicate",RunwayML:"runwayml",SAGEMAKER_LEGACY:"sagemaker",SageMaker:"sagemaker_chat",Sambanova:"sambanova",SAP:"sap",Snowflake:"snowflake",Soniox:"soniox",TEXT_COMPLETION_CODESTRAL:"text-completion-codestral",TogetherAI:"together_ai",TOPAZ:"topaz",Triton:"triton",V0:"v0",VERCEL_AI_GATEWAY:"vercel_ai_gateway",Vertex_AI:"vertex_ai",VERTEX_AI_BETA:"vertex_ai_beta",VLLM:"vllm",VolcEngine:"volcengine",Voyage:"voyage",WANDB:"wandb",WATSONX:"watsonx",WATSONX_TEXT:"watsonx_text",xAI:"xai",XINFERENCE:"xinference",ZAI:"zai"},a=new Set(["bedrock_mantle"]),n="/ui/assets/logos/",l={"A2A Agent":`${n}a2a_agent.png`,Ai21:`${n}ai21.svg`,"Ai21 Chat":`${n}ai21.svg`,"AI/ML API":`${n}aiml_api.svg`,"Aiohttp Openai":`${n}openai_small.svg`,Anthropic:`${n}anthropic.svg`,"Anthropic Text":`${n}anthropic.svg`,AssemblyAI:`${n}assemblyai_small.png`,Azure:`${n}microsoft_azure.svg`,"Azure AI Foundry (Studio)":`${n}microsoft_azure.svg`,"Azure Text":`${n}microsoft_azure.svg`,Baseten:`${n}baseten.svg`,"Amazon Bedrock":`${n}bedrock.svg`,"Amazon Bedrock Mantle":`${n}bedrock.svg`,"AWS SageMaker":`${n}bedrock.svg`,Cerebras:`${n}cerebras.svg`,Cloudflare:`${n}cloudflare.svg`,Codestral:`${n}mistral.svg`,Cohere:`${n}cohere.svg`,"Cohere Chat":`${n}cohere.svg`,Cometapi:`${n}cometapi.svg`,Cursor:`${n}cursor.svg`,"Databricks (Qwen API)":`${n}databricks.svg`,Dashscope:`${n}dashscope.svg`,Deepseek:`${n}deepseek.svg`,Deepgram:`${n}deepgram.png`,DeepInfra:`${n}deepinfra.png`,ElevenLabs:`${n}elevenlabs.png`,"Fal AI":`${n}fal_ai.jpg`,"Featherless Ai":`${n}featherless.svg`,"Fireworks AI":`${n}fireworks.svg`,Friendliai:`${n}friendli.svg`,"Github Copilot":`${n}github_copilot.svg`,"Google AI Studio":`${n}google.svg`,GradientAI:`${n}gradientai.svg`,Groq:`${n}groq.svg`,vllm:`${n}vllm.png`,Huggingface:`${n}huggingface.svg`,Hyperbolic:`${n}hyperbolic.svg`,Infinity:`${n}infinity.png`,"Jina AI":`${n}jina.png`,"Lambda Ai":`${n}lambda.svg`,"Lm Studio":`${n}lmstudio.svg`,"Meta Llama":`${n}meta_llama.svg`,MiniMax:`${n}minimax.svg`,"Mistral AI":`${n}mistral.svg`,Moonshot:`${n}moonshot.svg`,Morph:`${n}morph.svg`,Nebius:`${n}nebius.svg`,Novita:`${n}novita.svg`,"Nvidia Nim":`${n}nvidia_nim.svg`,Ollama:`${n}ollama.svg`,"Ollama Chat":`${n}ollama.svg`,Oobabooga:`${n}openai_small.svg`,OpenAI:`${n}openai_small.svg`,"Openai Like":`${n}openai_small.svg`,"OpenAI Text Completion":`${n}openai_small.svg`,"OpenAI-Compatible Completions (legacy /v1/completions)":`${n}openai_small.svg`,"OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)":`${n}openai_small.svg`,Openrouter:`${n}openrouter.svg`,"Oracle Cloud Infrastructure (OCI)":`${n}oracle.svg`,Perplexity:`${n}perplexity-ai.svg`,Recraft:`${n}recraft.svg`,Replicate:`${n}replicate.svg`,RunwayML:`${n}runwayml.png`,Sagemaker:`${n}bedrock.svg`,Sambanova:`${n}sambanova.svg`,"SAP Generative AI Hub":`${n}sap.png`,Snowflake:`${n}snowflake.svg`,Soniox:`${n}soniox.svg`,"Text-Completion-Codestral":`${n}mistral.svg`,TogetherAI:`${n}togetherai.svg`,Topaz:`${n}topaz.svg`,Triton:`${n}nvidia_triton.png`,V0:`${n}v0.svg`,"Vercel Ai Gateway":`${n}vercel.svg`,"Vertex AI (Anthropic, Gemini, etc.)":`${n}google.svg`,"Vertex Ai Beta":`${n}google.svg`,Vllm:`${n}vllm.png`,VolcEngine:`${n}volcengine.png`,"Voyage AI":`${n}voyage.webp`,Watsonx:`${n}watsonx.svg`,"Watsonx Text":`${n}watsonx.svg`,xAI:`${n}xai.svg`,Xinference:`${n}xinference.svg`};e.s(["Providers",()=>r,"getPlaceholder",0,e=>{if("AI/ML API"===e)return"aiml/flux-pro/v1.1";if("Vertex AI (Anthropic, Gemini, etc.)"===e)return"gemini-pro";if("Anthropic"==e)return"claude-3-opus";if("Amazon Bedrock"==e)return"claude-3-opus";if("AWS SageMaker"==e)return"sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b";else if("Google AI Studio"==e)return"gemini-pro";else if("Azure AI Foundry (Studio)"==e)return"azure_ai/command-r-plus";else if("Azure"==e)return"my-deployment";else if("Oracle Cloud Infrastructure (OCI)"==e)return"oci/xai.grok-4";else if("Snowflake"==e)return"snowflake/mistral-7b";else if("Voyage AI"==e)return"voyage/";else if("Jina AI"==e)return"jina_ai/";else if("VolcEngine"==e)return"volcengine/";else if("DeepInfra"==e)return"deepinfra/";else if("Fal AI"==e)return"fal_ai/fal-ai/flux-pro/v1.1-ultra";else if("RunwayML"==e)return"runwayml/gen4_turbo";else if("Watsonx"===e)return"watsonx/ibm/granite-3-3-8b-instruct";else if("Cursor"===e)return"cursor/claude-4-sonnet";else if("Z.AI (Zhipu AI)"===e)return"zai/glm-4.5";else return"gpt-3.5-turbo"},"getProviderLogoAndName",0,e=>{if(!e)return{logo:"",displayName:"-"};if("gemini"===e.toLowerCase()){let e="Google AI Studio";return{logo:(0,i.resolveLogoSrc)(l[e])??"",displayName:e}}let t=Object.keys(o).find(t=>o[t].toLowerCase()===e.toLowerCase())??Object.keys(o).find(t=>t.toLowerCase()===e.toLowerCase());if(!t)return{logo:"",displayName:e};let a=r[t];return{logo:(0,i.resolveLogoSrc)(l[a])??"",displayName:a}},"getProviderModels",0,(e,t)=>{let i=o[e],r=[];return e&&"object"==typeof t&&(Object.entries(t).forEach(([e,t])=>{if(null!==t&&"object"==typeof t&&"litellm_provider"in t){let o=t.litellm_provider,n="string"==typeof o&&(o.startsWith(`${i}_`)||o.startsWith(`${i}-`));(o===i||n&&!a.has(o))&&r.push(e)}}),"Cohere"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"cohere_chat"===t.litellm_provider&&r.push(e)}),"AWS SageMaker"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"sagemaker_chat"===t.litellm_provider&&r.push(e)})),r},"providerLogoMap",0,l,"provider_map",0,o])},928685,e=>{"use strict";var t=e.i(38953);e.s(["SearchOutlined",()=>t.default])},596239,e=>{"use strict";e.i(247167);var t=e.i(931067),i=e.i(271645);let r={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M574 665.4a8.03 8.03 0 00-11.3 0L446.5 781.6c-53.8 53.8-144.6 59.5-204 0-59.5-59.5-53.8-150.2 0-204l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3l-39.8-39.8a8.03 8.03 0 00-11.3 0L191.4 526.5c-84.6 84.6-84.6 221.5 0 306s221.5 84.6 306 0l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3L574 665.4zm258.6-474c-84.6-84.6-221.5-84.6-306 0L410.3 307.6a8.03 8.03 0 000 11.3l39.7 39.7c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c53.8-53.8 144.6-59.5 204 0 59.5 59.5 53.8 150.2 0 204L665.3 562.6a8.03 8.03 0 000 11.3l39.8 39.8c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c84.5-84.6 84.5-221.5 0-306.1zM610.1 372.3a8.03 8.03 0 00-11.3 0L372.3 598.7a8.03 8.03 0 000 11.3l39.6 39.6c3.1 3.1 8.2 3.1 11.3 0l226.4-226.4c3.1-3.1 3.1-8.2 0-11.3l-39.5-39.6z"}}]},name:"link",theme:"outlined"};var o=e.i(9583),a=i.forwardRef(function(e,a){return i.createElement(o.default,(0,t.default)({},e,{ref:a,icon:r}))});e.s(["LinkOutlined",0,a],596239)},280898,e=>{"use strict";e.i(247167);var t=e.i(271645),i=e.i(121229),r=e.i(864517),o=e.i(343794),a=e.i(931067),n=e.i(209428),l=e.i(211577),s=e.i(703923),c=e.i(404948),d=["className","prefixCls","style","active","status","iconPrefix","icon","wrapperStyle","stepNumber","disabled","description","title","subTitle","progressDot","stepIcon","tailContent","icons","stepIndex","onStepClick","onClick","render"];function m(e){return"string"==typeof e}let g=function(e){var i,r,g,u,p,h=e.className,f=e.prefixCls,b=e.style,v=e.active,$=e.status,A=e.iconPrefix,C=e.icon,I=(e.wrapperStyle,e.stepNumber),w=e.disabled,x=e.description,k=e.title,S=e.subTitle,E=e.progressDot,T=e.stepIcon,O=e.tailContent,y=e.icons,N=e.stepIndex,L=e.onStepClick,_=e.onClick,M=e.render,R=(0,s.default)(e,d),P={};L&&!w&&(P.role="button",P.tabIndex=0,P.onClick=function(e){null==_||_(e),L(N)},P.onKeyDown=function(e){var t=e.which;(t===c.default.ENTER||t===c.default.SPACE)&&L(N)});var z=$||"wait",H=(0,o.default)("".concat(f,"-item"),"".concat(f,"-item-").concat(z),h,(p={},(0,l.default)(p,"".concat(f,"-item-custom"),C),(0,l.default)(p,"".concat(f,"-item-active"),v),(0,l.default)(p,"".concat(f,"-item-disabled"),!0===w),p)),j=(0,n.default)({},b),D=t.createElement("div",(0,a.default)({},R,{className:H,style:j}),t.createElement("div",(0,a.default)({onClick:_},P,{className:"".concat(f,"-item-container")}),t.createElement("div",{className:"".concat(f,"-item-tail")},O),t.createElement("div",{className:"".concat(f,"-item-icon")},(g=(0,o.default)("".concat(f,"-icon"),"".concat(A,"icon"),(i={},(0,l.default)(i,"".concat(A,"icon-").concat(C),C&&m(C)),(0,l.default)(i,"".concat(A,"icon-check"),!C&&"finish"===$&&(y&&!y.finish||!y)),(0,l.default)(i,"".concat(A,"icon-cross"),!C&&"error"===$&&(y&&!y.error||!y)),i)),u=t.createElement("span",{className:"".concat(f,"-icon-dot")}),r=E?"function"==typeof E?t.createElement("span",{className:"".concat(f,"-icon")},E(u,{index:I-1,status:$,title:k,description:x})):t.createElement("span",{className:"".concat(f,"-icon")},u):C&&!m(C)?t.createElement("span",{className:"".concat(f,"-icon")},C):y&&y.finish&&"finish"===$?t.createElement("span",{className:"".concat(f,"-icon")},y.finish):y&&y.error&&"error"===$?t.createElement("span",{className:"".concat(f,"-icon")},y.error):C||"finish"===$||"error"===$?t.createElement("span",{className:g}):t.createElement("span",{className:"".concat(f,"-icon")},I),T&&(r=T({index:I-1,status:$,title:k,description:x,node:r})),r)),t.createElement("div",{className:"".concat(f,"-item-content")},t.createElement("div",{className:"".concat(f,"-item-title")},k,S&&t.createElement("div",{title:"string"==typeof S?S:void 0,className:"".concat(f,"-item-subtitle")},S)),x&&t.createElement("div",{className:"".concat(f,"-item-description")},x))));return M&&(D=M(D)||null),D};var u=["prefixCls","style","className","children","direction","type","labelPlacement","iconPrefix","status","size","current","progressDot","stepIcon","initial","icons","onChange","itemRender","items"];function p(e){var i,r=e.prefixCls,c=void 0===r?"rc-steps":r,d=e.style,m=void 0===d?{}:d,p=e.className,h=(e.children,e.direction),f=e.type,b=void 0===f?"default":f,v=e.labelPlacement,$=e.iconPrefix,A=void 0===$?"rc":$,C=e.status,I=void 0===C?"process":C,w=e.size,x=e.current,k=void 0===x?0:x,S=e.progressDot,E=e.stepIcon,T=e.initial,O=void 0===T?0:T,y=e.icons,N=e.onChange,L=e.itemRender,_=e.items,M=(0,s.default)(e,u),R="inline"===b,P=R||void 0!==S&&S,z=R||void 0===h?"horizontal":h,H=R?void 0:w,j=(0,o.default)(c,"".concat(c,"-").concat(z),p,(i={},(0,l.default)(i,"".concat(c,"-").concat(H),H),(0,l.default)(i,"".concat(c,"-label-").concat(P?"vertical":void 0===v?"horizontal":v),"horizontal"===z),(0,l.default)(i,"".concat(c,"-dot"),!!P),(0,l.default)(i,"".concat(c,"-navigation"),"navigation"===b),(0,l.default)(i,"".concat(c,"-inline"),R),i)),D=function(e){N&&k!==e&&N(e)};return t.default.createElement("div",(0,a.default)({className:j,style:m},M),(void 0===_?[]:_).filter(function(e){return e}).map(function(e,i){var r=(0,n.default)({},e),o=O+i;return"error"===I&&i===k-1&&(r.className="".concat(c,"-next-error")),r.status||(o===k?r.status=I:o{let i=`${t.componentCls}-item`,r=`${e}IconColor`,o=`${e}TitleColor`,a=`${e}DescriptionColor`,n=`${e}TailColor`,l=`${e}IconBgColor`,s=`${e}IconBorderColor`,c=`${e}DotColor`;return{[`${i}-${e} ${i}-icon`]:{backgroundColor:t[l],borderColor:t[s],[`> ${t.componentCls}-icon`]:{color:t[r],[`${t.componentCls}-icon-dot`]:{background:t[c]}}},[`${i}-${e}${i}-custom ${i}-icon`]:{[`> ${t.componentCls}-icon`]:{color:t[c]}},[`${i}-${e} > ${i}-container > ${i}-content > ${i}-title`]:{color:t[o],"&::after":{backgroundColor:t[n]}},[`${i}-${e} > ${i}-container > ${i}-content > ${i}-description`]:{color:t[a]},[`${i}-${e} > ${i}-container > ${i}-tail::after`]:{backgroundColor:t[n]}}},k=(0,I.genStyleHooks)("Steps",e=>{let{colorTextDisabled:t,controlHeightLG:i,colorTextLightSolid:r,colorText:o,colorPrimary:a,colorTextDescription:n,colorTextQuaternary:l,colorError:s,colorBorderSecondary:c,colorSplit:d}=e;return(e=>{let{componentCls:t}=e;return{[t]:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},(0,C.resetComponent)(e)),{display:"flex",width:"100%",fontSize:0,textAlign:"initial"}),(e=>{let{componentCls:t,motionDurationSlow:i}=e,r=`${t}-item`,o=`${r}-icon`;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({[r]:{position:"relative",display:"inline-block",flex:1,overflow:"hidden",verticalAlign:"top","&:last-child":{flex:"none",[`> ${r}-container > ${r}-tail, > ${r}-container > ${r}-content > ${r}-title::after`]:{display:"none"}}},[`${r}-container`]:{outline:"none",[`&:focus-visible ${o}`]:(0,C.genFocusOutline)(e)},[`${o}, ${r}-content`]:{display:"inline-block",verticalAlign:"top"},[o]:{width:e.iconSize,height:e.iconSize,marginTop:0,marginBottom:0,marginInlineStart:0,marginInlineEnd:e.marginXS,fontSize:e.iconFontSize,fontFamily:e.fontFamily,lineHeight:(0,A.unit)(e.iconSize),textAlign:"center",borderRadius:e.iconSize,border:`${(0,A.unit)(e.lineWidth)} ${e.lineType} transparent`,transition:`background-color ${i}, border-color ${i}`,[`${t}-icon`]:{position:"relative",top:e.iconTop,color:e.colorPrimary,lineHeight:1}},[`${r}-tail`]:{position:"absolute",top:e.calc(e.iconSize).div(2).equal(),insetInlineStart:0,width:"100%","&::after":{display:"inline-block",width:"100%",height:e.lineWidth,background:e.colorSplit,borderRadius:e.lineWidth,transition:`background ${i}`,content:'""'}},[`${r}-title`]:{position:"relative",display:"inline-block",paddingInlineEnd:e.padding,color:e.colorText,fontSize:e.fontSizeLG,lineHeight:(0,A.unit)(e.titleLineHeight),"&::after":{position:"absolute",top:e.calc(e.titleLineHeight).div(2).equal(),insetInlineStart:"100%",display:"block",width:9999,height:e.lineWidth,background:e.processTailColor,content:'""'}},[`${r}-subtitle`]:{display:"inline",marginInlineStart:e.marginXS,color:e.colorTextDescription,fontWeight:"normal",fontSize:e.fontSize},[`${r}-description`]:{color:e.colorTextDescription,fontSize:e.fontSize}},x("wait",e)),x("process",e)),{[`${r}-process > ${r}-container > ${r}-title`]:{fontWeight:e.fontWeightStrong}}),x("finish",e)),x("error",e)),{[`${r}${t}-next-error > ${t}-item-title::after`]:{background:e.colorError},[`${r}-disabled`]:{cursor:"not-allowed"}})})(e)),(e=>{let{componentCls:t,motionDurationSlow:i}=e;return{[`& ${t}-item`]:{[`&:not(${t}-item-active)`]:{[`& > ${t}-item-container[role='button']`]:{cursor:"pointer",[`${t}-item`]:{[`&-title, &-subtitle, &-description, &-icon ${t}-icon`]:{transition:`color ${i}`}},"&:hover":{[`${t}-item`]:{"&-title, &-subtitle, &-description":{color:e.colorPrimary}}}},[`&:not(${t}-item-process)`]:{[`& > ${t}-item-container[role='button']:hover`]:{[`${t}-item`]:{"&-icon":{borderColor:e.colorPrimary,[`${t}-icon`]:{color:e.colorPrimary}}}}}}},[`&${t}-horizontal:not(${t}-label-vertical)`]:{[`${t}-item`]:{paddingInlineStart:e.padding,whiteSpace:"nowrap","&:first-child":{paddingInlineStart:0},[`&:last-child ${t}-item-title`]:{paddingInlineEnd:0},"&-tail":{display:"none"},"&-description":{maxWidth:e.descriptionMaxWidth,whiteSpace:"normal"}}}}})(e)),(e=>{let{componentCls:t,customIconTop:i,customIconSize:r,customIconFontSize:o}=e;return{[`${t}-item-custom`]:{[`> ${t}-item-container > ${t}-item-icon`]:{height:"auto",background:"none",border:0,[`> ${t}-icon`]:{top:i,width:r,height:r,fontSize:o,lineHeight:(0,A.unit)(r)}}},[`&:not(${t}-vertical)`]:{[`${t}-item-custom`]:{[`${t}-item-icon`]:{width:"auto",background:"none"}}}}})(e)),(e=>{let{componentCls:t,iconSizeSM:i,fontSizeSM:r,fontSize:o,colorTextDescription:a}=e;return{[`&${t}-small`]:{[`&${t}-horizontal:not(${t}-label-vertical) ${t}-item`]:{paddingInlineStart:e.paddingSM,"&:first-child":{paddingInlineStart:0}},[`${t}-item-icon`]:{width:i,height:i,marginTop:0,marginBottom:0,marginInline:`0 ${(0,A.unit)(e.marginXS)}`,fontSize:r,lineHeight:(0,A.unit)(i),textAlign:"center",borderRadius:i},[`${t}-item-title`]:{paddingInlineEnd:e.paddingSM,fontSize:o,lineHeight:(0,A.unit)(i),"&::after":{top:e.calc(i).div(2).equal()}},[`${t}-item-description`]:{color:a,fontSize:o},[`${t}-item-tail`]:{top:e.calc(i).div(2).sub(e.paddingXXS).equal()},[`${t}-item-custom ${t}-item-icon`]:{width:"inherit",height:"inherit",lineHeight:"inherit",background:"none",border:0,borderRadius:0,[`> ${t}-icon`]:{fontSize:i,lineHeight:(0,A.unit)(i),transform:"none"}}}}})(e)),(e=>{let{componentCls:t,iconSizeSM:i,iconSize:r}=e;return{[`&${t}-vertical`]:{display:"flex",flexDirection:"column",[`> ${t}-item`]:{display:"block",flex:"1 0 auto",paddingInlineStart:0,overflow:"visible",[`${t}-item-icon`]:{float:"left",marginInlineEnd:e.margin},[`${t}-item-content`]:{display:"block",minHeight:e.calc(e.controlHeight).mul(1.5).equal(),overflow:"hidden"},[`${t}-item-title`]:{lineHeight:(0,A.unit)(r)},[`${t}-item-description`]:{paddingBottom:e.paddingSM}},[`> ${t}-item > ${t}-item-container > ${t}-item-tail`]:{position:"absolute",top:0,insetInlineStart:e.calc(r).div(2).sub(e.lineWidth).equal(),width:e.lineWidth,height:"100%",padding:`${(0,A.unit)(e.calc(e.marginXXS).mul(1.5).add(r).equal())} 0 ${(0,A.unit)(e.calc(e.marginXXS).mul(1.5).equal())}`,"&::after":{width:e.lineWidth,height:"100%"}},[`> ${t}-item:not(:last-child) > ${t}-item-container > ${t}-item-tail`]:{display:"block"},[` > ${t}-item > ${t}-item-container > ${t}-item-content > ${t}-item-title`]:{"&::after":{display:"none"}},[`&${t}-small ${t}-item-container`]:{[`${t}-item-tail`]:{position:"absolute",top:0,insetInlineStart:e.calc(i).div(2).sub(e.lineWidth).equal(),padding:`${(0,A.unit)(e.calc(e.marginXXS).mul(1.5).add(i).equal())} 0 ${(0,A.unit)(e.calc(e.marginXXS).mul(1.5).equal())}`},[`${t}-item-title`]:{lineHeight:(0,A.unit)(i)}}}}})(e)),(e=>{let{componentCls:t}=e,i=`${t}-item`;return{[`${t}-horizontal`]:{[`${i}-tail`]:{transform:"translateY(-50%)"}}}})(e)),(e=>{let{componentCls:t,iconSize:i,lineHeight:r,iconSizeSM:o}=e;return{[`&${t}-label-vertical`]:{[`${t}-item`]:{overflow:"visible","&-tail":{marginInlineStart:e.calc(i).div(2).add(e.controlHeightLG).equal(),padding:`0 ${(0,A.unit)(e.paddingLG)}`},"&-content":{display:"block",width:e.calc(i).div(2).add(e.controlHeightLG).mul(2).equal(),marginTop:e.marginSM,textAlign:"center"},"&-icon":{display:"inline-block",marginInlineStart:e.controlHeightLG},"&-title":{paddingInlineEnd:0,paddingInlineStart:0,"&::after":{display:"none"}},"&-subtitle":{display:"block",marginBottom:e.marginXXS,marginInlineStart:0,lineHeight:r}},[`&${t}-small:not(${t}-dot)`]:{[`${t}-item`]:{"&-icon":{marginInlineStart:e.calc(i).sub(o).div(2).add(e.controlHeightLG).equal()}}}}}})(e)),(e=>{let{componentCls:t,descriptionMaxWidth:i,lineHeight:r,dotCurrentSize:o,dotSize:a,motionDurationSlow:n}=e;return{[`&${t}-dot, &${t}-dot${t}-small`]:{[`${t}-item`]:{"&-title":{lineHeight:r},"&-tail":{top:e.calc(e.dotSize).sub(e.calc(e.lineWidth).mul(3).equal()).div(2).equal(),width:"100%",marginTop:0,marginBottom:0,marginInline:`${(0,A.unit)(e.calc(i).div(2).equal())} 0`,padding:0,"&::after":{width:`calc(100% - ${(0,A.unit)(e.calc(e.marginSM).mul(2).equal())})`,height:e.calc(e.lineWidth).mul(3).equal(),marginInlineStart:e.marginSM}},"&-icon":{width:a,height:a,marginInlineStart:e.calc(e.descriptionMaxWidth).sub(a).div(2).equal(),paddingInlineEnd:0,lineHeight:(0,A.unit)(a),background:"transparent",border:0,[`${t}-icon-dot`]:{position:"relative",float:"left",width:"100%",height:"100%",borderRadius:100,transition:`all ${n}`,"&::after":{position:"absolute",top:e.calc(e.marginSM).mul(-1).equal(),insetInlineStart:e.calc(a).sub(e.calc(e.controlHeightLG).mul(1.5).equal()).div(2).equal(),width:e.calc(e.controlHeightLG).mul(1.5).equal(),height:e.controlHeight,background:"transparent",content:'""'}}},"&-content":{width:i},[`&-process ${t}-item-icon`]:{position:"relative",top:e.calc(a).sub(o).div(2).equal(),width:o,height:o,lineHeight:(0,A.unit)(o),background:"none",marginInlineStart:e.calc(e.descriptionMaxWidth).sub(o).div(2).equal()},[`&-process ${t}-icon`]:{[`&:first-child ${t}-icon-dot`]:{insetInlineStart:0}}}},[`&${t}-vertical${t}-dot`]:{[`${t}-item-icon`]:{marginTop:e.calc(e.controlHeight).sub(a).div(2).equal(),marginInlineStart:0,background:"none"},[`${t}-item-process ${t}-item-icon`]:{marginTop:e.calc(e.controlHeight).sub(o).div(2).equal(),top:0,insetInlineStart:e.calc(a).sub(o).div(2).equal(),marginInlineStart:0},[`${t}-item > ${t}-item-container > ${t}-item-tail`]:{top:e.calc(e.controlHeight).sub(a).div(2).equal(),insetInlineStart:0,margin:0,padding:`${(0,A.unit)(e.calc(a).add(e.paddingXS).equal())} 0 ${(0,A.unit)(e.paddingXS)}`,"&::after":{marginInlineStart:e.calc(a).sub(e.lineWidth).div(2).equal()}},[`&${t}-small`]:{[`${t}-item-icon`]:{marginTop:e.calc(e.controlHeightSM).sub(a).div(2).equal()},[`${t}-item-process ${t}-item-icon`]:{marginTop:e.calc(e.controlHeightSM).sub(o).div(2).equal()},[`${t}-item > ${t}-item-container > ${t}-item-tail`]:{top:e.calc(e.controlHeightSM).sub(a).div(2).equal()}},[`${t}-item:first-child ${t}-icon-dot`]:{insetInlineStart:0},[`${t}-item-content`]:{width:"inherit"}}}})(e)),(e=>{let{componentCls:t,navContentMaxWidth:i,navArrowColor:r,stepsNavActiveColor:o,motionDurationSlow:a}=e;return{[`&${t}-navigation`]:{paddingTop:e.paddingSM,[`&${t}-small`]:{[`${t}-item`]:{"&-container":{marginInlineStart:e.calc(e.marginSM).mul(-1).equal()}}},[`${t}-item`]:{overflow:"visible",textAlign:"center","&-container":{display:"inline-block",height:"100%",marginInlineStart:e.calc(e.margin).mul(-1).equal(),paddingBottom:e.paddingSM,textAlign:"start",transition:`opacity ${a}`,[`${t}-item-content`]:{maxWidth:i},[`${t}-item-title`]:Object.assign(Object.assign({maxWidth:"100%",paddingInlineEnd:0},C.textEllipsis),{"&::after":{display:"none"}})},[`&:not(${t}-item-active)`]:{[`${t}-item-container[role='button']`]:{cursor:"pointer","&:hover":{opacity:.85}}},"&:last-child":{flex:1,"&::after":{display:"none"}},"&::after":{position:"absolute",top:`calc(50% - ${(0,A.unit)(e.calc(e.paddingSM).div(2).equal())})`,insetInlineStart:"100%",display:"inline-block",width:e.fontSizeIcon,height:e.fontSizeIcon,borderTop:`${(0,A.unit)(e.lineWidth)} ${e.lineType} ${r}`,borderBottom:"none",borderInlineStart:"none",borderInlineEnd:`${(0,A.unit)(e.lineWidth)} ${e.lineType} ${r}`,transform:"translateY(-50%) translateX(-50%) rotate(45deg)",content:'""'},"&::before":{position:"absolute",bottom:0,insetInlineStart:"50%",display:"inline-block",width:0,height:e.lineWidthBold,backgroundColor:o,transition:`width ${a}, inset-inline-start ${a}`,transitionTimingFunction:"ease-out",content:'""'}},[`${t}-item${t}-item-active::before`]:{insetInlineStart:0,width:"100%"}},[`&${t}-navigation${t}-vertical`]:{[`> ${t}-item`]:{marginInlineEnd:0,"&::before":{display:"none"},[`&${t}-item-active::before`]:{top:0,insetInlineEnd:0,insetInlineStart:"unset",display:"block",width:e.calc(e.lineWidth).mul(3).equal(),height:`calc(100% - ${(0,A.unit)(e.marginLG)})`},"&::after":{position:"relative",insetInlineStart:"50%",display:"block",width:e.calc(e.controlHeight).mul(.25).equal(),height:e.calc(e.controlHeight).mul(.25).equal(),marginBottom:e.marginXS,textAlign:"center",transform:"translateY(-50%) translateX(-50%) rotate(135deg)"},"&:last-child":{"&::after":{display:"none"}},[`> ${t}-item-container > ${t}-item-tail`]:{visibility:"hidden"}}},[`&${t}-navigation${t}-horizontal`]:{[`> ${t}-item > ${t}-item-container > ${t}-item-tail`]:{visibility:"hidden"}}}})(e)),(e=>{let{componentCls:t}=e;return{[`&${t}-rtl`]:{direction:"rtl",[`${t}-item`]:{"&-subtitle":{float:"left"}},[`&${t}-navigation`]:{[`${t}-item::after`]:{transform:"rotate(-45deg)"}},[`&${t}-vertical`]:{[`> ${t}-item`]:{"&::after":{transform:"rotate(225deg)"},[`${t}-item-icon`]:{float:"right"}}},[`&${t}-dot`]:{[`${t}-item-icon ${t}-icon-dot, &${t}-small ${t}-item-icon ${t}-icon-dot`]:{float:"right"}}}}})(e)),(e=>{let{antCls:t,componentCls:i,iconSize:r,iconSizeSM:o,processIconColor:a,marginXXS:n,lineWidthBold:l,lineWidth:s,paddingXXS:c}=e,d=e.calc(r).add(e.calc(l).mul(4).equal()).equal(),m=e.calc(o).add(e.calc(e.lineWidth).mul(4).equal()).equal();return{[`&${i}-with-progress`]:{[`${i}-item`]:{paddingTop:c,[`&-process ${i}-item-container ${i}-item-icon ${i}-icon`]:{color:a}},[`&${i}-vertical > ${i}-item `]:{paddingInlineStart:c,[`> ${i}-item-container > ${i}-item-tail`]:{top:n,insetInlineStart:e.calc(r).div(2).sub(s).add(c).equal()}},[`&, &${i}-small`]:{[`&${i}-horizontal ${i}-item:first-child`]:{paddingBottom:c,paddingInlineStart:c}},[`&${i}-small${i}-vertical > ${i}-item > ${i}-item-container > ${i}-item-tail`]:{insetInlineStart:e.calc(o).div(2).sub(s).add(c).equal()},[`&${i}-label-vertical ${i}-item ${i}-item-tail`]:{top:e.calc(r).div(2).add(c).equal()},[`${i}-item-icon`]:{position:"relative",[`${t}-progress`]:{position:"absolute",insetInlineStart:"50%",top:"50%",transform:"translate(-50%, -50%)","&-inner":{width:`${(0,A.unit)(d)} !important`,height:`${(0,A.unit)(d)} !important`}}},[`&${i}-small`]:{[`&${i}-label-vertical ${i}-item ${i}-item-tail`]:{top:e.calc(o).div(2).add(c).equal()},[`${i}-item-icon ${t}-progress-inner`]:{width:`${(0,A.unit)(m)} !important`,height:`${(0,A.unit)(m)} !important`}}}}})(e)),(e=>{let{componentCls:t,inlineDotSize:i,inlineTitleColor:r,inlineTailColor:o}=e,a=e.calc(e.paddingXS).add(e.lineWidth).equal(),n={[`${t}-item-container ${t}-item-content ${t}-item-title`]:{color:r}};return{[`&${t}-inline`]:{width:"auto",display:"inline-flex",[`${t}-item`]:{flex:"none","&-container":{padding:`${(0,A.unit)(a)} ${(0,A.unit)(e.paddingXXS)} 0`,margin:`0 ${(0,A.unit)(e.calc(e.marginXXS).div(2).equal())}`,borderRadius:e.borderRadiusSM,cursor:"pointer",transition:`background-color ${e.motionDurationMid}`,"&:hover":{background:e.controlItemBgHover},"&[role='button']:hover":{opacity:1}},"&-icon":{width:i,height:i,marginInlineStart:`calc(50% - ${(0,A.unit)(e.calc(i).div(2).equal())})`,[`> ${t}-icon`]:{top:0},[`${t}-icon-dot`]:{borderRadius:e.calc(e.fontSizeSM).div(4).equal(),"&::after":{display:"none"}}},"&-content":{width:"auto",marginTop:e.calc(e.marginXS).sub(e.lineWidth).equal()},"&-title":{color:r,fontSize:e.fontSizeSM,lineHeight:e.lineHeightSM,fontWeight:"normal",marginBottom:e.calc(e.marginXXS).div(2).equal()},"&-description":{display:"none"},"&-tail":{marginInlineStart:0,top:e.calc(i).div(2).add(a).equal(),transform:"translateY(-50%)","&:after":{width:"100%",height:e.lineWidth,borderRadius:0,marginInlineStart:0,background:o}},[`&:first-child ${t}-item-tail`]:{width:"50%",marginInlineStart:"50%"},[`&:last-child ${t}-item-tail`]:{display:"block",width:"50%"},"&-wait":Object.assign({[`${t}-item-icon ${t}-icon ${t}-icon-dot`]:{backgroundColor:e.colorBorderBg,border:`${(0,A.unit)(e.lineWidth)} ${e.lineType} ${o}`}},n),"&-finish":Object.assign({[`${t}-item-tail::after`]:{backgroundColor:o},[`${t}-item-icon ${t}-icon ${t}-icon-dot`]:{backgroundColor:o,border:`${(0,A.unit)(e.lineWidth)} ${e.lineType} ${o}`}},n),"&-error":n,"&-active, &-process":Object.assign({[`${t}-item-icon`]:{width:i,height:i,marginInlineStart:`calc(50% - ${(0,A.unit)(e.calc(i).div(2).equal())})`,top:0}},n),[`&:not(${t}-item-active) > ${t}-item-container[role='button']:hover`]:{[`${t}-item-title`]:{color:r}}}}}})(e))}})((0,w.mergeToken)(e,{processIconColor:r,processTitleColor:o,processDescriptionColor:o,processIconBgColor:a,processIconBorderColor:a,processDotColor:a,processTailColor:d,waitTitleColor:n,waitDescriptionColor:n,waitTailColor:d,waitDotColor:t,finishIconColor:a,finishTitleColor:o,finishDescriptionColor:n,finishTailColor:a,finishDotColor:a,errorIconColor:r,errorTitleColor:s,errorDescriptionColor:s,errorTailColor:d,errorIconBgColor:s,errorIconBorderColor:s,errorDotColor:s,stepsNavActiveColor:a,stepsProgressSize:i,inlineDotSize:6,inlineTitleColor:l,inlineTailColor:c}))},e=>({titleLineHeight:e.controlHeight,customIconSize:e.controlHeight,customIconTop:0,customIconFontSize:e.controlHeightSM,iconSize:e.controlHeight,iconTop:-.5,iconFontSize:e.fontSize,iconSizeSM:e.fontSizeHeading3,dotSize:e.controlHeight/4,dotCurrentSize:e.controlHeightLG/4,navArrowColor:e.colorTextDisabled,navContentMaxWidth:"unset",descriptionMaxWidth:140,waitIconColor:e.wireframe?e.colorTextDisabled:e.colorTextLabel,waitIconBgColor:e.wireframe?e.colorBgContainer:e.colorFillContent,waitIconBorderColor:e.wireframe?e.colorTextDisabled:"transparent",finishIconBgColor:e.wireframe?e.colorBgContainer:e.controlItemBgActive,finishIconBorderColor:e.wireframe?e.colorPrimary:e.controlItemBgActive}));var S=e.i(876556),E=function(e,t){var i={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&0>t.indexOf(r)&&(i[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,r=Object.getOwnPropertySymbols(e);ot.indexOf(r[o])&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(i[r[o]]=e[r[o]]);return i};let T=e=>{var a,n;let{percent:l,size:s,className:c,rootClassName:d,direction:m,items:g,responsive:u=!0,current:A=0,children:C,style:I}=e,w=E(e,["percent","size","className","rootClassName","direction","items","responsive","current","children","style"]),{xs:x}=(0,b.default)(u),{getPrefixCls:T,direction:O,className:y,style:N}=(0,h.useComponentConfig)("steps"),L=t.useMemo(()=>u&&x?"vertical":m,[u,x,m]),_=(0,f.default)(s),M=T("steps",e.prefixCls),[R,P,z]=k(M),H="inline"===e.type,j=T("",e.iconPrefix),D=(a=g,n=C,a?a:(0,S.default)(n).map(e=>{if(t.isValidElement(e)){let{props:t}=e;return Object.assign({},t)}return null}).filter(e=>e)),B=H?void 0:l,W=Object.assign(Object.assign({},N),I),q=(0,o.default)(y,{[`${M}-rtl`]:"rtl"===O,[`${M}-with-progress`]:void 0!==B},c,d,P,z),X={finish:t.createElement(i.default,{className:`${M}-finish-icon`}),error:t.createElement(r.default,{className:`${M}-error-icon`})};return R(t.createElement(p,Object.assign({icons:X},w,{style:W,current:A,size:_,items:D,itemRender:H?(e,i)=>e.description?t.createElement($.default,{title:e.description},i):i:void 0,stepIcon:({node:e,status:i})=>"process"===i&&void 0!==B?t.createElement("div",{className:`${M}-progress-icon`},t.createElement(v.default,{type:"circle",percent:B,size:"small"===_?32:40,strokeWidth:4,format:()=>null}),e):e,direction:L,prefixCls:M,iconPrefix:j,className:q})))};T.Step=p.Step,e.s(["Steps",0,T],280898)},86408,e=>{"use strict";var t=e.i(843476),i=e.i(271645),r=e.i(618566),o=e.i(934879);function a(){let e=(0,r.useSearchParams)().get("key"),[a,n]=(0,i.useState)(null);return(0,i.useEffect)(()=>{e&&n(e)},[e]),(0,t.jsx)(o.default,{accessToken:a,publicPage:!0,premiumUser:!1,userRole:null})}e.s(["default",0,function(){return(0,t.jsx)(i.Suspense,{fallback:(0,t.jsx)("div",{className:"flex items-center justify-center min-h-screen",children:"Loading..."}),children:(0,t.jsx)(a,{})})}])}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/00fcsizkvc4hx.js b/litellm/proxy/_experimental/out/_next/static/chunks/00fcsizkvc4hx.js new file mode 100644 index 00000000000..7875ab8fb17 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/00fcsizkvc4hx.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,728889,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(829087),s=e.i(480731),n=e.i(444755),l=e.i(673706),o=e.i(95779);let i={xs:{paddingX:"px-1.5",paddingY:"py-1.5"},sm:{paddingX:"px-1.5",paddingY:"py-1.5"},md:{paddingX:"px-2",paddingY:"py-2"},lg:{paddingX:"px-2",paddingY:"py-2"},xl:{paddingX:"px-2.5",paddingY:"py-2.5"}},c={xs:{height:"h-3",width:"w-3"},sm:{height:"h-5",width:"w-5"},md:{height:"h-5",width:"w-5"},lg:{height:"h-7",width:"w-7"},xl:{height:"h-9",width:"w-9"}},d={simple:{rounded:"",border:"",ring:"",shadow:""},light:{rounded:"rounded-tremor-default",border:"",ring:"",shadow:""},shadow:{rounded:"rounded-tremor-default",border:"border",ring:"",shadow:"shadow-tremor-card dark:shadow-dark-tremor-card"},solid:{rounded:"rounded-tremor-default",border:"border-2",ring:"ring-1",shadow:""},outlined:{rounded:"rounded-tremor-default",border:"border",ring:"ring-2",shadow:""}},u=(0,l.makeClassName)("Icon"),m=r.default.forwardRef((e,m)=>{let{icon:h,variant:p="simple",tooltip:g,size:f=s.Sizes.SM,color:x,className:b}=e,v=(0,t.__rest)(e,["icon","variant","tooltip","size","color","className"]),y=((e,t)=>{switch(e){case"simple":return{textColor:t?(0,l.getColorClassNames)(t,o.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:"",borderColor:"",ringColor:""};case"light":return{textColor:t?(0,l.getColorClassNames)(t,o.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,n.tremorTwMerge)((0,l.getColorClassNames)(t,o.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-brand-muted dark:bg-dark-tremor-brand-muted",borderColor:"",ringColor:""};case"shadow":return{textColor:t?(0,l.getColorClassNames)(t,o.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,n.tremorTwMerge)((0,l.getColorClassNames)(t,o.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:"border-tremor-border dark:border-dark-tremor-border",ringColor:""};case"solid":return{textColor:t?(0,l.getColorClassNames)(t,o.colorPalette.text).textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:t?(0,n.tremorTwMerge)((0,l.getColorClassNames)(t,o.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-brand dark:bg-dark-tremor-brand",borderColor:"border-tremor-brand-inverted dark:border-dark-tremor-brand-inverted",ringColor:"ring-tremor-ring dark:ring-dark-tremor-ring"};case"outlined":return{textColor:t?(0,l.getColorClassNames)(t,o.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,n.tremorTwMerge)((0,l.getColorClassNames)(t,o.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:t?(0,l.getColorClassNames)(t,o.colorPalette.ring).borderColor:"border-tremor-brand-subtle dark:border-dark-tremor-brand-subtle",ringColor:t?(0,n.tremorTwMerge)((0,l.getColorClassNames)(t,o.colorPalette.ring).ringColor,"ring-opacity-40"):"ring-tremor-brand-muted dark:ring-dark-tremor-brand-muted"}}})(p,x),{tooltipProps:C,getReferenceProps:w}=(0,a.useTooltip)();return r.default.createElement("span",Object.assign({ref:(0,l.mergeRefs)([m,C.refs.setReference]),className:(0,n.tremorTwMerge)(u("root"),"inline-flex shrink-0 items-center justify-center",y.bgColor,y.textColor,y.borderColor,y.ringColor,d[p].rounded,d[p].border,d[p].shadow,d[p].ring,i[f].paddingX,i[f].paddingY,b)},w,v),r.default.createElement(a.default,Object.assign({text:g},C)),r.default.createElement(h,{className:(0,n.tremorTwMerge)(u("icon"),"shrink-0",c[f].height,c[f].width)}))});m.displayName="Icon",e.s(["default",0,m],728889)},752978,e=>{"use strict";var t=e.i(728889);e.s(["Icon",()=>t.default])},278587,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"}))});e.s(["RefreshIcon",0,r],278587)},551332,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"}))});e.s(["ClipboardCopyIcon",0,r],551332)},439189,435684,96226,497245,e=>{"use strict";function t(e){let t=Object.prototype.toString.call(e);return e instanceof Date||"object"==typeof e&&"[object Date]"===t?new e.constructor(+e):new Date("number"==typeof e||"[object Number]"===t||"string"==typeof e||"[object String]"===t?e:NaN)}function r(e,t){return e instanceof Date?new e.constructor(t):new Date(t)}e.s(["toDate",0,t],435684),e.s(["constructFrom",0,r],96226),e.s(["addDays",0,function(e,a){let s=t(e);return isNaN(a)?r(e,NaN):(a&&s.setDate(s.getDate()+a),s)}],439189),e.s(["addMonths",0,function(e,a){let s=t(e);if(isNaN(a))return r(e,NaN);if(!a)return s;let n=s.getDate(),l=r(e,s.getTime());return(l.setMonth(s.getMonth()+a+1,0),n>=l.getDate())?l:(s.setFullYear(l.getFullYear(),l.getMonth(),n),s)}],497245)},888288,e=>{"use strict";var t=e.i(271645);e.s(["default",0,(e,r)=>{let a=void 0!==r,[s,n]=(0,t.useState)(e);return[a?r:s,e=>{a||n(e)}]}])},37091,e=>{"use strict";var t=e.i(290571),r=e.i(95779),a=e.i(444755),s=e.i(673706),n=e.i(271645);let l=n.default.forwardRef((e,l)=>{let{color:o,children:i,className:c}=e,d=(0,t.__rest)(e,["color","children","className"]);return n.default.createElement("p",Object.assign({ref:l,className:(0,a.tremorTwMerge)(o?(0,s.getColorClassNames)(o,r.colorPalette.lightText).textColor:"text-tremor-content-emphasis dark:text-dark-tremor-content-emphasis",c)},d),i)});l.displayName="Subtitle",e.s(["Subtitle",0,l],37091)},757440,e=>{"use strict";var t=e.i(290571),r=e.i(271645);e.s(["default",0,e=>{var a=(0,t.__rest)(e,[]);return r.default.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"},a),r.default.createElement("path",{d:"M11.9999 13.1714L16.9497 8.22168L18.3639 9.63589L11.9999 15.9999L5.63599 9.63589L7.0502 8.22168L11.9999 13.1714Z"}))}])},446428,854056,e=>{"use strict";let t;var r=e.i(290571),a=e.i(271645);e.s(["default",0,e=>{var t=(0,r.__rest)(e,[]);return a.default.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"},t),a.default.createElement("path",{d:"M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 10.5858L9.17157 7.75736L7.75736 9.17157L10.5858 12L7.75736 14.8284L9.17157 16.2426L12 13.4142L14.8284 16.2426L16.2426 14.8284L13.4142 12L16.2426 9.17157L14.8284 7.75736L12 10.5858Z"}))}],446428);var s=e.i(746725),n=e.i(914189),l=e.i(553521),o=e.i(835696),i=e.i(941444),c=e.i(178677),d=e.i(294316),u=e.i(83733),m=e.i(233137),h=e.i(732607),p=e.i(397701),g=e.i(700020);function f(e){var t;return!!(e.enter||e.enterFrom||e.enterTo||e.leave||e.leaveFrom||e.leaveTo)||(null!=(t=e.as)?t:w)!==a.Fragment||1===a.default.Children.count(e.children)}let x=(0,a.createContext)(null);x.displayName="TransitionContext";var b=((t=b||{}).Visible="visible",t.Hidden="hidden",t);let v=(0,a.createContext)(null);function y(e){return"children"in e?y(e.children):e.current.filter(({el:e})=>null!==e.current).filter(({state:e})=>"visible"===e).length>0}function C(e,t){let r=(0,i.useLatestValue)(e),o=(0,a.useRef)([]),c=(0,l.useIsMounted)(),d=(0,s.useDisposables)(),u=(0,n.useEvent)((e,t=g.RenderStrategy.Hidden)=>{let a=o.current.findIndex(({el:t})=>t===e);-1!==a&&((0,p.match)(t,{[g.RenderStrategy.Unmount](){o.current.splice(a,1)},[g.RenderStrategy.Hidden](){o.current[a].state="hidden"}}),d.microTask(()=>{var e;!y(o)&&c.current&&(null==(e=r.current)||e.call(r))}))}),m=(0,n.useEvent)(e=>{let t=o.current.find(({el:t})=>t===e);return t?"visible"!==t.state&&(t.state="visible"):o.current.push({el:e,state:"visible"}),()=>u(e,g.RenderStrategy.Unmount)}),h=(0,a.useRef)([]),f=(0,a.useRef)(Promise.resolve()),x=(0,a.useRef)({enter:[],leave:[]}),b=(0,n.useEvent)((e,r,a)=>{h.current.splice(0),t&&(t.chains.current[r]=t.chains.current[r].filter(([t])=>t!==e)),null==t||t.chains.current[r].push([e,new Promise(e=>{h.current.push(e)})]),null==t||t.chains.current[r].push([e,new Promise(e=>{Promise.all(x.current[r].map(([e,t])=>t)).then(()=>e())})]),"enter"===r?f.current=f.current.then(()=>null==t?void 0:t.wait.current).then(()=>a(r)):a(r)}),v=(0,n.useEvent)((e,t,r)=>{Promise.all(x.current[t].splice(0).map(([e,t])=>t)).then(()=>{var e;null==(e=h.current.shift())||e()}).then(()=>r(t))});return(0,a.useMemo)(()=>({children:o,register:m,unregister:u,onStart:b,onStop:v,wait:f,chains:x}),[m,u,o,b,v,x,f])}v.displayName="NestingContext";let w=a.Fragment,N=g.RenderFeatures.RenderStrategy,k=(0,g.forwardRefWithAs)(function(e,t){let{show:r,appear:s=!1,unmount:l=!0,...i}=e,u=(0,a.useRef)(null),h=f(e),p=(0,d.useSyncRefs)(...h?[u,t]:null===t?[]:[t]);(0,c.useServerHandoffComplete)();let b=(0,m.useOpenClosed)();if(void 0===r&&null!==b&&(r=(b&m.State.Open)===m.State.Open),void 0===r)throw Error("A is used but it is missing a `show={true | false}` prop.");let[w,k]=(0,a.useState)(r?"visible":"hidden"),S=C(()=>{r||k("hidden")}),[T,_]=(0,a.useState)(!0),E=(0,a.useRef)([r]);(0,o.useIsoMorphicEffect)(()=>{!1!==T&&E.current[E.current.length-1]!==r&&(E.current.push(r),_(!1))},[E,r]);let M=(0,a.useMemo)(()=>({show:r,appear:s,initial:T}),[r,s,T]);(0,o.useIsoMorphicEffect)(()=>{r?k("visible"):y(S)||null===u.current||k("hidden")},[r,S]);let R={unmount:l},P=(0,n.useEvent)(()=>{var t;T&&_(!1),null==(t=e.beforeEnter)||t.call(e)}),L=(0,n.useEvent)(()=>{var t;T&&_(!1),null==(t=e.beforeLeave)||t.call(e)}),A=(0,g.useRender)();return a.default.createElement(v.Provider,{value:S},a.default.createElement(x.Provider,{value:M},A({ourProps:{...R,as:a.Fragment,children:a.default.createElement(j,{ref:p,...R,...i,beforeEnter:P,beforeLeave:L})},theirProps:{},defaultTag:a.Fragment,features:N,visible:"visible"===w,name:"Transition"})))}),j=(0,g.forwardRefWithAs)(function(e,t){var r,s;let{transition:l=!0,beforeEnter:i,afterEnter:b,beforeLeave:k,afterLeave:j,enter:S,enterFrom:T,enterTo:_,entered:E,leave:M,leaveFrom:R,leaveTo:P,...L}=e,[A,I]=(0,a.useState)(null),O=(0,a.useRef)(null),F=f(e),D=(0,d.useSyncRefs)(...F?[O,t,I]:null===t?[]:[t]),H=null==(r=L.unmount)||r?g.RenderStrategy.Unmount:g.RenderStrategy.Hidden,{show:V,appear:B,initial:J}=function(){let e=(0,a.useContext)(x);if(null===e)throw Error("A is used but it is missing a parent or .");return e}(),[U,q]=(0,a.useState)(V?"visible":"hidden"),G=function(){let e=(0,a.useContext)(v);if(null===e)throw Error("A is used but it is missing a parent or .");return e}(),{register:z,unregister:W}=G;(0,o.useIsoMorphicEffect)(()=>z(O),[z,O]),(0,o.useIsoMorphicEffect)(()=>{if(H===g.RenderStrategy.Hidden&&O.current)return V&&"visible"!==U?void q("visible"):(0,p.match)(U,{hidden:()=>W(O),visible:()=>z(O)})},[U,O,z,W,V,H]);let Y=(0,c.useServerHandoffComplete)();(0,o.useIsoMorphicEffect)(()=>{if(F&&Y&&"visible"===U&&null===O.current)throw Error("Did you forget to passthrough the `ref` to the actual DOM node?")},[O,U,Y,F]);let X=J&&!B,Z=B&&V&&J,$=(0,a.useRef)(!1),K=C(()=>{$.current||(q("hidden"),W(O))},G),Q=(0,n.useEvent)(e=>{$.current=!0,K.onStart(O,e?"enter":"leave",e=>{"enter"===e?null==i||i():"leave"===e&&(null==k||k())})}),ee=(0,n.useEvent)(e=>{let t=e?"enter":"leave";$.current=!1,K.onStop(O,t,e=>{"enter"===e?null==b||b():"leave"===e&&(null==j||j())}),"leave"!==t||y(K)||(q("hidden"),W(O))});(0,a.useEffect)(()=>{F&&l||(Q(V),ee(V))},[V,F,l]);let et=!(!l||!F||!Y||X),[,er]=(0,u.useTransition)(et,A,V,{start:Q,end:ee}),ea=(0,g.compact)({ref:D,className:(null==(s=(0,h.classNames)(L.className,Z&&S,Z&&T,er.enter&&S,er.enter&&er.closed&&T,er.enter&&!er.closed&&_,er.leave&&M,er.leave&&!er.closed&&R,er.leave&&er.closed&&P,!er.transition&&V&&E))?void 0:s.trim())||void 0,...(0,u.transitionDataAttributes)(er)}),es=0;"visible"===U&&(es|=m.State.Open),"hidden"===U&&(es|=m.State.Closed),er.enter&&(es|=m.State.Opening),er.leave&&(es|=m.State.Closing);let en=(0,g.useRender)();return a.default.createElement(v.Provider,{value:K},a.default.createElement(m.OpenClosedProvider,{value:es},en({ourProps:ea,theirProps:L,defaultTag:w,features:N,visible:"visible"===U,name:"Transition.Child"})))}),S=(0,g.forwardRefWithAs)(function(e,t){let r=null!==(0,a.useContext)(x),s=null!==(0,m.useOpenClosed)();return a.default.createElement(a.default.Fragment,null,!r&&s?a.default.createElement(k,{ref:t,...e}):a.default.createElement(j,{ref:t,...e}))}),T=Object.assign(k,{Child:S,Root:k});e.s(["Transition",0,T],854056)},206929,e=>{"use strict";var t=e.i(290571),r=e.i(757440),a=e.i(271645),s=e.i(446428),n=e.i(444755),l=e.i(673706),o=e.i(103471),i=e.i(495470),c=e.i(854056),d=e.i(888288);let u=(0,l.makeClassName)("Select"),m=a.default.forwardRef((e,l)=>{let{defaultValue:m="",value:h,onValueChange:p,placeholder:g="Select...",disabled:f=!1,icon:x,enableClear:b=!1,required:v,children:y,name:C,error:w=!1,errorMessage:N,className:k,id:j}=e,S=(0,t.__rest)(e,["defaultValue","value","onValueChange","placeholder","disabled","icon","enableClear","required","children","name","error","errorMessage","className","id"]),T=(0,a.useRef)(null),_=a.Children.toArray(y),[E,M]=(0,d.default)(m,h),R=(0,a.useMemo)(()=>{let e=a.default.Children.toArray(y).filter(a.isValidElement);return(0,o.constructValueToNameMapping)(e)},[y]);return a.default.createElement("div",{className:(0,n.tremorTwMerge)("w-full min-w-[10rem] text-tremor-default",k)},a.default.createElement("div",{className:"relative"},a.default.createElement("select",{title:"select-hidden",required:v,className:(0,n.tremorTwMerge)("h-full w-full absolute left-0 top-0 -z-10 opacity-0"),value:E,onChange:e=>{e.preventDefault()},name:C,disabled:f,id:j,onFocus:()=>{let e=T.current;e&&e.focus()}},a.default.createElement("option",{className:"hidden",value:"",disabled:!0,hidden:!0},g),_.map(e=>{let t=e.props.value,r=e.props.children;return a.default.createElement("option",{className:"hidden",key:t,value:t},r)})),a.default.createElement(i.Listbox,Object.assign({as:"div",ref:l,defaultValue:E,value:E,onChange:e=>{null==p||p(e),M(e)},disabled:f,id:j},S),({value:e})=>{var t;return a.default.createElement(a.default.Fragment,null,a.default.createElement(i.ListboxButton,{ref:T,className:(0,n.tremorTwMerge)("w-full outline-none text-left whitespace-nowrap truncate rounded-tremor-default focus:ring-2 transition duration-100 border pr-8 py-2","border-tremor-border shadow-tremor-input focus:border-tremor-brand-subtle focus:ring-tremor-brand-muted","dark:border-dark-tremor-border dark:shadow-dark-tremor-input dark:focus:border-dark-tremor-brand-subtle dark:focus:ring-dark-tremor-brand-muted",x?"pl-10":"pl-3",(0,o.getSelectButtonColors)((0,o.hasValue)(e),f,w))},x&&a.default.createElement("span",{className:(0,n.tremorTwMerge)("absolute inset-y-0 left-0 flex items-center ml-px pl-2.5")},a.default.createElement(x,{className:(0,n.tremorTwMerge)(u("Icon"),"flex-none h-5 w-5","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")})),a.default.createElement("span",{className:"w-[90%] block truncate"},e&&null!=(t=R.get(e))?t:g),a.default.createElement("span",{className:(0,n.tremorTwMerge)("absolute inset-y-0 right-0 flex items-center mr-3")},a.default.createElement(r.default,{className:(0,n.tremorTwMerge)(u("arrowDownIcon"),"flex-none h-5 w-5","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")}))),b&&E?a.default.createElement("button",{type:"button",className:(0,n.tremorTwMerge)("absolute inset-y-0 right-0 flex items-center mr-8"),onClick:e=>{e.preventDefault(),M(""),null==p||p("")}},a.default.createElement(s.default,{className:(0,n.tremorTwMerge)(u("clearIcon"),"flex-none h-4 w-4","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")})):null,a.default.createElement(c.Transition,{enter:"transition ease duration-100 transform",enterFrom:"opacity-0 -translate-y-4",enterTo:"opacity-100 translate-y-0",leave:"transition ease duration-100 transform",leaveFrom:"opacity-100 translate-y-0",leaveTo:"opacity-0 -translate-y-4"},a.default.createElement(i.ListboxOptions,{anchor:"bottom start",className:(0,n.tremorTwMerge)("z-10 w-[var(--button-width)] divide-y overflow-y-auto outline-none rounded-tremor-default max-h-[228px] border [--anchor-gap:4px]","bg-tremor-background border-tremor-border divide-tremor-border shadow-tremor-dropdown","dark:bg-dark-tremor-background dark:border-dark-tremor-border dark:divide-dark-tremor-border dark:shadow-dark-tremor-dropdown")},y)))})),w&&N?a.default.createElement("p",{className:(0,n.tremorTwMerge)("errorMessage","text-sm text-rose-500 mt-1")},N):null)});m.displayName="Select",e.s(["Select",0,m],206929)},254709,e=>{"use strict";var t=e.i(843476),r=e.i(584935),a=e.i(304967),s=e.i(309426),n=e.i(350967),l=e.i(752978),o=e.i(621642),i=e.i(25080),c=e.i(37091),d=e.i(197647),u=e.i(653824),m=e.i(881073),h=e.i(404206),p=e.i(723731),g=e.i(599724),f=e.i(271645),x=e.i(727749),b=e.i(144267),v=e.i(278587),y=e.i(602869),C=e.i(994388),w=e.i(220508),N=e.i(964306),k=e.i(551332);let j=({responseTimeMs:e})=>null==e?null:(0,t.jsxs)("div",{className:"flex items-center space-x-1 text-xs text-gray-500 font-mono",children:[(0,t.jsx)("svg",{className:"w-4 h-4",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:(0,t.jsx)("path",{d:"M12 6V12L16 14M12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2Z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})}),(0,t.jsxs)("span",{children:[e.toFixed(0),"ms"]})]}),S=e=>{let t=e;if("string"==typeof t)try{t=JSON.parse(t)}catch{}return t},T=({label:e,value:r})=>{let[a,s]=f.default.useState(!1),[n,l]=f.default.useState(!1),o=r?.toString()||"N/A",i=o.length>50?o.substring(0,50)+"...":o;return(0,t.jsx)("tr",{className:"hover:bg-gray-50",children:(0,t.jsx)("td",{className:"px-4 py-2 align-top",colSpan:2,children:(0,t.jsxs)("div",{className:"flex items-center justify-between group",children:[(0,t.jsxs)("div",{className:"flex items-center flex-1",children:[(0,t.jsx)("button",{onClick:()=>s(!a),className:"text-gray-400 hover:text-gray-600 mr-2",children:a?"▼":"▶"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-sm text-gray-600",children:e}),(0,t.jsx)("pre",{className:"mt-1 text-sm font-mono text-gray-800 whitespace-pre-wrap",children:a?o:i})]})]}),(0,t.jsx)("button",{onClick:()=>{navigator.clipboard.writeText(o),l(!0),setTimeout(()=>l(!1),2e3)},className:"opacity-0 group-hover:opacity-100 text-gray-400 hover:text-gray-600",children:(0,t.jsx)(k.ClipboardCopyIcon,{className:"h-4 w-4"})})]})})})},_=({response:e})=>{let r=null,a={},s={};try{if(e?.error)try{let t="string"==typeof e.error.message?JSON.parse(e.error.message):e.error.message;r={message:t?.message||"Unknown error",traceback:t?.traceback||"No traceback available",litellm_params:t?.litellm_cache_params||{},health_check_cache_params:t?.health_check_cache_params||{}},a=S(r.litellm_params)||{},s=S(r.health_check_cache_params)||{}}catch(t){console.warn("Error parsing error details:",t),r={message:String(e.error.message||"Unknown error"),traceback:"Error parsing details",litellm_params:{},health_check_cache_params:{}}}else a=S(e?.litellm_cache_params)||{},s=S(e?.health_check_cache_params)||{}}catch(e){console.warn("Error in response parsing:",e),a={},s={}}let n={redis_host:s?.redis_client?.connection_pool?.connection_kwargs?.host||s?.redis_async_client?.connection_pool?.connection_kwargs?.host||s?.connection_kwargs?.host||s?.host||"N/A",redis_port:s?.redis_client?.connection_pool?.connection_kwargs?.port||s?.redis_async_client?.connection_pool?.connection_kwargs?.port||s?.connection_kwargs?.port||s?.port||"N/A",redis_version:s?.redis_version||"N/A",startup_nodes:(()=>{try{if(s?.redis_kwargs?.startup_nodes)return JSON.stringify(s.redis_kwargs.startup_nodes);let e=s?.redis_client?.connection_pool?.connection_kwargs?.host||s?.redis_async_client?.connection_pool?.connection_kwargs?.host,t=s?.redis_client?.connection_pool?.connection_kwargs?.port||s?.redis_async_client?.connection_pool?.connection_kwargs?.port;return e&&t?JSON.stringify([{host:e,port:t}]):"N/A"}catch(e){return"N/A"}})(),namespace:s?.namespace||"N/A"};return(0,t.jsx)("div",{className:"bg-white rounded-lg shadow-sm",children:(0,t.jsxs)(u.TabGroup,{children:[(0,t.jsxs)(m.TabList,{className:"border-b border-gray-200 px-4",children:[(0,t.jsx)(d.Tab,{className:"px-4 py-2 text-sm font-medium text-gray-600 hover:text-gray-800",children:"Summary"}),(0,t.jsx)(d.Tab,{className:"px-4 py-2 text-sm font-medium text-gray-600 hover:text-gray-800",children:"Raw Response"})]}),(0,t.jsxs)(p.TabPanels,{children:[(0,t.jsx)(h.TabPanel,{className:"p-4",children:(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center mb-6",children:[e?.status==="healthy"?(0,t.jsx)(w.CheckCircleIcon,{className:"h-5 w-5 text-green-500 mr-2"}):(0,t.jsx)(N.XCircleIcon,{className:"h-5 w-5 text-red-500 mr-2"}),(0,t.jsxs)(g.Text,{className:`text-sm font-medium ${e?.status==="healthy"?"text-green-500":"text-red-500"}`,children:["Cache Status: ",e?.status||"unhealthy"]})]}),(0,t.jsx)("table",{className:"w-full border-collapse",children:(0,t.jsxs)("tbody",{children:[r&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("tr",{children:(0,t.jsx)("td",{colSpan:2,className:"pt-4 pb-2 font-semibold text-red-600",children:"Error Details"})}),(0,t.jsx)(T,{label:"Error Message",value:r.message}),(0,t.jsx)(T,{label:"Traceback",value:r.traceback})]}),(0,t.jsx)("tr",{children:(0,t.jsx)("td",{colSpan:2,className:"pt-4 pb-2 font-semibold",children:"Cache Details"})}),(0,t.jsx)(T,{label:"Cache Configuration",value:String(a?.type)}),(0,t.jsx)(T,{label:"Ping Response",value:String(e.ping_response)}),(0,t.jsx)(T,{label:"Set Cache Response",value:e.set_cache_response||"N/A"}),(0,t.jsx)(T,{label:"litellm_settings.cache_params",value:JSON.stringify(a,null,2)}),a?.type==="redis"&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("tr",{children:(0,t.jsx)("td",{colSpan:2,className:"pt-4 pb-2 font-semibold",children:"Redis Details"})}),(0,t.jsx)(T,{label:"Redis Host",value:n.redis_host||"N/A"}),(0,t.jsx)(T,{label:"Redis Port",value:n.redis_port||"N/A"}),(0,t.jsx)(T,{label:"Redis Version",value:n.redis_version||"N/A"}),(0,t.jsx)(T,{label:"Startup Nodes",value:n.startup_nodes||"N/A"}),(0,t.jsx)(T,{label:"Namespace",value:n.namespace||"N/A"})]})]})})]})}),(0,t.jsx)(h.TabPanel,{className:"p-4",children:(0,t.jsx)("div",{className:"bg-gray-50 rounded-md p-4 font-mono text-sm",children:(0,t.jsx)("pre",{className:"whitespace-pre-wrap wrap-break-word overflow-auto max-h-[500px]",children:(()=>{try{let t={...e,litellm_cache_params:a,health_check_cache_params:s},r=JSON.parse(JSON.stringify(t,(e,t)=>{if("string"==typeof t)try{return JSON.parse(t)}catch{}return t}));return JSON.stringify(r,null,2)}catch(e){return"Error formatting JSON: "+e.message}})()})})})]})]})})},E=({accessToken:e,healthCheckResponse:r,runCachingHealthCheck:a,responseTimeMs:s})=>{let[n,l]=f.default.useState(null),[o,i]=f.default.useState(!1),c=async()=>{i(!0);let e=performance.now();await a(),l(performance.now()-e),i(!1)};return(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between",children:[(0,t.jsx)(C.Button,{onClick:c,disabled:o,className:"bg-indigo-600 hover:bg-indigo-700 disabled:bg-indigo-400 text-white text-sm px-4 py-2 rounded-md",children:o?"Running Health Check...":"Run Health Check"}),(0,t.jsx)(j,{responseTimeMs:n})]}),r&&(0,t.jsx)(_,{response:r})]})};var M=e.i(677667),R=e.i(898667),P=e.i(130643),L=e.i(808613),A=e.i(695411),I=e.i(206929),O=e.i(35983);let F=({redisType:e,redisTypeDescriptions:r,onTypeChange:a})=>(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Redis Type"}),(0,t.jsxs)(I.Select,{value:e,onValueChange:a,children:[(0,t.jsx)(O.SelectItem,{value:"node",children:"Node (Single Instance)"}),(0,t.jsx)(O.SelectItem,{value:"cluster",children:"Cluster"}),(0,t.jsx)(O.SelectItem,{value:"sentinel",children:"Sentinel"}),(0,t.jsx)(O.SelectItem,{value:"semantic",children:"Semantic"})]}),(0,t.jsx)("p",{className:"text-xs text-gray-500",children:r[e]||"Select the type of Redis deployment you're using"})]});var D=e.i(311451),H=e.i(199133),V=e.i(790848);let B=({field:e,embeddingModels:r})=>(0,t.jsx)(L.Form.Item,{name:e.name,label:e.label,extra:e.helpText,rules:e.rules,valuePropName:"boolean"===e.type?"checked":"value",children:((e,r)=>{switch(e.type){case"boolean":return(0,t.jsx)(V.Switch,{});case"password":return(0,t.jsx)(D.Input.Password,{placeholder:e.helpText,autoComplete:"new-password"});case"integer":case"float":return(0,t.jsx)(D.Input,{inputMode:"decimal",placeholder:e.helpText});case"list":return(0,t.jsx)(D.Input.TextArea,{rows:4,placeholder:e.helpText});case"model-select":return(0,t.jsx)(H.Select,{showSearch:!0,allowClear:!0,placeholder:"Search and select a model...",options:r,optionFilterProp:"label",style:{width:"100%"}});default:return(0,t.jsx)(D.Input,{placeholder:e.helpText})}})(e,r)}),J=["node","cluster","sentinel","semantic"],U={node:"Standard Redis node/single instance",cluster:"Redis Cluster mode for high availability and horizontal scaling",sentinel:"Redis Sentinel mode for high availability with automatic failover",semantic:"Semantic caching that reuses responses for similar prompts"},q={validator:(e,t)=>{let r;if(null==t||""===String(t).trim())return Promise.resolve();try{r=JSON.parse(String(t))}catch{return Promise.reject(Error("Must be a valid JSON array (use double quotes)"))}return Array.isArray(r)?Promise.resolve():Promise.reject(Error("Must be a JSON array"))}},G={validator:(e,t)=>{if(null==t||""===String(t).trim())return Promise.resolve();let r=Number(t);return!Number.isInteger(r)||r<0?Promise.reject(Error("Must be a non-negative integer")):Promise.resolve()}},z={validator:(e,t)=>null==t||""===String(t).trim()?Promise.resolve():Number.isNaN(Number(t))?Promise.reject(Error("Must be a number")):Promise.resolve()},W=[{name:"url",label:"Redis URL",type:"string",section:"connection",helpText:"Full Redis/Valkey connection URL (e.g. redis://:password@host:6379/1). When set, it takes precedence over Host, Port, Password, and Database Index.",redisType:null},{name:"host",label:"Host",type:"string",section:"connection",helpText:"Redis server hostname or IP address",redisType:null},{name:"port",label:"Port",type:"string",section:"connection",helpText:"Redis server port number",redisType:null,defaultValue:"6379",rules:[{validator:(e,t)=>{if(null==t||""===String(t).trim())return Promise.resolve();let r=Number(t);return!Number.isInteger(r)||r<1||r>65535?Promise.reject(Error("Port must be an integer between 1 and 65535")):Promise.resolve()}}]},{name:"db",label:"Database Index",type:"integer",section:"connection",helpText:"Logical database index to isolate the cache (e.g. 1 for redis://host:6379/1)",redisType:null,rules:[G]},{name:"password",label:"Password",type:"password",section:"connection",helpText:"Redis server password",redisType:null},{name:"username",label:"Username",type:"string",section:"connection",helpText:"Redis server username (if required)",redisType:null},{name:"redis_startup_nodes",label:"Startup Nodes",type:"list",section:"cluster",helpText:'List of startup nodes for Redis Cluster (e.g., [{"host": "127.0.0.1", "port": "7001"}])',redisType:"cluster",rules:[q]},{name:"sentinel_nodes",label:"Sentinel Nodes",type:"list",section:"sentinel",helpText:'List of Sentinel nodes (e.g., [["localhost", 26379]])',redisType:"sentinel",rules:[q]},{name:"service_name",label:"Service Name",type:"string",section:"sentinel",helpText:"Master service name for Redis Sentinel",redisType:"sentinel"},{name:"sentinel_password",label:"Sentinel Password",type:"password",section:"sentinel",helpText:"Password for Redis Sentinel authentication",redisType:"sentinel"},{name:"similarity_threshold",label:"Similarity Threshold",type:"float",section:"semantic",helpText:"Similarity threshold for semantic cache",redisType:"semantic",defaultValue:.8,rules:[z]},{name:"redis_semantic_cache_embedding_model",label:"Embedding Model",type:"model-select",section:"semantic",helpText:"Embedding model for semantic cache",redisType:"semantic"},{name:"ssl",label:"SSL",type:"boolean",section:"ssl",helpText:"Enable SSL/TLS connection",redisType:null,defaultValue:!1},{name:"ssl_cert_reqs",label:"SSL Cert Reqs",type:"string",section:"ssl",helpText:"SSL certificate requirements (None, CERT_REQUIRED, CERT_OPTIONAL)",redisType:null},{name:"ssl_check_hostname",label:"SSL Check Hostname",type:"boolean",section:"ssl",helpText:"Enable SSL hostname verification",redisType:null,defaultValue:!1},{name:"namespace",label:"Namespace",type:"string",section:"cacheManagement",helpText:"Namespace prefix for cache keys",redisType:null},{name:"ttl",label:"TTL (seconds)",type:"float",section:"cacheManagement",helpText:"Time-to-live for cached items in seconds",redisType:null,rules:[z]},{name:"max_connections",label:"Max Connections",type:"integer",section:"cacheManagement",helpText:"Maximum number of connections in the connection pool",redisType:null,rules:[G]},{name:"gcp_service_account",label:"GCP Service Account",type:"string",section:"gcp",helpText:"GCP service account for IAM authentication (e.g., projects/-/serviceAccounts/your-sa@project.iam.gserviceaccount.com)",redisType:null},{name:"gcp_ssl_ca_certs",label:"GCP SSL CA Certs",type:"string",section:"gcp",helpText:"Path to SSL CA certificate file for GCP Memorystore Redis",redisType:null}],Y=(e,t)=>null===e.redisType||e.redisType===t,X=(e,t,{forTesting:r})=>({type:r||"semantic"!==e?"redis":"redis-semantic",...Object.fromEntries(W.filter(t=>Y(t,e)).flatMap(e=>{let r=((e,t)=>{if("boolean"===e.type)return!!t;if("list"===e.type){if("string"!=typeof t||""===t.trim())return;try{return JSON.parse(t)}catch{return}}if("integer"===e.type||"float"===e.type){if(null==t||""===t)return;let e=Number(t);return Number.isNaN(e)?void 0:e}if("string"!=typeof t)return void 0===t?void 0:String(t);let r=t.trim();return""===r?void 0:r})(e,t[e.name]);return void 0===r?[]:[[e.name,r]]}))}),Z=({title:e,section:r,redisType:a,embeddingModels:s,gridCols:n="grid-cols-1 gap-6 sm:grid-cols-2",headingLevel:l="h4"})=>{let o=W.filter(e=>e.section===r&&Y(e,a));return 0===o.length?null:(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsx)(l,{className:"text-sm font-medium text-gray-900",children:e}),(0,t.jsx)("div",{className:`grid ${n}`,children:o.map(e=>(0,t.jsx)(B,{field:e,embeddingModels:s},e.name))})]})},$=e=>J.includes(e)?e:"node",K=({accessToken:e})=>{let[r]=L.Form.useForm(),[a,s]=(0,f.useState)("node"),[n,l]=(0,f.useState)([]),[o,i]=(0,f.useState)(!1),[c,d]=(0,f.useState)(!1),u=(0,f.useCallback)(async()=>{if(e)try{let t=(await (0,y.getCacheSettingsCall)(e)).current_values??{};r.setFieldsValue(Object.fromEntries(W.map(e=>{let r;return[e.name,(r=t[e.name]??e.defaultValue,"boolean"===e.type?!0===r||"true"===r:"list"===e.type?null==r||""===r?"":"string"==typeof r?r:JSON.stringify(r,null,2):null==r?"":String(r))]}))),s($(t.redis_type))}catch(e){console.error("Failed to load cache settings:",e),x.default.fromBackend("Failed to load cache settings")}},[e,r]);(0,f.useEffect)(()=>{u()},[u]),(0,f.useEffect)(()=>{e&&(0,A.fetchAvailableModels)(e).then(e=>l(e.filter(e=>"embedding"===e.mode).map(e=>({value:e.model_group,label:e.model_group})))).catch(e=>console.error("Error fetching embedding models:",e))},[e]);let m=async()=>{try{return await r.validateFields()}catch{return null}},h=async()=>{if(!e)return;let t=await m();if(null!==t){i(!0);try{let r=await (0,y.testCacheConnectionCall)(e,X(a,t,{forTesting:!0}));"success"===r.status?x.default.success("Cache connection test successful!"):x.default.fromBackend(`Connection test failed: ${r.message||r.error}`)}catch(e){console.error("Test connection error:",e),x.default.fromBackend(`Connection test failed: ${e instanceof Error?e.message:"Unknown error"}`)}finally{i(!1)}}},p=async()=>{if(!e)return;let t=await m();if(null!==t){d(!0);try{await (0,y.updateCacheSettingsCall)(e,X(a,t,{forTesting:!1})),x.default.success("Cache settings updated successfully"),await u()}catch(e){console.error("Failed to save cache settings:",e),x.default.fromBackend("Failed to update cache settings")}finally{d(!1)}}};return e?(0,t.jsxs)("div",{className:"w-full space-y-8 py-2",children:[(0,t.jsxs)(L.Form,{form:r,layout:"vertical",requiredMark:!1,className:"space-y-6",children:[(0,t.jsxs)("div",{className:"max-w-3xl",children:[(0,t.jsx)("h3",{className:"text-sm font-medium text-gray-900",children:"Cache Settings"}),(0,t.jsx)("p",{className:"text-xs text-gray-500 mt-1",children:"Configure Redis cache for LiteLLM"})]}),(0,t.jsx)(F,{redisType:a,redisTypeDescriptions:U,onTypeChange:e=>s($(e))}),(0,t.jsx)("div",{className:"pt-4 border-t border-gray-200",children:(0,t.jsx)(Z,{title:"Connection Settings",section:"connection",redisType:a,embeddingModels:n})}),"cluster"===a&&(0,t.jsx)("div",{className:"pt-4 border-t border-gray-200",children:(0,t.jsx)(Z,{title:"Cluster Configuration",section:"cluster",redisType:a,embeddingModels:n,gridCols:"grid-cols-1 gap-6"})}),"sentinel"===a&&(0,t.jsx)("div",{className:"pt-4 border-t border-gray-200",children:(0,t.jsx)(Z,{title:"Sentinel Configuration",section:"sentinel",redisType:a,embeddingModels:n})}),"semantic"===a&&(0,t.jsx)("div",{className:"pt-4 border-t border-gray-200",children:(0,t.jsx)(Z,{title:"Semantic Configuration",section:"semantic",redisType:a,embeddingModels:n})}),(0,t.jsxs)(M.Accordion,{className:"mt-4",children:[(0,t.jsx)(R.AccordionHeader,{children:(0,t.jsx)("span",{className:"text-sm font-medium text-gray-900",children:"Advanced Settings"})}),(0,t.jsx)(P.AccordionBody,{children:(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsx)(Z,{title:"SSL Settings",section:"ssl",redisType:a,embeddingModels:n,headingLevel:"h5"}),(0,t.jsx)(Z,{title:"Cache Management",section:"cacheManagement",redisType:a,embeddingModels:n,headingLevel:"h5"}),(0,t.jsx)(Z,{title:"GCP Authentication",section:"gcp",redisType:a,embeddingModels:n,headingLevel:"h5"})]})})]})]}),(0,t.jsxs)("div",{className:"border-t border-gray-200 pt-6 flex justify-end gap-3",children:[(0,t.jsx)(C.Button,{variant:"secondary",size:"sm",onClick:h,disabled:o,className:"text-sm",children:o?"Testing...":"Test Connection"}),(0,t.jsx)(C.Button,{size:"sm",onClick:p,disabled:c,className:"text-sm font-medium",children:c?"Saving...":"Save Changes"})]})]}):null},Q=e=>{if(e)return e.toISOString().split("T")[0]};function ee(e){return new Intl.NumberFormat("en-US",{maximumFractionDigits:0,notation:"compact",compactDisplay:"short"}).format(e)}let et=({accessToken:e,token:C,userRole:w,userID:N,premiumUser:k})=>{let[j,S]=(0,f.useState)([]),[T,_]=(0,f.useState)([]),[M,R]=(0,f.useState)([]),[P,L]=(0,f.useState)([]),[A,I]=(0,f.useState)("0"),[O,F]=(0,f.useState)("0"),[D,H]=(0,f.useState)("0"),[V,B]=(0,f.useState)({from:new Date(Date.now()-6048e5),to:new Date}),[J,U]=(0,f.useState)(""),[q,G]=(0,f.useState)("");(0,f.useEffect)(()=>{e&&V&&((async()=>{L(await (0,y.adminGlobalCacheActivity)(e,Q(V.from),Q(V.to)))})(),U(new Date().toLocaleString()))},[e]);let z=Array.from(new Set(P.map(e=>e?.api_key??""))),W=Array.from(new Set(P.map(e=>e?.model??"")));Array.from(new Set(P.map(e=>e?.call_type??"")));let Y=async(t,r)=>{t&&r&&e&&L(await (0,y.adminGlobalCacheActivity)(e,Q(t),Q(r)))};(0,f.useEffect)(()=>{let e=P;T.length>0&&(e=e.filter(e=>T.includes(e.api_key))),M.length>0&&(e=e.filter(e=>M.includes(e.model)));let t=0,r=0,a=0,s=e.reduce((e,s)=>{s.call_type||(s.call_type="Unknown"),t+=(s.total_rows||0)-(s.cache_hit_true_rows||0),r+=s.cache_hit_true_rows||0,a+=s.cached_completion_tokens||0;let n=e.find(e=>e.name===s.call_type);return n?(n["LLM API requests"]+=(s.total_rows||0)-(s.cache_hit_true_rows||0),n["Cache hit"]+=s.cache_hit_true_rows||0,n["Cached Completion Tokens"]+=s.cached_completion_tokens||0,n["Generated Completion Tokens"]+=s.generated_completion_tokens||0):e.push({name:s.call_type,"LLM API requests":(s.total_rows||0)-(s.cache_hit_true_rows||0),"Cache hit":s.cache_hit_true_rows||0,"Cached Completion Tokens":s.cached_completion_tokens||0,"Generated Completion Tokens":s.generated_completion_tokens||0}),e},[]);I(ee(r)),F(ee(a));let n=r+t;n>0?H((r/n*100).toFixed(2)):H("0"),S(s)},[T,M,V,P]);let X=async()=>{try{x.default.info("Running cache health check..."),G("");let t=await (0,y.cachingHealthCheckCall)(null!==e?e:"");G(t)}catch(t){let e;if(console.error("Error running health check:",t),t&&t.message)try{let r=JSON.parse(t.message);r.error&&(r=r.error),e=r}catch(r){e={message:t.message}}else e={message:"Unknown error occurred"};G({error:e})}};return(0,t.jsxs)(u.TabGroup,{className:"gap-2 p-8 h-full w-full mt-2 mb-8",children:[(0,t.jsxs)(m.TabList,{className:"flex justify-between mt-2 w-full items-center",children:[(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)(d.Tab,{children:"Cache Analytics"}),(0,t.jsx)(d.Tab,{children:"Cache Health"}),(0,t.jsx)(d.Tab,{children:"Cache Settings"})]}),(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[J&&(0,t.jsxs)(g.Text,{children:["Last Refreshed: ",J]}),(0,t.jsx)(l.Icon,{icon:v.RefreshIcon,variant:"shadow",size:"xs",className:"self-center",onClick:()=>{U(new Date().toLocaleString())}})]})]}),(0,t.jsxs)(p.TabPanels,{children:[(0,t.jsx)(h.TabPanel,{children:(0,t.jsxs)(a.Card,{children:[(0,t.jsxs)(n.Grid,{numItems:3,className:"gap-4 mt-4",children:[(0,t.jsx)(s.Col,{children:(0,t.jsx)(o.MultiSelect,{placeholder:"Select Virtual Keys",value:T,onValueChange:_,children:z.map(e=>(0,t.jsx)(i.MultiSelectItem,{value:e,children:e},e))})}),(0,t.jsx)(s.Col,{children:(0,t.jsx)(o.MultiSelect,{placeholder:"Select Models",value:M,onValueChange:R,children:W.map(e=>(0,t.jsx)(i.MultiSelectItem,{value:e,children:e},e))})}),(0,t.jsx)(s.Col,{children:(0,t.jsx)(b.default,{value:V,onValueChange:e=>{B(e),Y(e.from,e.to)}})})]}),(0,t.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-4",children:[(0,t.jsxs)(a.Card,{children:[(0,t.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Cache Hit Ratio"}),(0,t.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,t.jsxs)("p",{className:"text-tremor-metric font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:[D,"%"]})})]}),(0,t.jsxs)(a.Card,{children:[(0,t.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Cache Hits"}),(0,t.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,t.jsx)("p",{className:"text-tremor-metric font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:A})})]}),(0,t.jsxs)(a.Card,{children:[(0,t.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Cached Tokens"}),(0,t.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,t.jsx)("p",{className:"text-tremor-metric font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:O})})]})]}),(0,t.jsx)(c.Subtitle,{className:"mt-4",children:"Cache Hits vs API Requests"}),(0,t.jsx)(r.BarChart,{title:"Cache Hits vs API Requests",data:j,stack:!0,index:"name",valueFormatter:ee,categories:["LLM API requests","Cache hit"],colors:["sky","teal"],yAxisWidth:48}),(0,t.jsx)(c.Subtitle,{className:"mt-4",children:"Cached Completion Tokens vs Generated Completion Tokens"}),(0,t.jsx)(r.BarChart,{className:"mt-6",data:j,stack:!0,index:"name",valueFormatter:ee,categories:["Generated Completion Tokens","Cached Completion Tokens"],colors:["sky","teal"],yAxisWidth:48})]})}),(0,t.jsx)(h.TabPanel,{children:(0,t.jsx)(E,{accessToken:e,healthCheckResponse:q,runCachingHealthCheck:X})}),(0,t.jsx)(h.TabPanel,{children:(0,t.jsx)(K,{accessToken:e,userRole:w,userID:N})})]})]})};var er=e.i(135214);e.s(["default",0,function(){let{accessToken:e,userRole:r,userId:a,token:s,premiumUser:n}=(0,er.default)();return(0,t.jsx)(et,{userID:a,userRole:r,token:s,accessToken:e,premiumUser:n})}],254709)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/00pr1xqcusy8a.js b/litellm/proxy/_experimental/out/_next/static/chunks/00pr1xqcusy8a.js new file mode 100644 index 00000000000..a6f74b19695 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/00pr1xqcusy8a.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,207082,e=>{"use strict";var t=e.i(619273),s=e.i(266027),l=e.i(243652),a=e.i(602869),r=e.i(431703),i=e.i(135214);let n=(0,l.createQueryKeys)("keys"),o=async(e,t,s,l={})=>{try{let i=(0,a.getProxyBaseUrl)(),n=new URLSearchParams(Object.entries({team_id:l.teamID,project_id:l.projectID,agent_id:l.agentID,organization_id:l.organizationID,key_alias:l.selectedKeyAlias,key_hash:l.keyHash,user_id:l.userID,page:t,size:s,sort_by:l.sortBy,sort_order:l.sortOrder,expand:l.expand,status:l.status,return_full_object:"true",include_team_keys:"true",include_created_by_keys:"true",substring_matching:"true"}).filter(([,e])=>null!=e).map(([e,t])=>[e,String(t)])),o=`${i?`${i}/key/list`:"/key/list"}?${n}`,d=await fetch(o,{method:"GET",headers:{[(0,a.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!d.ok){let e=await d.json(),t=(0,r.deriveErrorMessage)(e);throw(0,a.handleError)(t),Error(t)}return await d.json()}catch(e){throw console.error("Failed to list keys:",e),e}},d=(0,l.createQueryKeys)("deletedKeys");e.s(["keyKeys",0,n,"useDeletedKeys",0,(e,l,a={})=>{let{accessToken:r}=(0,i.default)();return(0,s.useQuery)({queryKey:d.list({page:e,limit:l,...a}),queryFn:async()=>await o(r,e,l,{...a,status:"deleted"}),enabled:!!r,staleTime:3e4,placeholderData:t.keepPreviousData})},"useKeys",0,(e,l,a={})=>{let{accessToken:r}=(0,i.default)();return(0,s.useQuery)({queryKey:n.list({page:e,limit:l,...a}),queryFn:async()=>await o(r,e,l,a),enabled:!!r,staleTime:3e4,placeholderData:t.keepPreviousData})}])},510674,e=>{"use strict";var t=e.i(266027),s=e.i(243652),l=e.i(602869),a=e.i(431703),r=e.i(135214),i=e.i(708347);let n=(0,s.createQueryKeys)("projects"),o=[...i.all_admin_roles,...i.internalUserRoles],d=async e=>{let t=(0,l.getProxyBaseUrl)(),s=`${t}/project/list`,r=await fetch(s,{method:"GET",headers:{[(0,l.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!r.ok){let e=await r.json(),t=(0,a.deriveErrorMessage)(e);throw(0,l.handleError)(t),Error(t)}return r.json()};e.s(["projectKeys",0,n,"useProjects",0,()=>{let{accessToken:e,userRole:s}=(0,r.default)();return(0,t.useQuery)({queryKey:n.list({}),queryFn:async()=>d(e),enabled:!!e&&o.includes(s)})}])},557662,e=>{"use strict";let t="/ui/assets/logos/",s=[{id:"arize",displayName:"Arize",logo:`${t}arize.png`,supports_key_team_logging:!0,dynamic_params:{arize_api_key:"password",arize_space_id:"password"},description:"Arize Logging Integration"},{id:"braintrust",displayName:"Braintrust",logo:`${t}braintrust.png`,supports_key_team_logging:!1,dynamic_params:{braintrust_api_key:"password",braintrust_project_name:"text"},description:"Braintrust Logging Integration"},{id:"custom_callback_api",displayName:"Custom Callback API",logo:`${t}custom.svg`,supports_key_team_logging:!0,dynamic_params:{custom_callback_api_url:"text",custom_callback_api_headers:"text"},description:"Custom Callback API Logging Integration"},{id:"galileo",displayName:"Galileo",logo:`${t}galileo.ico`,supports_key_team_logging:!1,dynamic_params:{GALILEO_API_KEY:"password",GALILEO_PROJECT_ID:"text",GALILEO_LOG_STREAM_ID:"text",GALILEO_BASE_URL:"text",GALILEO_USERNAME:"text",GALILEO_PASSWORD:"password"},description:"Galileo AI Observability Integration"},{id:"datadog",displayName:"Datadog",logo:`${t}datadog.png`,supports_key_team_logging:!1,dynamic_params:{dd_api_key:"password",dd_site:"text"},description:"Datadog Logging Integration"},{id:"lago",displayName:"Lago",logo:`${t}lago.svg`,supports_key_team_logging:!1,dynamic_params:{lago_api_url:"text",lago_api_key:"password"},description:"Lago Billing Logging Integration"},{id:"langfuse",displayName:"Langfuse",logo:`${t}langfuse.png`,supports_key_team_logging:!0,dynamic_params:{langfuse_public_key:"text",langfuse_secret_key:"password",langfuse_host:"text"},description:"Langfuse v2 Logging Integration"},{id:"langfuse_otel",displayName:"Langfuse OTEL",logo:`${t}langfuse.png`,supports_key_team_logging:!0,dynamic_params:{langfuse_public_key:"text",langfuse_secret_key:"password",langfuse_host:"text"},description:"Langfuse v3 OTEL Logging Integration"},{id:"langsmith",displayName:"LangSmith",logo:`${t}langsmith.png`,supports_key_team_logging:!0,dynamic_params:{langsmith_api_key:"password",langsmith_project:"text",langsmith_base_url:"text",langsmith_sampling_rate:"number"},description:"Langsmith Logging Integration"},{id:"openmeter",displayName:"OpenMeter",logo:`${t}openmeter.png`,supports_key_team_logging:!1,dynamic_params:{openmeter_api_key:"password",openmeter_base_url:"text"},description:"OpenMeter Logging Integration"},{id:"otel",displayName:"Open Telemetry",logo:`${t}otel.png`,supports_key_team_logging:!1,dynamic_params:{otel_endpoint:"text",otel_headers:"text"},description:"OpenTelemetry Logging Integration"},{id:"s3",displayName:"S3",logo:`${t}aws.svg`,supports_key_team_logging:!1,dynamic_params:{s3_bucket_name:"text",aws_access_key_id:"password",aws_secret_access_key:"password",aws_region:"text"},description:"S3 Bucket (AWS) Logging Integration"},{id:"SQS",displayName:"SQS",logo:`${t}aws.svg`,supports_key_team_logging:!1,dynamic_params:{sqs_queue_url:"text",aws_access_key_id:"password",aws_secret_access_key:"password",aws_region:"text"},description:"SQS Queue (AWS) Logging Integration"}],l=s.reduce((e,t)=>(e[t.displayName]=t,e),{}),a=s.reduce((e,t)=>(e[t.displayName]=t.id,e),{}),r=s.reduce((e,t)=>(e[t.id]=t.displayName,e),{});e.s(["callbackInfo",0,l,"callback_map",0,a,"mapDisplayToInternalNames",0,e=>e.map(e=>a[e]||e),"mapInternalToDisplayNames",0,e=>e.map(e=>r[e]||e),"reverse_callback_map",0,r])},810757,477386,e=>{"use strict";var t=e.i(271645);let s=t.forwardRef(function(e,s){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:s},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"}),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"}))});e.s(["CogIcon",0,s],810757);let l=t.forwardRef(function(e,s){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:s},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"}))});e.s(["BanIcon",0,l],477386)},552130,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(199133),a=e.i(602869);e.s(["default",0,({onChange:e,value:r,className:i,accessToken:n,placeholder:o="Select agents",disabled:d=!1})=>{let[c,u]=(0,s.useState)([]),[m,p]=(0,s.useState)([]),[g,h]=(0,s.useState)(!1);(0,s.useEffect)(()=>{(async()=>{if(n){h(!0);try{let e=await (0,a.getAgentsList)(n),t=e?.agents||[];u(t);let s=new Set;t.forEach(e=>{let t=e.agent_access_groups;t&&Array.isArray(t)&&t.forEach(e=>s.add(e))}),p(Array.from(s))}catch(e){console.error("Error fetching agents:",e)}finally{h(!1)}}})()},[n]);let x=[...m.map(e=>({label:e,value:`group:${e}`,isAccessGroup:!0,searchText:`${e} Access Group`})),...c.map(e=>({label:`${e.agent_name||e.agent_id}`,value:e.agent_id,isAccessGroup:!1,searchText:`${e.agent_name||e.agent_id} ${e.agent_id} Agent`}))],y=[...r?.agents||[],...(r?.accessGroups||[]).map(e=>`group:${e}`)];return(0,t.jsx)("div",{children:(0,t.jsx)(l.Select,{mode:"multiple",placeholder:o,onChange:t=>{e({agents:t.filter(e=>!e.startsWith("group:")),accessGroups:t.filter(e=>e.startsWith("group:")).map(e=>e.replace("group:",""))})},value:y,loading:g,className:i,allowClear:!0,showSearch:!0,style:{width:"100%"},disabled:d,filterOption:(e,t)=>(x.find(e=>e.value===t?.value)?.searchText||"").toLowerCase().includes(e.toLowerCase()),children:x.map(e=>(0,t.jsx)(l.Select.Option,{value:e.value,label:e.label,children:(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[(0,t.jsx)("span",{style:{display:"inline-block",width:8,height:8,borderRadius:"50%",background:e.isAccessGroup?"#52c41a":"#722ed1",flexShrink:0}}),(0,t.jsx)("span",{style:{flex:1},children:e.label}),(0,t.jsx)("span",{style:{color:e.isAccessGroup?"#52c41a":"#722ed1",fontSize:"12px",fontWeight:500,opacity:.8},children:e.isAccessGroup?"Access Group":"Agent"})]})},e.value))})})}])},9314,e=>{"use strict";var t=e.i(843476),s=e.i(199133),l=e.i(981339),a=e.i(645526),r=e.i(599724),i=e.i(263147);e.s(["default",0,({value:e,onChange:n,placeholder:o="Select access groups",disabled:d=!1,style:c,className:u,showLabel:m=!1,labelText:p="Access Group",allowClear:g=!0})=>{let{data:h,isLoading:x,isError:y}=(0,i.useAccessGroups)();if(x)return(0,t.jsxs)("div",{children:[m&&(0,t.jsxs)(r.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,t.jsx)(a.TeamOutlined,{className:"mr-2"})," ",p]}),(0,t.jsx)(l.Skeleton.Input,{active:!0,block:!0,style:{height:32,...c}})]});let f=(h??[]).map(e=>({label:(0,t.jsxs)("span",{children:[(0,t.jsx)("span",{className:"font-medium",children:e.access_group_name})," ",(0,t.jsxs)("span",{className:"text-gray-400 text-xs",children:["(",e.access_group_id,")"]})]}),value:e.access_group_id,selectedLabel:e.access_group_name,searchText:`${e.access_group_name} ${e.access_group_id}`}));return(0,t.jsxs)("div",{children:[m&&(0,t.jsxs)(r.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,t.jsx)(a.TeamOutlined,{className:"mr-2"})," ",p]}),(0,t.jsx)(s.Select,{mode:"multiple",value:e,placeholder:o,onChange:n,disabled:d,allowClear:g,showSearch:!0,style:{width:"100%",...c},className:`rounded-md ${u??""}`,notFoundContent:y?(0,t.jsx)("span",{className:"text-red-500",children:"Failed to load access groups"}):"No access groups found",filterOption:(e,t)=>(f.find(e=>e.value===t?.value)?.searchText??"").toLowerCase().includes(e.toLowerCase()),optionLabelProp:"selectedLabel",options:f.map(e=>({label:e.label,value:e.value,selectedLabel:e.selectedLabel}))})]})}])},392110,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(199133),a=e.i(592968),r=e.i(312361),i=e.i(790848),n=e.i(536916),o=e.i(827252),d=e.i(779241);let{Option:c}=l.Select;e.s(["default",0,({form:e,autoRotationEnabled:u,onAutoRotationChange:m,rotationInterval:p,onRotationIntervalChange:g,isCreateMode:h=!1,neverExpire:x=!1,onNeverExpireChange:y})=>{let f=p&&!["7d","30d","90d","180d","365d"].includes(p),[b,_]=(0,s.useState)(f),[j,v]=(0,s.useState)(f?p:""),[w,N]=(0,s.useState)(e?.getFieldValue?.("duration")||"");return(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Key Expiry Settings"}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,t.jsx)("span",{children:"Expire Key"}),(0,t.jsx)(a.Tooltip,{title:"Set when this key should expire. Format: 30s (seconds), 30m (minutes), 30h (hours), 30d (days). Leave empty to keep the current expiry unchanged.",children:(0,t.jsx)(o.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})}),!h&&y&&(0,t.jsx)(n.Checkbox,{checked:x,onChange:t=>{let s=t.target.checked;y(s),s&&(N(""),e&&"function"==typeof e.setFieldValue?e.setFieldValue("duration",""):e&&"function"==typeof e.setFieldsValue&&e.setFieldsValue({duration:""}))},className:"ml-2 text-sm font-normal text-gray-600",children:"Never Expire"})]}),(0,t.jsx)(d.TextInput,{name:"duration",placeholder:h?"e.g., 30d or leave empty to never expire":"e.g., 30d",className:"w-full",value:w,onValueChange:t=>{N(t),e&&"function"==typeof e.setFieldValue?e.setFieldValue("duration",t):e&&"function"==typeof e.setFieldsValue&&e.setFieldsValue({duration:t})},disabled:!h&&x})]})]}),(0,t.jsx)(r.Divider,{}),(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Auto-Rotation Settings"}),(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,t.jsx)("span",{children:"Enable Auto-Rotation"}),(0,t.jsx)(a.Tooltip,{title:"Key will automatically regenerate at the specified interval for enhanced security.",children:(0,t.jsx)(o.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})})]}),(0,t.jsx)(i.Switch,{checked:u,onChange:m,size:"default",className:u?"":"bg-gray-400"})]}),u&&(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,t.jsx)("span",{children:"Rotation Interval"}),(0,t.jsx)(a.Tooltip,{title:"How often the key should be automatically rotated. Choose the interval that best fits your security requirements.",children:(0,t.jsx)(o.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)(l.Select,{value:b?"custom":p,onChange:e=>{"custom"===e?_(!0):(_(!1),v(""),g(e))},className:"w-full",placeholder:"Select interval",children:[(0,t.jsx)(c,{value:"7d",children:"7 days"}),(0,t.jsx)(c,{value:"30d",children:"30 days"}),(0,t.jsx)(c,{value:"90d",children:"90 days"}),(0,t.jsx)(c,{value:"180d",children:"180 days"}),(0,t.jsx)(c,{value:"365d",children:"365 days"}),(0,t.jsx)(c,{value:"custom",children:"Custom interval"})]}),b&&(0,t.jsxs)("div",{className:"space-y-1",children:[(0,t.jsx)(d.TextInput,{value:j,onChange:e=>{let t=e.target.value;v(t),g(t)},placeholder:"e.g., 1s, 5m, 2h, 14d"}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Supported formats: seconds (s), minutes (m), hours (h), days (d)"})]})]})]})]}),u&&(0,t.jsx)("div",{className:"bg-blue-50 p-3 rounded-md text-sm text-blue-700",children:"When rotation occurs, you'll receive a notification with the new key. The old key will be deactivated after a brief grace period."})]})]})}])},844565,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(199133),a=e.i(602869);e.s(["default",0,({onChange:e,value:r,className:i,accessToken:n,placeholder:o="Select pass through routes",disabled:d=!1,teamId:c})=>{let[u,m]=(0,s.useState)([]),[p,g]=(0,s.useState)(!1);return(0,s.useEffect)(()=>{(async()=>{if(n){g(!0);try{let e=await (0,a.getPassThroughEndpointsCall)(n,c);if(e.endpoints){let t=e.endpoints.flatMap(e=>{let t=e.path,s=e.methods;return s&&s.length>0?s.map(e=>({label:`${e} ${t}`,value:t})):[{label:t,value:t}]});m(t)}}catch(e){console.error("Error fetching pass through routes:",e)}finally{g(!1)}}})()},[n,c]),(0,t.jsx)(l.Select,{mode:"tags",placeholder:o,onChange:e,value:r,loading:p,className:i,allowClear:!0,options:u,optionFilterProp:"label",showSearch:!0,style:{width:"100%"},disabled:d})}])},939510,e=>{"use strict";var t=e.i(843476),s=e.i(808613),l=e.i(199133),a=e.i(592968),r=e.i(827252);let{Option:i}=l.Select;e.s(["default",0,({type:e,name:n,showDetailedDescriptions:o=!0,className:d="",initialValue:c=null,form:u,onChange:m})=>{let p=e.toUpperCase(),g=e.toLowerCase(),h=`Select 'guaranteed_throughput' to prevent overallocating ${p} limit when the key belongs to a Team with specific ${p} limits.`;return(0,t.jsx)(s.Form.Item,{label:(0,t.jsxs)("span",{children:[p," Rate Limit Type"," ",(0,t.jsx)(a.Tooltip,{title:h,children:(0,t.jsx)(r.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:n,initialValue:c,className:d,children:(0,t.jsx)(l.Select,{defaultValue:o?"default":void 0,placeholder:"Select rate limit type",style:{width:"100%"},optionLabelProp:o?"label":void 0,onChange:e=>{u&&u.setFieldValue(n,e),m&&m(e)},children:o?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i,{value:"best_effort_throughput",label:"Default",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)("div",{style:{fontWeight:500},children:"Default"}),(0,t.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["Best effort throughput - no error if we're overallocating ",g," (Team/Key Limits checked at runtime)."]})]})}),(0,t.jsx)(i,{value:"guaranteed_throughput",label:"Guaranteed throughput",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)("div",{style:{fontWeight:500},children:"Guaranteed throughput"}),(0,t.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["Guaranteed throughput - raise an error if we're overallocating ",g," (also checks model-specific limits)"]})]})}),(0,t.jsx)(i,{value:"dynamic",label:"Dynamic",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)("div",{style:{fontWeight:500},children:"Dynamic"}),(0,t.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["If the key has a set ",p," (e.g. 2 ",p,") and there are no 429 errors, it can dynamically exceed the limit when the model being called is not erroring."]})]})})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i,{value:"best_effort_throughput",children:"Best effort throughput"}),(0,t.jsx)(i,{value:"guaranteed_throughput",children:"Guaranteed throughput"}),(0,t.jsx)(i,{value:"dynamic",children:"Dynamic"})]})})})}])},363256,e=>{"use strict";var t=e.i(843476),s=e.i(199133);let{Text:l}=e.i(898586).Typography;e.s(["default",0,({organizations:e,value:a,onChange:r,disabled:i,loading:n,style:o})=>(0,t.jsx)(s.Select,{showSearch:!0,placeholder:"All Organizations",value:a,onChange:r,disabled:i,loading:n,allowClear:!0,style:{minWidth:280,...o},filterOption:(t,s)=>{if(!s)return!1;let l=e?.find(e=>e.organization_id===s.key);if(!l)return!1;let a=t.toLowerCase().trim(),r=(l.organization_alias||"").toLowerCase(),i=(l.organization_id||"").toLowerCase();return r.includes(a)||i.includes(a)},children:e?.map(e=>(0,t.jsxs)(s.Select.Option,{value:e.organization_id,children:[(0,t.jsx)("span",{className:"font-medium",children:e.organization_alias})," ",(0,t.jsxs)(l,{type:"secondary",children:["(",e.organization_id,")"]})]},e.organization_id))})])},128233,319312,e=>{"use strict";var t=e.i(843476),s=e.i(464571),l=e.i(199133),a=e.i(592968),r=e.i(425063),i=e.i(107233),n=e.i(37727),o=e.i(271645);e.s(["BudgetFallbacksEditor",0,function({value:e,onChange:d,availableModels:c}){let[u,m]=(0,o.useState)(()=>{let t;return 0===(t=Object.keys(e)).length?[]:t.map((t,s)=>({id:String(s+1),primaryModel:t,fallbackModels:e[t]}))}),p=e=>{m(e),d(Object.fromEntries(e.filter(e=>null!==e.primaryModel&&e.fallbackModels.length>0).map(e=>[e.primaryModel,e.fallbackModels])))},g=()=>{p([...u,{id:Date.now().toString(),primaryModel:null,fallbackModels:[]}])},h=(e,t)=>{p(u.map(s=>s.id===e?{...s,...t}:s))},x=new Set(u.map(e=>e.primaryModel).filter(Boolean));return 0===u.length?(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-xs text-gray-500 mb-2",children:"When a model exceeds its per-model budget, requests automatically reroute to fallback models"}),(0,t.jsx)(s.Button,{size:"small",onClick:g,icon:(0,t.jsx)(i.Plus,{className:"w-3 h-3"}),children:"Add Budget Fallback"})]}):(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"When a model exceeds its per-model budget, requests automatically reroute to fallback models"}),u.map(e=>{let s=c.filter(t=>t===e.primaryModel||!x.has(t)),i=c.filter(t=>t!==e.primaryModel);return(0,t.jsxs)("div",{className:"relative rounded-lg border border-gray-200 bg-gray-50 p-4",children:[(0,t.jsx)("button",{type:"button",onClick:()=>{var t;return t=e.id,void p(u.filter(e=>e.id!==t))},className:"absolute top-2 right-2 text-gray-400 hover:text-red-500 transition-colors p-1",children:(0,t.jsx)(n.X,{className:"w-4 h-4"})}),(0,t.jsxs)("div",{className:"mb-3",children:[(0,t.jsx)("label",{className:"block text-xs font-medium text-gray-600 mb-1",children:"Primary Model"}),(0,t.jsx)(l.Select,{className:"w-full",placeholder:"Select model",value:e.primaryModel,onChange:t=>{let s=e.fallbackModels.filter(e=>e!==t);h(e.id,{primaryModel:t,fallbackModels:s})},showSearch:!0,filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase()),options:s.map(e=>({label:e,value:e})),getPopupContainer:e=>e.parentElement||document.body})]}),(0,t.jsx)("div",{className:"flex items-center justify-center -my-1 mb-2",children:(0,t.jsxs)("div",{className:"bg-amber-50 text-amber-600 px-3 py-0.5 rounded-full text-[10px] font-bold border border-amber-100 flex items-center gap-1",children:[(0,t.jsx)(r.ArrowDown,{className:"w-3 h-3"}),"IF BUDGET EXCEEDED, TRY"]})}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs font-medium text-gray-600 mb-1",children:"Fallback Models"}),(0,t.jsx)(l.Select,{mode:"multiple",className:"w-full",placeholder:e.primaryModel?"Select fallback models":"Select a primary model first",value:e.fallbackModels,onChange:t=>h(e.id,{fallbackModels:t}),disabled:!e.primaryModel,showSearch:!0,filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase()),options:i.map(e=>({label:e,value:e})),getPopupContainer:e=>e.parentElement||document.body,maxTagCount:"responsive",maxTagPlaceholder:e=>(0,t.jsx)(a.Tooltip,{styles:{root:{pointerEvents:"none"}},title:e.map(({value:e})=>e).join(", "),children:(0,t.jsxs)("span",{children:["+",e.length," more"]})})}),e.fallbackModels.length>1&&(0,t.jsx)("div",{className:"text-[10px] text-gray-400 mt-1 ml-1",children:"Tried in order; first model still within its own budget is used"})]})]},e.id)}),(0,t.jsx)(s.Button,{size:"small",onClick:g,icon:(0,t.jsx)(i.Plus,{className:"w-3 h-3"}),children:"Add Budget Fallback"})]})}],128233);var d=e.i(28651);let c=[{value:"1h",label:"Hourly",resetHint:"Resets every hour"},{value:"24h",label:"Daily",resetHint:"Resets daily at midnight UTC"},{value:"7d",label:"Weekly",resetHint:"Resets every Sunday at midnight UTC"},{value:"30d",label:"Monthly",resetHint:"Resets on the 1st of every month at midnight UTC"}];e.s(["BudgetWindowsEditor",0,function({value:e,onChange:a}){let r=(t,s,l)=>{a(e.map((e,a)=>a===t?{...e,[s]:l}:e))};return(0,t.jsxs)("div",{children:[e.map((i,n)=>{let o=c.find(e=>e.value===i.budget_duration)?.resetHint;return(0,t.jsxs)("div",{style:{marginBottom:12},children:[(0,t.jsxs)("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[(0,t.jsx)(l.Select,{value:i.budget_duration,onChange:e=>r(n,"budget_duration",e),style:{width:130},options:c.map(e=>({value:e.value,label:e.label}))}),(0,t.jsx)(d.InputNumber,{step:.01,min:0,precision:2,value:i.max_budget??void 0,onChange:e=>r(n,"max_budget",e??null),placeholder:"Max spend ($)",style:{width:160},prefix:"$"}),(0,t.jsx)(s.Button,{type:"text",danger:!0,size:"small",onClick:()=>{a(e.filter((e,t)=>t!==n))},style:{padding:"0 4px"},children:"✕"})]}),o&&(0,t.jsxs)("div",{style:{fontSize:11,color:"#888",marginTop:3,marginLeft:2},children:["↻ ",o]})]},n)}),(0,t.jsx)(s.Button,{size:"small",onClick:t=>{t.preventDefault(),a([...e,{budget_duration:"24h",max_budget:null}])},children:"+ Add Budget Window"})]})}],319312)},390605,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(602869),a=e.i(599724),r=e.i(482725),i=e.i(91739),n=e.i(500727),o=e.i(531516),d=e.i(696609);e.s(["default",0,({accessToken:e,selectedServers:c,toolPermissions:u,onChange:m,disabled:p=!1})=>{let{data:g=[]}=(0,n.useMCPServers)(),[h,x]=(0,s.useState)({}),[y,f]=(0,s.useState)({}),[b,_]=(0,s.useState)({}),[j,v]=(0,s.useState)({}),w=(0,s.useRef)(u);(0,s.useEffect)(()=>{w.current=u},[u]);let N=(0,s.useMemo)(()=>0===c.length?[]:g.filter(e=>c.includes(e.server_id)),[g,c]),k=async(e,t)=>{f(t=>({...t,[e]:!0})),_(t=>({...t,[e]:""}));try{let s=await (0,l.listMCPTools)(t,e);if(s.error)_(t=>({...t,[e]:s.message||"Failed to fetch tools"})),x(t=>({...t,[e]:[]}));else{let t=s.tools||[];x(s=>({...s,[e]:t}));let l=w.current;if(!l[e]&&t.length>0){let s=t.filter(e=>"delete"!==(0,d.classifyToolOp)(e.name,e.description||"")).map(e=>e.name);m({...l,[e]:s})}}}catch(t){console.error(`Error fetching tools for server ${e}:`,t),_(t=>({...t,[e]:"Failed to fetch tools"})),x(t=>({...t,[e]:[]}))}finally{f(t=>({...t,[e]:!1}))}};(0,s.useEffect)(()=>{N.forEach(t=>{h[t.server_id]||y[t.server_id]||k(t.server_id,e)})},[N,e]);let S=(e,t)=>{m({...u,[e]:t})};return 0===c.length?null:(0,t.jsx)("div",{className:"space-y-4",children:N.map(e=>{let s=e.server_name||e.alias||e.server_id,l=h[e.server_id]||[],n=u[e.server_id]||[],d=y[e.server_id],c=b[e.server_id],g=j[e.server_id]??"crud";return(0,t.jsxs)("div",{className:"border rounded-lg bg-gray-50",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between p-4 border-b bg-white rounded-t-lg",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(a.Text,{className:"font-semibold text-gray-900",children:s}),e.description&&(0,t.jsx)(a.Text,{className:"text-sm text-gray-500",children:e.description})]}),(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[!p&&l.length>0&&(0,t.jsx)(i.Radio.Group,{value:g,onChange:t=>v(s=>({...s,[e.server_id]:t.target.value})),size:"small",optionType:"button",buttonStyle:"solid",options:[{label:"Risk Groups",value:"crud"},{label:"Flat List",value:"flat"}]}),!p&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("button",{type:"button",className:"text-sm text-blue-600 hover:text-blue-700 font-medium",onClick:()=>{var t;let s;return s=h[t=e.server_id]||[],void m({...u,[t]:s.map(e=>e.name)})},disabled:d,children:"Select All"}),(0,t.jsx)("button",{type:"button",className:"text-sm text-blue-600 hover:text-blue-700 font-medium",onClick:()=>{var t;return t=e.server_id,void m({...u,[t]:[]})},disabled:d,children:"Deselect All"})]})]})]}),(0,t.jsxs)("div",{className:"p-4",children:[d&&(0,t.jsxs)("div",{className:"flex items-center justify-center py-8",children:[(0,t.jsx)(r.Spin,{size:"large"}),(0,t.jsx)(a.Text,{className:"ml-3 text-gray-500",children:"Loading tools..."})]}),c&&!d&&(0,t.jsxs)("div",{className:"p-4 bg-red-50 border border-red-200 rounded-lg text-center",children:[(0,t.jsx)(a.Text,{className:"text-red-600 font-medium",children:"Unable to load tools"}),(0,t.jsx)(a.Text,{className:"text-sm text-red-500 mt-1",children:c})]}),!d&&!c&&l.length>0&&"crud"===g&&(0,t.jsx)(o.default,{tools:l,value:u[e.server_id]?n:void 0,onChange:t=>S(e.server_id,t),readOnly:p}),!d&&!c&&l.length>0&&"flat"===g&&(0,t.jsx)("div",{className:"space-y-2",children:l.map(s=>{let l=n.includes(s.name);return(0,t.jsxs)("div",{className:"flex items-start gap-2",children:[(0,t.jsx)("input",{type:"checkbox",checked:l,onChange:()=>{if(p)return;let t=l?n.filter(e=>e!==s.name):[...n,s.name];S(e.server_id,t)},disabled:p,className:"mt-0.5"}),(0,t.jsx)("div",{className:"flex-1 min-w-0",children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(a.Text,{className:"font-medium text-gray-900",children:s.name}),(0,t.jsxs)(a.Text,{className:"text-sm text-gray-500",children:["- ",s.description||"No description"]})]})})]},s.name)})}),!d&&!c&&0===l.length&&(0,t.jsx)("div",{className:"text-center py-6",children:(0,t.jsx)(a.Text,{className:"text-gray-500",children:"No tools available"})})]})]},e.server_id)})})}])},109034,e=>{"use strict";var t=e.i(266027),s=e.i(243652),l=e.i(602869),a=e.i(135214);let r=(0,s.createQueryKeys)("tags");e.s(["useTags",0,()=>{let{accessToken:e,userId:s,userRole:i}=(0,a.default)();return(0,t.useQuery)({queryKey:r.list({}),queryFn:async()=>await (0,l.tagListCall)(e),enabled:!!(e&&s&&i)})}])},533882,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(250980),a=e.i(797672),r=e.i(68155),i=e.i(304967),n=e.i(629569),o=e.i(599724),d=e.i(269200),c=e.i(427612),u=e.i(64848),m=e.i(942232),p=e.i(496020),g=e.i(977572),h=e.i(992619),x=e.i(727749);e.s(["default",0,({accessToken:e,initialModelAliases:y={},onAliasUpdate:f,showExampleConfig:b=!0})=>{let[_,j]=(0,s.useState)([]),[v,w]=(0,s.useState)({aliasName:"",targetModel:""}),[N,k]=(0,s.useState)(null);(0,s.useEffect)(()=>{j(Object.entries(y).map(([e,t],s)=>({id:`${s}-${e}`,aliasName:e,targetModel:t})))},[y]);let S=()=>{if(!N)return;if(!N.aliasName||!N.targetModel)return void x.default.fromBackend("Please provide both alias name and target model");if(_.some(e=>e.id!==N.id&&e.aliasName===N.aliasName))return void x.default.fromBackend("An alias with this name already exists");let e=_.map(e=>e.id===N.id?N:e);j(e),k(null);let t={};e.forEach(e=>{t[e.aliasName]=e.targetModel}),f&&f(t),x.default.success("Alias updated successfully")},C=()=>{k(null)},T=_.reduce((e,t)=>(e[t.aliasName]=t.targetModel,e),{});return(0,t.jsxs)("div",{className:"mt-4",children:[(0,t.jsxs)("div",{className:"mb-6",children:[(0,t.jsx)(o.Text,{className:"text-sm font-medium text-gray-700 mb-2",children:"Add New Alias"}),(0,t.jsxs)("div",{className:"grid grid-cols-3 gap-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Alias Name"}),(0,t.jsx)("input",{type:"text",value:v.aliasName,onChange:e=>w({...v,aliasName:e.target.value}),placeholder:"e.g., gpt-4o",className:"w-full px-3 py-2 border border-gray-300 rounded-md text-sm"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Target Model"}),(0,t.jsx)(h.default,{accessToken:e,value:v.targetModel,placeholder:"Select target model",onChange:e=>w({...v,targetModel:e}),showLabel:!1})]}),(0,t.jsx)("div",{className:"flex items-end",children:(0,t.jsxs)("button",{onClick:()=>{if(!v.aliasName||!v.targetModel)return void x.default.fromBackend("Please provide both alias name and target model");if(_.some(e=>e.aliasName===v.aliasName))return void x.default.fromBackend("An alias with this name already exists");let e=[..._,{id:`${Date.now()}-${v.aliasName}`,aliasName:v.aliasName,targetModel:v.targetModel}];j(e),w({aliasName:"",targetModel:""});let t={};e.forEach(e=>{t[e.aliasName]=e.targetModel}),f&&f(t),x.default.success("Alias added successfully")},disabled:!v.aliasName||!v.targetModel,className:`flex items-center px-4 py-2 rounded-md text-sm ${!v.aliasName||!v.targetModel?"bg-gray-300 text-gray-500 cursor-not-allowed":"bg-green-600 text-white hover:bg-green-700"}`,children:[(0,t.jsx)(l.PlusCircleIcon,{className:"w-4 h-4 mr-1"}),"Add Alias"]})})]})]}),(0,t.jsx)(o.Text,{className:"text-sm font-medium text-gray-700 mb-2",children:"Manage Existing Aliases"}),(0,t.jsx)("div",{className:"rounded-lg custom-border relative mb-6",children:(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsxs)(d.Table,{className:"[&_td]:py-0.5 [&_th]:py-1",children:[(0,t.jsx)(c.TableHead,{children:(0,t.jsxs)(p.TableRow,{children:[(0,t.jsx)(u.TableHeaderCell,{className:"py-1 h-8",children:"Alias Name"}),(0,t.jsx)(u.TableHeaderCell,{className:"py-1 h-8",children:"Target Model"}),(0,t.jsx)(u.TableHeaderCell,{className:"py-1 h-8",children:"Actions"})]})}),(0,t.jsxs)(m.TableBody,{children:[_.map(s=>(0,t.jsx)(p.TableRow,{className:"h-8",children:N&&N.id===s.id?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(g.TableCell,{className:"py-0.5",children:(0,t.jsx)("input",{type:"text",value:N.aliasName,onChange:e=>k({...N,aliasName:e.target.value}),className:"w-full px-2 py-1 border border-gray-300 rounded-md text-sm"})}),(0,t.jsx)(g.TableCell,{className:"py-0.5",children:(0,t.jsx)(h.default,{accessToken:e,value:N.targetModel,onChange:e=>k({...N,targetModel:e}),showLabel:!1,style:{height:"32px"}})}),(0,t.jsx)(g.TableCell,{className:"py-0.5 whitespace-nowrap",children:(0,t.jsxs)("div",{className:"flex space-x-2",children:[(0,t.jsx)("button",{onClick:S,className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded-sm hover:bg-blue-100",children:"Save"}),(0,t.jsx)("button",{onClick:C,className:"text-xs bg-gray-50 text-gray-600 px-2 py-1 rounded-sm hover:bg-gray-100",children:"Cancel"})]})})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(g.TableCell,{className:"py-0.5 text-sm text-gray-900",children:s.aliasName}),(0,t.jsx)(g.TableCell,{className:"py-0.5 text-sm text-gray-500",children:s.targetModel}),(0,t.jsx)(g.TableCell,{className:"py-0.5 whitespace-nowrap",children:(0,t.jsxs)("div",{className:"flex space-x-2",children:[(0,t.jsx)("button",{onClick:()=>{k({...s})},className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded-sm hover:bg-blue-100",children:(0,t.jsx)(a.PencilIcon,{className:"w-3 h-3"})}),(0,t.jsx)("button",{onClick:()=>{var e;let t,l;return e=s.id,j(t=_.filter(t=>t.id!==e)),l={},void(t.forEach(e=>{l[e.aliasName]=e.targetModel}),f&&f(l),x.default.success("Alias deleted successfully"))},className:"text-xs bg-red-50 text-red-600 px-2 py-1 rounded-sm hover:bg-red-100",children:(0,t.jsx)(r.TrashIcon,{className:"w-3 h-3"})})]})})]})},s.id)),0===_.length&&(0,t.jsx)(p.TableRow,{children:(0,t.jsx)(g.TableCell,{colSpan:3,className:"py-0.5 text-sm text-gray-500 text-center",children:"No aliases added yet. Add a new alias above."})})]})]})})}),b&&(0,t.jsxs)(i.Card,{children:[(0,t.jsx)(n.Title,{className:"mb-4",children:"Configuration Example"}),(0,t.jsx)(o.Text,{className:"text-gray-600 mb-4",children:"Here's how your current aliases would look in the config:"}),(0,t.jsx)("div",{className:"bg-gray-100 rounded-lg p-4 font-mono text-sm",children:(0,t.jsxs)("div",{className:"text-gray-700",children:["model_aliases:",0===Object.keys(T).length?(0,t.jsxs)("span",{className:"text-gray-500",children:[(0,t.jsx)("br",{}),"  # No aliases configured yet"]}):Object.entries(T).map(([e,s])=>(0,t.jsxs)("span",{children:[(0,t.jsx)("br",{}),'  "',e,'": "',s,'"']},e))]})})]})]})}])},266484,e=>{"use strict";var t=e.i(843476),s=e.i(199133),l=e.i(592968),a=e.i(312361),r=e.i(827252),i=e.i(994388),n=e.i(304967),o=e.i(779241),d=e.i(988297),c=e.i(68155),u=e.i(810757),m=e.i(477386),p=e.i(557662),g=e.i(555987),h=e.i(435451);let{Option:x}=s.Select;e.s(["default",0,({value:e=[],onChange:y,disabledCallbacks:f=[],onDisabledCallbacksChange:b})=>{let _=Object.entries(p.callbackInfo).filter(([e,t])=>t.supports_key_team_logging).map(([e,t])=>e),j=Object.keys(p.callbackInfo),v=e=>{y?.(e)},w=(t,s,l)=>{let a=[...e];if("callback_name"===s){let e=p.callback_map[l]||l;a[t]={...a[t],[s]:e,callback_vars:{}}}else a[t]={...a[t],[s]:l};v(a)},N=(t,s,l)=>{let a=[...e];a[t]={...a[t],callback_vars:{...a[t].callback_vars,[s]:l}},v(a)};return(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)(m.BanIcon,{className:"w-5 h-5 text-red-500"}),(0,t.jsx)("span",{className:"text-base font-semibold text-gray-800",children:"Disabled Callbacks"}),(0,t.jsx)(l.Tooltip,{title:"Select callbacks to disable for this key. Disabled callbacks will not receive any logging data.",children:(0,t.jsx)(r.InfoCircleOutlined,{className:"text-gray-400 cursor-help"})})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Disabled Callbacks"}),(0,t.jsx)(s.Select,{mode:"multiple",placeholder:"Select callbacks to disable",value:f,onChange:e=>{let t=(0,p.mapDisplayToInternalNames)(e);b?.(t)},style:{width:"100%"},optionLabelProp:"label",children:j.map(e=>{let s=(0,g.resolveLogoSrc)(p.callbackInfo[e]?.logo),a=p.callbackInfo[e]?.description;return(0,t.jsx)(x,{value:e,label:e,children:(0,t.jsx)(l.Tooltip,{title:a,placement:"right",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[s&&(0,t.jsx)("img",{src:s,alt:e,className:"w-4 h-4 object-contain",onError:t=>{let s=t.target,l=s.parentElement;if(l){let t=document.createElement("div");t.className="w-4 h-4 rounded-full bg-gray-200 flex items-center justify-center text-xs",t.textContent=e.charAt(0),l.replaceChild(t,s)}}}),(0,t.jsx)("span",{children:e})]})})},e)})}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Select callbacks that should be disabled for this key. These callbacks will not receive any logging data."})]})]}),(0,t.jsx)(a.Divider,{}),(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)(u.CogIcon,{className:"w-5 h-5 text-blue-500"}),(0,t.jsx)("span",{className:"text-base font-semibold text-gray-800",children:"Logging Integrations"}),(0,t.jsx)(l.Tooltip,{title:"Configure callback logging integrations for this team.",children:(0,t.jsx)(r.InfoCircleOutlined,{className:"text-gray-400 cursor-help"})})]}),(0,t.jsx)(i.Button,{variant:"secondary",onClick:()=>{v([...e,{callback_name:"",callback_type:"success",callback_vars:{}}])},icon:d.PlusIcon,size:"sm",className:"hover:border-blue-400 hover:text-blue-500",type:"button",children:"Add Integration"})]}),(0,t.jsx)("div",{className:"space-y-4",children:e.map((a,d)=>{let u=a.callback_name?Object.entries(p.callback_map).find(([e,t])=>t===a.callback_name)?.[0]:void 0,m=u?(0,g.resolveLogoSrc)(p.callbackInfo[u]?.logo):null;return(0,t.jsxs)(n.Card,{className:"border border-gray-200 shadow-xs hover:shadow-md transition-shadow duration-200",decoration:"top",decorationColor:"blue",children:[(0,t.jsxs)("div",{className:"flex justify-between items-start mb-4",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[m&&(0,t.jsx)("img",{src:m,alt:u,className:"w-5 h-5 object-contain"}),(0,t.jsxs)("span",{className:"text-sm font-medium",children:[u||"New Integration"," Configuration"]})]}),(0,t.jsx)(i.Button,{variant:"light",onClick:()=>{v(e.filter((e,t)=>t!==d))},icon:c.TrashIcon,size:"xs",color:"red",className:"hover:bg-red-50",type:"button",children:"Remove"})]}),(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Integration Type"}),(0,t.jsx)(s.Select,{value:u,placeholder:"Select integration",onChange:e=>w(d,"callback_name",e),className:"w-full",optionLabelProp:"label",children:_.map(e=>{let s=(0,g.resolveLogoSrc)(p.callbackInfo[e]?.logo),a=p.callbackInfo[e]?.description;return(0,t.jsx)(x,{value:e,label:e,children:(0,t.jsx)(l.Tooltip,{title:a,placement:"right",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[s&&(0,t.jsx)("img",{src:s,alt:e,className:"w-4 h-4 object-contain",onError:t=>{let s=t.target,l=s.parentElement;if(l){let t=document.createElement("div");t.className="w-4 h-4 rounded-full bg-gray-200 flex items-center justify-center text-xs",t.textContent=e.charAt(0),l.replaceChild(t,s)}}}),(0,t.jsx)("span",{children:e})]})})},e)})})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Event Type"}),(0,t.jsxs)(s.Select,{value:a.callback_type,onChange:e=>w(d,"callback_type",e),className:"w-full",children:[(0,t.jsx)(x,{value:"success",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("div",{className:"w-2 h-2 bg-green-500 rounded-full"}),(0,t.jsx)("span",{children:"Success Only"})]})}),(0,t.jsx)(x,{value:"failure",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("div",{className:"w-2 h-2 bg-red-500 rounded-full"}),(0,t.jsx)("span",{children:"Failure Only"})]})}),(0,t.jsx)(x,{value:"success_and_failure",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("div",{className:"w-2 h-2 bg-blue-500 rounded-full"}),(0,t.jsx)("span",{children:"Success & Failure"})]})})]})]})]}),((e,s)=>{if(!e.callback_name)return null;let a=Object.entries(p.callback_map).find(([t,s])=>s===e.callback_name)?.[0];if(!a)return null;let i=p.callbackInfo[a]?.dynamic_params||{};return 0===Object.keys(i).length?null:(0,t.jsxs)("div",{className:"mt-6 pt-4 border-t border-gray-100",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2 mb-4",children:[(0,t.jsx)("div",{className:"w-3 h-3 bg-blue-100 rounded-full flex items-center justify-center",children:(0,t.jsx)("div",{className:"w-1.5 h-1.5 bg-blue-500 rounded-full"})}),(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Integration Parameters"})]}),(0,t.jsx)("div",{className:"grid grid-cols-1 gap-4",children:Object.entries(i).map(([a,i])=>(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 capitalize flex items-center space-x-1",children:[(0,t.jsx)("span",{children:a.replace(/_/g," ")}),(0,t.jsx)(l.Tooltip,{title:`Environment variable reference recommended: os.environ/${a.toUpperCase()}`,children:(0,t.jsx)(r.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})}),"password"===i&&(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-medium bg-yellow-100 text-yellow-800",children:"Sensitive"}),"number"===i&&(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-medium bg-yellow-100 text-yellow-800",children:"Number"})]}),"number"===i&&(0,t.jsx)("span",{className:"text-xs text-gray-500",children:"Value must be between 0 and 1"}),"number"===i?(0,t.jsx)(h.default,{step:.01,width:400,placeholder:`os.environ/${a.toUpperCase()}`,value:e.callback_vars[a]||"",onChange:e=>N(s,a,e.target.value)}):(0,t.jsx)(o.TextInput,{type:"password"===i?"password":"text",placeholder:`os.environ/${a.toUpperCase()}`,value:e.callback_vars[a]||"",onChange:e=>N(s,a,e.target.value)})]},a))})]})})(a,d)]})]},d)})}),0===e.length&&(0,t.jsxs)("div",{className:"text-center py-12 text-gray-500 border-2 border-dashed border-gray-200 rounded-lg bg-gray-50/50",children:[(0,t.jsx)(u.CogIcon,{className:"w-12 h-12 text-gray-300 mb-3 mx-auto"}),(0,t.jsx)("div",{className:"text-base font-medium mb-1",children:"No logging integrations configured"}),(0,t.jsx)("div",{className:"text-sm text-gray-400",children:'Click "Add Integration" to configure logging for this team'})]})]})}])},651904,e=>{"use strict";var t=e.i(843476),s=e.i(599724),l=e.i(266484);e.s(["default",0,function({value:e,onChange:a,premiumUser:r=!1,disabledCallbacks:i=[],onDisabledCallbacksChange:n}){return r?(0,t.jsx)(l.default,{value:e,onChange:a,disabledCallbacks:i,onDisabledCallbacksChange:n}):(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex flex-wrap gap-2 mb-3",children:[(0,t.jsx)("div",{className:"inline-flex items-center px-3 py-1.5 rounded-lg bg-green-50 border border-green-200 text-green-800 text-sm font-medium opacity-50",children:"✨ langfuse-logging"}),(0,t.jsx)("div",{className:"inline-flex items-center px-3 py-1.5 rounded-lg bg-green-50 border border-green-200 text-green-800 text-sm font-medium opacity-50",children:"✨ datadog-logging"})]}),(0,t.jsx)("div",{className:"p-3 bg-yellow-50 border border-yellow-200 rounded-lg",children:(0,t.jsxs)(s.Text,{className:"text-sm text-yellow-800",children:["Setting Key/Team logging settings is a LiteLLM Enterprise feature. Global Logging Settings are available for all free users. Get a trial key"," ",(0,t.jsx)("a",{href:"https://www.litellm.ai/#pricing",target:"_blank",rel:"noopener noreferrer",className:"underline",children:"here"}),"."]})})]})}])},460285,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(404206),a=e.i(723731),r=e.i(653824),i=e.i(881073),n=e.i(197647),o=e.i(602869),d=e.i(158392),c=e.i(419470),u=e.i(695411);let m=(0,s.forwardRef)(({accessToken:e,value:m,onChange:p,modelData:g},h)=>{let[x,y]=(0,s.useState)({routerSettings:{},selectedStrategy:null,enableTagFiltering:!1}),[f,b]=(0,s.useState)([]),[_,j]=(0,s.useState)([]),[v,w]=(0,s.useState)([]),[N,k]=(0,s.useState)([]),[S,C]=(0,s.useState)({}),[T,I]=(0,s.useState)({}),A=(0,s.useRef)(!1),L=(0,s.useRef)(null);(0,s.useEffect)(()=>{let e=m?.router_settings?JSON.stringify({routing_strategy:m.router_settings.routing_strategy,fallbacks:m.router_settings.fallbacks,enable_tag_filtering:m.router_settings.enable_tag_filtering}):null;if(A.current&&e===L.current){A.current=!1;return}if(A.current&&e!==L.current&&(A.current=!1),e!==L.current)if(L.current=e,m?.router_settings){let e=m.router_settings,{fallbacks:t,...s}=e;y({routerSettings:s,selectedStrategy:e.routing_strategy||null,enableTagFiltering:e.enable_tag_filtering??!1});let l=e.fallbacks||[];b(l),j(l&&0!==l.length?l.map((e,t)=>{let[s,l]=Object.entries(e)[0];return{id:(t+1).toString(),primaryModel:s||null,fallbackModels:l||[]}}):[{id:"1",primaryModel:null,fallbackModels:[]}])}else y({routerSettings:{},selectedStrategy:null,enableTagFiltering:!1}),b([]),j([{id:"1",primaryModel:null,fallbackModels:[]}])},[m]),(0,s.useEffect)(()=>{e&&(0,o.getRouterSettingsCall)(e).then(e=>{if(e.fields){let t={};e.fields.forEach(e=>{t[e.field_name]={ui_field_name:e.ui_field_name,field_description:e.field_description,options:e.options,link:e.link}}),C(t);let s=e.fields.find(e=>"routing_strategy"===e.field_name);s?.options&&k(s.options),e.routing_strategy_descriptions&&I(e.routing_strategy_descriptions)}})},[e]),(0,s.useEffect)(()=>{e&&(async()=>{try{let t=await (0,u.fetchAvailableModels)(e);w(t)}catch(e){console.error("Error fetching model info for fallbacks:",e)}})()},[e]);let F=()=>{let e=new Set(["allowed_fails","cooldown_time","num_retries","timeout","retry_after"]),t=new Set(["model_group_alias","retry_policy"]),s=Object.fromEntries(Object.entries({...x.routerSettings,enable_tag_filtering:x.enableTagFiltering,routing_strategy:x.selectedStrategy,fallbacks:f.length>0?f:null}).map(([s,l])=>{if("routing_strategy_args"!==s&&"routing_strategy"!==s&&"enable_tag_filtering"!==s&&"fallbacks"!==s){let a=document.querySelector(`input[name="${s}"]`);if(a){if(void 0!==a.value&&""!==a.value){let r=((s,l,a)=>{if(null==l)return a;let r=String(l).trim();if(""===r||"null"===r.toLowerCase())return null;if(e.has(s)){let e=Number(r);return Number.isNaN(e)?a:e}if(t.has(s)){if(""===r)return null;try{return JSON.parse(r)}catch{return a}}return"true"===r.toLowerCase()||"false"!==r.toLowerCase()&&r})(s,a.value,l);return[s,r]}return[s,null]}}else if("routing_strategy"===s)return[s,x.selectedStrategy];else if("enable_tag_filtering"===s)return[s,x.enableTagFiltering];else if("fallbacks"===s)return[s,f.length>0?f:null];else if("routing_strategy_args"===s&&"latency-based-routing"===x.selectedStrategy){let e=document.querySelector('input[name="lowest_latency_buffer"]'),t=document.querySelector('input[name="ttl"]'),s={};return e?.value&&(s.lowest_latency_buffer=Number(e.value)),t?.value&&(s.ttl=Number(t.value)),["routing_strategy_args",Object.keys(s).length>0?s:null]}return[s,l]}).filter(e=>null!=e)),l=(e,t=!1)=>null==e||"object"==typeof e&&!Array.isArray(e)&&0===Object.keys(e).length||t&&("number"!=typeof e||Number.isNaN(e))?null:e;return{routing_strategy:l(s.routing_strategy),allowed_fails:l(s.allowed_fails,!0),cooldown_time:l(s.cooldown_time,!0),num_retries:l(s.num_retries,!0),timeout:l(s.timeout,!0),retry_after:l(s.retry_after,!0),fallbacks:f.length>0?f:null,context_window_fallbacks:l(s.context_window_fallbacks),retry_policy:l(s.retry_policy),model_group_alias:l(s.model_group_alias),enable_tag_filtering:x.enableTagFiltering,routing_strategy_args:l(s.routing_strategy_args)}};(0,s.useEffect)(()=>{if(!p)return;let e=setTimeout(()=>{A.current=!0,p({router_settings:F()})},100);return()=>clearTimeout(e)},[x,f]);let M=Array.from(new Set(v.map(e=>e.model_group))).sort();return((0,s.useImperativeHandle)(h,()=>({getValue:()=>({router_settings:F()})})),e)?(0,t.jsx)("div",{className:"w-full",children:(0,t.jsxs)(r.TabGroup,{className:"w-full",children:[(0,t.jsxs)(i.TabList,{variant:"line",defaultValue:"1",className:"px-8 pt-4",children:[(0,t.jsx)(n.Tab,{value:"1",children:"Loadbalancing"}),(0,t.jsx)(n.Tab,{value:"2",children:"Fallbacks"})]}),(0,t.jsxs)(a.TabPanels,{className:"px-8 py-6",children:[(0,t.jsx)(l.TabPanel,{children:(0,t.jsx)(d.default,{value:x,onChange:y,routerFieldsMetadata:S,availableRoutingStrategies:N,routingStrategyDescriptions:T})}),(0,t.jsx)(l.TabPanel,{children:(0,t.jsx)(c.FallbackSelectionForm,{groups:_,onGroupsChange:e=>{j(e),b(e.filter(e=>e.primaryModel&&e.fallbackModels.length>0).map(e=>({[e.primaryModel]:e.fallbackModels})))},availableModels:M,maxGroups:5})})]})]})}):null});m.displayName="RouterSettingsAccordion",e.s(["default",0,m])},575260,e=>{"use strict";var t=e.i(843476),s=e.i(199133),l=e.i(482725),a=e.i(56456);e.s(["default",0,({projects:e,value:r,onChange:i,disabled:n,loading:o,teamId:d})=>{let c=d?e?.filter(e=>e.team_id===d):e;return(0,t.jsx)(s.Select,{showSearch:!0,placeholder:"Search or select a project",value:r,onChange:i,disabled:n,loading:o,allowClear:!0,notFoundContent:o?(0,t.jsx)(l.Spin,{indicator:(0,t.jsx)(a.LoadingOutlined,{spin:!0}),size:"small"}):void 0,filterOption:(e,t)=>{if(!t)return!1;let s=c?.find(e=>e.project_id===t.key);if(!s)return!1;let l=e.toLowerCase().trim(),a=(s.project_alias||"").toLowerCase(),r=(s.project_id||"").toLowerCase();return a.includes(l)||r.includes(l)},optionFilterProp:"children",children:!o&&c?.map(e=>(0,t.jsxs)(s.Select.Option,{value:e.project_id,children:[(0,t.jsx)("span",{className:"font-medium",children:e.project_alias||e.project_id})," ",(0,t.jsxs)("span",{className:"text-gray-500",children:["(",e.project_id,")"]})]},e.project_id))})}])},364769,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(237016),a=e.i(464571),r=e.i(888259);e.s(["default",0,({apiKey:e})=>{let[i,n]=(0,s.useState)(!1);return(0,t.jsxs)("div",{children:[(0,t.jsxs)("p",{className:"mb-2",children:["Please save this secret key somewhere safe and accessible. For security reasons,"," ",(0,t.jsx)("b",{children:"you will not be able to view it again"})," through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]}),(0,t.jsx)("p",{className:"text-sm text-gray-600 mt-3 mb-1",children:"Virtual Key:"}),(0,t.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,t.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal",margin:0},children:e})}),(0,t.jsx)(l.CopyToClipboard,{text:e,onCopy:()=>{n(!0),r.default.success("Key copied to clipboard"),setTimeout(()=>n(!1),2e3)},children:(0,t.jsx)(a.Button,{type:"primary",style:{marginTop:12},children:i?"Copied!":"Copy Virtual Key"})})]})}])},702597,e=>{"use strict";var t=e.i(843476),s=e.i(207082),l=e.i(109799),a=e.i(510674),r=e.i(109034),i=e.i(292639),n=e.i(135214),o=e.i(500330),d=e.i(827252),c=e.i(912598),u=e.i(677667),m=e.i(130643),p=e.i(898667),g=e.i(994388),h=e.i(309426),x=e.i(350967),y=e.i(599724),f=e.i(779241),b=e.i(629569),_=e.i(464571),j=e.i(808613),v=e.i(311451),w=e.i(212931),N=e.i(91739),k=e.i(199133),S=e.i(790848),C=e.i(262218),T=e.i(592968),I=e.i(898586),A=e.i(374009),L=e.i(271645),F=e.i(708347),M=e.i(552130),O=e.i(557662),E=e.i(9314),P=e.i(860585),B=e.i(82946),$=e.i(392110),R=e.i(533882),D=e.i(844565),V=e.i(651904),z=e.i(939510),U=e.i(460285),G=e.i(663435),K=e.i(363256),q=e.i(575260),W=e.i(371455),H=e.i(128233),Q=e.i(319312),J=e.i(355619),Y=e.i(75921),X=e.i(234713),Z=e.i(390605),ee=e.i(727749),et=e.i(602869),es=e.i(364769),el=e.i(435451),ea=e.i(916940);let{Option:er}=k.Select,ei=async(e,t,s,l)=>{try{if(null===e||null===t)return[];if(null!==s)return(await (0,et.modelAvailableCall)(s,e,t,!0,l,!0)).data.map(e=>e.id);return[]}catch(e){return console.error("Error fetching user models:",e),[]}},en=async(e,t,s,l)=>{try{if(null===e||null===t)return;if(null!==s){let a=(await (0,et.modelAvailableCall)(s,e,t)).data.map(e=>e.id);l(a)}}catch(e){console.error("Error fetching user models:",e)}};e.s(["default",0,({team:e,teams:eo,data:ed,addKey:ec,autoOpenCreate:eu,prefillData:em})=>{let{accessToken:ep,userId:eg,userRole:eh,premiumUser:ex}=(0,n.default)(),ey=ex||null!=eh&&F.rolesWithWriteAccess.includes(eh),{data:ef,isLoading:eb}=(0,l.useOrganizations)(),{data:e_,isLoading:ej}=(0,a.useProjects)(),{data:ev}=(0,i.useUISettings)(),{data:ew}=(0,r.useTags)(),eN=!!ev?.values?.enable_projects_ui,ek=!!ev?.values?.disable_custom_api_keys,eS=ew?Object.values(ew).map(e=>({value:e.name,label:e.name})):[],eC=(0,c.useQueryClient)(),[eT]=j.Form.useForm(),[eI,eA]=(0,L.useState)(!1),[eL,eF]=(0,L.useState)(null),[eM,eO]=(0,L.useState)(null),[eE,eP]=(0,L.useState)([]),[eB,e$]=(0,L.useState)([]),[eR,eD]=(0,L.useState)("you"),[eV,ez]=(0,L.useState)(!1),[eU,eG]=(0,L.useState)(null),[eK,eq]=(0,L.useState)([]),[eW,eH]=(0,L.useState)([]),[eQ,eJ]=(0,L.useState)([]),[eY,eX]=(0,L.useState)([]),[eZ,e0]=(0,L.useState)(e),[e1,e2]=(0,L.useState)(null),[e4,e3]=(0,L.useState)(null),[e5,e6]=(0,L.useState)(!1),[e7,e9]=(0,L.useState)(null),[e8,te]=(0,L.useState)({}),[tt,ts]=(0,L.useState)([]),[tl,ta]=(0,L.useState)(!1),[tr,ti]=(0,L.useState)([]),[tn,to]=(0,L.useState)([]),[td,tc]=(0,L.useState)("llm_api"),[tu,tm]=(0,L.useState)({}),[tp,tg]=(0,L.useState)(!1),[th,tx]=(0,L.useState)("30d"),[ty,tf]=(0,L.useState)(null),[tb,t_]=(0,L.useState)([]),[tj,tv]=(0,L.useState)({}),[tw,tN]=(0,L.useState)(0),[tk,tS]=(0,L.useState)(0),[tC,tT]=(0,L.useState)([]),[tI,tA]=(0,L.useState)(null),tL=()=>{eA(!1),eT.resetFields(),eX([]),to([]),tc("llm_api"),tm({}),tg(!1),tx("30d"),tf(null),tS(e=>e+1),tA(null),e2(null),e3(null),t_([]),tv({}),tN(e=>e+1)},tF=()=>{eA(!1),eF(null),e0(null),eT.resetFields(),eX([]),to([]),tc("llm_api"),tm({}),tg(!1),tx("30d"),tf(null),tS(e=>e+1),tA(null),e2(null),e3(null),t_([]),tv({}),tN(e=>e+1)};(0,L.useEffect)(()=>{eg&&eh&&ep&&en(eg,eh,ep,eP)},[ep,eg,eh]),(0,L.useEffect)(()=>{ep&&(0,et.getAgentsList)(ep).then(e=>tT(e?.agents||[])).catch(()=>tT([]))},[ep]),(0,L.useEffect)(()=>{let e=async()=>{try{let e=(await (0,et.getPoliciesList)(ep)).policies.map(e=>e.policy_name);eH(e)}catch(e){console.error("Failed to fetch policies:",e)}},t=async()=>{try{let e=await (0,et.getPromptsList)(ep);eJ(e.prompts.map(e=>e.prompt_id))}catch(e){console.error("Failed to fetch prompts:",e)}};(async()=>{try{let e=(await (0,et.getGuardrailsList)(ep)).guardrails.map(e=>e.guardrail_name);eq(e)}catch(e){console.error("Failed to fetch guardrails:",e)}})(),e(),t()},[ep]),(0,L.useEffect)(()=>{(async()=>{try{if(ep){let e=sessionStorage.getItem("possibleUserRoles");if(e)te(JSON.parse(e));else{let e=await (0,et.getPossibleUserRoles)(ep);sessionStorage.setItem("possibleUserRoles",JSON.stringify(e)),te(e)}}}catch(e){console.error("Error fetching possible user roles:",e)}})()},[ep]),(0,L.useEffect)(()=>{if(eu&&!eV&&eo&&eh&&F.rolesWithWriteAccess.includes(eh)&&(eA(!0),ez(!0),em)){if(em.owned_by&&("another_user"===em.owned_by&&"Admin"!==eh?eD("you"):eD(em.owned_by)),em.team_id){let e=eo?.find(e=>e.team_id===em.team_id)||null;e&&(e0(e),eT.setFieldsValue({team_id:em.team_id}))}em.key_alias&&eT.setFieldsValue({key_alias:em.key_alias}),em.models&&em.models.length>0&&eG(em.models),em.key_type&&(tc(em.key_type),eT.setFieldsValue({key_type:em.key_type}))}},[eu,em,eo,eV,eT,eh]);let tM=eB.includes("no-default-models")&&!eZ,tO=async e=>{try{let t,l=e?.key_alias??"",a=e?.team_id??null;if((ed?.filter(e=>e.team_id===a).map(e=>e.key_alias)??[]).includes(l))throw Error(`Key alias ${l} already exists for team with ID ${a}, please provide another key alias`);if(ee.default.info("Making API Call"),eA(!0),"you"===eR)e.user_id=eg;else if("agent"===eR){if(!tI)return void ee.default.fromBackend("Please select an agent");e.agent_id=tI}let r={};try{r=JSON.parse(e.metadata||"{}")}catch(e){console.error("Error parsing metadata:",e)}if("service_account"===eR&&(r.service_account_id=e.key_alias),eY.length>0&&(r={...r,logging:eY.filter(e=>e.callback_name)}),tn.length>0){let e=(0,O.mapDisplayToInternalNames)(tn);r={...r,litellm_disabled_callbacks:e}}if(tp&&(e.auto_rotate=!0,e.rotation_interval=th),e.duration&&""!==e.duration.trim()||(e.duration=null),e.metadata=JSON.stringify(r),e.disable_global_guardrails||delete e.disable_global_guardrails,e.allowed_vector_store_ids&&e.allowed_vector_store_ids.length>0&&(e.object_permission={vector_stores:e.allowed_vector_store_ids},delete e.allowed_vector_store_ids),e.allowed_mcp_servers_and_groups&&(e.allowed_mcp_servers_and_groups.servers?.length>0||e.allowed_mcp_servers_and_groups.accessGroups?.length>0)){e.object_permission||(e.object_permission={});let{servers:t,accessGroups:s}=e.allowed_mcp_servers_and_groups;t&&t.length>0&&(e.object_permission.mcp_servers=t),s&&s.length>0&&(e.object_permission.mcp_access_groups=s),delete e.allowed_mcp_servers_and_groups}let i=e.mcp_tool_permissions||{};if(Object.keys(i).length>0&&(e.object_permission||(e.object_permission={}),e.object_permission.mcp_tool_permissions=i),delete e.mcp_tool_permissions,e.allowed_mcp_access_groups&&e.allowed_mcp_access_groups.length>0&&(e.object_permission||(e.object_permission={}),e.object_permission.mcp_access_groups=e.allowed_mcp_access_groups,delete e.allowed_mcp_access_groups),e.allowed_agents_and_groups&&(e.allowed_agents_and_groups.agents?.length>0||e.allowed_agents_and_groups.accessGroups?.length>0)){e.object_permission||(e.object_permission={});let{agents:t,accessGroups:s}=e.allowed_agents_and_groups;t&&t.length>0&&(e.object_permission.agents=t),s&&s.length>0&&(e.object_permission.agent_access_groups=s),delete e.allowed_agents_and_groups}Object.keys(tu).length>0&&(e.aliases=JSON.stringify(tu)),ty?.router_settings&&Object.values(ty.router_settings).some(e=>null!=e&&""!==e)&&(e.router_settings=ty.router_settings);let n=tb.filter(e=>e.budget_duration&&null!==e.max_budget&&void 0!==e.max_budget);n.length>0&&(e.budget_limits=n),Object.keys(tj).length>0&&(e.budget_fallbacks=tj),t="service_account"===eR?await (0,et.keyCreateServiceAccountCall)(ep,e):await (0,et.keyCreateCall)(ep,eg,e),ec(t),eC.invalidateQueries({queryKey:s.keyKeys.lists()}),eF(t.key),eO(t.soft_budget),ee.default.success("Virtual Key Created"),eT.resetFields(),t_([]),tv({}),tN(e=>e+1),localStorage.removeItem("userData"+eg)}catch(t){let e=(e=>{let t;if(!(t=!e||"object"!=typeof e||e instanceof Error?String(e):JSON.stringify(e)).includes("/key/generate")&&!t.includes("KeyManagementRoutes.KEY_GENERATE"))return`Error creating the key: ${e}`;let s=t;try{if(!e||"object"!=typeof e||e instanceof Error){let e=t.match(/\{[\s\S]*\}/);if(e){let t=JSON.parse(e[0]),l=t?.error||t;l?.message&&(s=l.message)}}else{let t=e?.error||e;t?.message&&(s=t.message)}}catch(e){}return t.includes("team_member_permission_error")||s.includes("Team member does not have permissions")?"Team member does not have permission to generate key for this team. Ask your proxy admin to configure the team member permission settings.":`Error creating the key: ${e}`})(t);ee.default.fromBackend(e)}};(0,L.useEffect)(()=>{if(e4){let e=e_?.find(e=>e.project_id===e4);e$(e?.models??[]),eT.setFieldValue("models",[]);return}eg&&eh&&ep&&ei(eg,eh,ep,eZ?.team_id??null).then(e=>{e$(Array.from(new Set([...eZ?.models??[],...e])))}),eU||eT.setFieldValue("models",[]),eT.setFieldValue("allowed_mcp_servers_and_groups",{servers:[],accessGroups:[]})},[eZ,e4,ep,eg,eh,eT]),(0,L.useEffect)(()=>{if(!eU||0===eU.length||!eB||0===eB.length)return;let e=eU.filter(e=>eB.includes(e));e.length>0&&eT.setFieldsValue({models:e}),eG(null)},[eU,eB,eT]),(0,L.useEffect)(()=>{if(!e4||!eo)return;let e=e_?.find(e=>e.project_id===e4);if(!e?.team_id||eZ?.team_id===e.team_id)return;let t=eo.find(t=>t.team_id===e.team_id)||null;t&&(e0(t),eT.setFieldValue("team_id",t.team_id))},[eo,e4,e_]);let tE=async e=>{if(!e)return void ts([]);ta(!0);try{let t=new URLSearchParams;if(t.append("user_email",e),null==ep)return;let s=(await (0,et.userFilterUICall)(ep,t)).map(e=>({label:`${e.user_email} (${e.user_id})`,value:e.user_id,user:e}));ts(s)}catch(e){console.error("Error fetching users:",e),ee.default.fromBackend("Failed to search for users")}finally{ta(!1)}},tP=(0,L.useCallback)((0,A.default)(e=>tE(e),300),[ep]);return(0,t.jsxs)("div",{children:[eh&&F.rolesWithWriteAccess.includes(eh)&&(0,t.jsx)(g.Button,{className:"mx-auto",onClick:()=>eA(!0),"data-testid":"create-key-button",children:"+ Create New Key"}),(0,t.jsx)(w.Modal,{open:eI,width:1e3,footer:null,onOk:tL,onCancel:tF,children:(0,t.jsxs)(j.Form,{form:eT,onFinish:tO,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,t.jsxs)("div",{className:"mb-8",children:[(0,t.jsx)(b.Title,{className:"mb-4",children:"Key Ownership"}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Owned By"," ",(0,t.jsx)(T.Tooltip,{title:"Select who will own this Virtual Key",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),className:"mb-4",children:(0,t.jsxs)(N.Radio.Group,{onChange:e=>eD(e.target.value),value:eR,children:[(0,t.jsx)(N.Radio,{value:"you",children:"You"}),(0,t.jsx)(N.Radio,{value:"service_account",children:"Service Account"}),"Admin"===eh&&(0,t.jsx)(N.Radio,{value:"another_user",children:"Another User"}),(0,t.jsxs)(N.Radio,{value:"agent",children:["Agent ",(0,t.jsx)(C.Tag,{color:"purple",children:"New"})]})]})}),"another_user"===eR&&(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["User ID"," ",(0,t.jsx)(T.Tooltip,{title:"The user who will own this key and be responsible for its usage",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"user_id",className:"mt-4",rules:[{required:"another_user"===eR,message:"Please input the user ID of the user you are assigning the key to"}],children:(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{style:{display:"flex",marginBottom:"8px"},children:[(0,t.jsx)(k.Select,{showSearch:!0,placeholder:"Type email to search for users",filterOption:!1,onSearch:e=>{tP(e)},onSelect:(e,t)=>{let s;return s=t.user,void eT.setFieldsValue({user_id:s.user_id})},options:tt,loading:tl,allowClear:!0,style:{width:"100%"},notFoundContent:tl?"Searching...":"No users found"}),(0,t.jsx)(_.Button,{onClick:()=>e6(!0),style:{marginLeft:"8px"},children:"Create User"})]}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Search by email to find users"})]})}),"agent"===eR&&(0,t.jsxs)("div",{className:"mt-4 p-4 bg-purple-50 border border-purple-200 rounded-md",children:[(0,t.jsx)("div",{className:"mb-3",children:(0,t.jsxs)("span",{className:"text-sm font-medium text-gray-700",children:["Select Agent ",(0,t.jsx)("span",{className:"text-red-500",children:"*"})]})}),(0,t.jsx)(k.Select,{showSearch:!0,placeholder:"Select an agent",style:{width:"100%"},value:tI,onChange:e=>tA(e),filterOption:(e,t)=>t?.label?.toLowerCase().includes(e.toLowerCase()),options:tC.map(e=>({label:e.agent_name||e.agent_id,value:e.agent_id}))}),(0,t.jsx)("div",{className:"text-xs text-gray-500 mt-2",children:"This key will be used by the selected agent to make requests to LiteLLM"})]}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Organization"," ",(0,t.jsx)(T.Tooltip,{title:"The organization this key belongs to. Selecting an organization filters the available teams.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"organization_id",className:"mt-4",children:(0,t.jsx)(K.default,{organizations:ef,loading:eb,disabled:"Admin"!==eh,onChange:e=>{e2(e||null),e0(null),e3(null),eT.setFieldValue("team_id",void 0),eT.setFieldValue("project_id",void 0)}})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Team"," ",(0,t.jsx)(T.Tooltip,{title:"The team this key belongs to, which determines available models and budget limits",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"team_id",initialValue:e?e.team_id:null,className:"mt-4",rules:[{required:"service_account"===eR,message:"Please select a team for the service account"}],help:"service_account"===eR?"required":"",children:(0,t.jsx)(G.default,{disabled:null!==e4,organizationId:e1,onTeamSelect:e=>{e0(e),e3(null),eT.setFieldValue("project_id",void 0),e?.organization_id?(e2(e.organization_id),eT.setFieldValue("organization_id",e.organization_id)):e||(e2(null),eT.setFieldValue("organization_id",void 0))}})}),eN&&(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Project"," ",(0,t.jsx)(T.Tooltip,{title:"Assign this key to a project. Selecting a project will lock the team to the project's team.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"project_id",className:"mt-4",children:(0,t.jsx)(q.default,{projects:e_,teamId:eZ?.team_id,loading:ej||!eo,onChange:e=>{if(!e){e3(null),e0(null),eT.setFieldValue("team_id",void 0);return}e3(e)}})})]}),tM&&(0,t.jsx)("div",{className:"mb-8 p-4 bg-blue-50 border border-blue-200 rounded-md",children:(0,t.jsx)(y.Text,{className:"text-blue-800 text-sm",children:"Please select a team to continue configuring your Virtual Key. If you do not see any teams, please contact your Proxy Admin to either provide you with access to models or to add you to a team."})}),!tM&&(0,t.jsxs)("div",{className:"mb-8",children:[(0,t.jsx)(b.Title,{className:"mb-4",children:"Key Details"}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["you"===eR||"another_user"===eR?"Key Name":"Service Account ID"," ",(0,t.jsx)(T.Tooltip,{title:"you"===eR||"another_user"===eR?"A descriptive name to identify this key":"Unique identifier for this service account",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"key_alias",rules:[{required:!0,message:`Please input a ${"you"===eR?"key name":"service account ID"}`}],help:"required",children:(0,t.jsx)(f.TextInput,{placeholder:""})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Models"," ",(0,t.jsx)(T.Tooltip,{title:"Select which models this key can access. Choose 'All Team Models' to grant access to all models available to the team. Leave empty to allow access to all models.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"models",rules:[],help:"management"===td||"read_only"===td?"Models field is disabled for this key type":"optional - leave empty to allow access to all models",className:"mt-4",children:(0,t.jsxs)(k.Select,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},disabled:"management"===td||"read_only"===td,onChange:e=>{e.includes("all-team-models")&&eT.setFieldsValue({models:["all-team-models"]})},children:[!e4&&(0,t.jsx)(er,{value:"all-team-models",children:"All Team Models"},"all-team-models"),eB.map(e=>(0,t.jsx)(er,{value:e,children:(0,J.getModelDisplayName)(e)},e))]})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Key Type"," ",(0,t.jsx)(T.Tooltip,{title:"Select the type of key to determine what routes and operations this key can access",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"key_type",initialValue:"llm_api",className:"mt-4",children:(0,t.jsxs)(k.Select,{defaultValue:"llm_api",placeholder:"Select key type",style:{width:"100%"},optionLabelProp:"label",onChange:e=>{tc(e),("management"===e||"read_only"===e)&&eT.setFieldsValue({models:[]})},children:[(0,t.jsx)(er,{value:"llm_api",label:"AI APIs",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)(I.Typography.Text,{strong:!0,children:"AI APIs"}),(0,t.jsx)(I.Typography.Paragraph,{type:"secondary",style:{fontSize:11,margin:"2px 0 0"},children:"Can call only AI API routes (chat/completions, embeddings, etc.)"})]})}),(0,t.jsx)(er,{value:"management",label:"Management",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)(I.Typography.Text,{strong:!0,children:"Management"}),(0,t.jsx)(I.Typography.Paragraph,{type:"secondary",style:{fontSize:11,margin:"2px 0 0"},children:"Can call only management routes (user/team/key management)"})]})}),(0,t.jsx)(er,{value:"default",label:"Full Access",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)(I.Typography.Text,{strong:!0,children:"Full Access"}),(0,t.jsx)(I.Typography.Paragraph,{type:"secondary",style:{fontSize:11,margin:"2px 0 0"},children:"Can call all routes (AI APIs, Management, and read-only)"})]})})]})})]}),!tM&&(0,t.jsx)("div",{className:"mb-8",children:(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)(b.Title,{className:"m-0",children:"Optional Settings"})}),(0,t.jsxs)(m.AccordionBody,{children:[(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Max Budget (USD)"," ",(0,t.jsx)(T.Tooltip,{title:"Maximum amount in USD this key can spend. When reached, the key will be blocked from making further requests",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"max_budget",help:`Budget cannot exceed team max budget: $${e?.max_budget!==null&&e?.max_budget!==void 0?e?.max_budget:"unlimited"}`,rules:[{validator:async(t,s)=>{if(s&&e&&null!==e.max_budget&&s>e.max_budget)throw Error(`Budget cannot exceed team max budget: $${(0,o.formatNumberWithCommas)(e.max_budget,4)}`)}}],children:(0,t.jsx)(el.default,{step:.01,precision:2,width:200})}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Reset Budget"," ",(0,t.jsx)(T.Tooltip,{title:"How often the budget should reset. For example, setting 'daily' will reset the budget every 24 hours",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"budget_duration",help:`Team Reset Budget: ${e?.budget_duration!==null&&e?.budget_duration!==void 0?e?.budget_duration:"None"}`,children:(0,t.jsx)(P.default,{onChange:e=>eT.setFieldValue("budget_duration",e)})}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Budget Windows"," ",(0,t.jsx)(T.Tooltip,{title:"Set multiple independent budget windows (e.g., hourly $10 AND monthly $200). Each window tracks spend separately and resets on its own schedule.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),children:(0,t.jsx)(Q.BudgetWindowsEditor,{value:tb,onChange:t_})}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Budget Fallbacks"," ",(0,t.jsx)(T.Tooltip,{title:"When a model exceeds its per-model budget (model_max_budget), requests automatically reroute to fallback models instead of failing. Configure per-model budgets in Advanced Settings.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),children:(0,t.jsx)(H.BudgetFallbacksEditor,{value:tj,onChange:tv,availableModels:eB},tw)}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Tokens per minute Limit (TPM)"," ",(0,t.jsx)(T.Tooltip,{title:"Maximum number of tokens this key can process per minute. Helps control usage and costs",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"tpm_limit",help:`TPM cannot exceed team TPM limit: ${e?.tpm_limit!==null&&e?.tpm_limit!==void 0?e?.tpm_limit:"unlimited"}`,rules:[{validator:async(t,s)=>{if(s&&e&&null!==e.tpm_limit&&s>e.tpm_limit)throw Error(`TPM limit cannot exceed team TPM limit: ${e.tpm_limit}`)}}],children:(0,t.jsx)(el.default,{step:1,width:400})}),(0,t.jsx)(z.default,{type:"tpm",name:"tpm_limit_type",className:"mt-4",initialValue:null,form:eT,showDetailedDescriptions:!0}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Requests per minute Limit (RPM)"," ",(0,t.jsx)(T.Tooltip,{title:"Maximum number of API requests this key can make per minute. Helps prevent abuse and manage load",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"rpm_limit",help:`RPM cannot exceed team RPM limit: ${e?.rpm_limit!==null&&e?.rpm_limit!==void 0?e?.rpm_limit:"unlimited"}`,rules:[{validator:async(t,s)=>{if(s&&e&&null!==e.rpm_limit&&s>e.rpm_limit)throw Error(`RPM limit cannot exceed team RPM limit: ${e.rpm_limit}`)}}],children:(0,t.jsx)(el.default,{step:1,width:400})}),(0,t.jsx)(z.default,{type:"rpm",name:"rpm_limit_type",className:"mt-4",initialValue:null,form:eT,showDetailedDescriptions:!0}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Guardrails"," ",(0,t.jsx)(T.Tooltip,{title:"Apply safety guardrails to this key to filter content or enforce policies",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"guardrails",className:"mt-4",help:ey?"Select existing guardrails or enter new ones":"Premium feature - Upgrade to set guardrails by key",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},disabled:!ey,placeholder:ey?"Select or enter guardrails":"Premium feature - Upgrade to set guardrails by key",options:eK.map(e=>({value:e,label:e}))})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Disable Global Guardrails"," ",(0,t.jsx)(T.Tooltip,{title:"When enabled, this key will bypass any guardrails configured to run on every request (global guardrails)",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"disable_global_guardrails",className:"mt-4",valuePropName:"checked",help:ey?"Bypass global guardrails for this key":"Premium feature - Upgrade to disable global guardrails by key",children:(0,t.jsx)(S.Switch,{disabled:!ey,checkedChildren:"Yes",unCheckedChildren:"No"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Policies"," ",(0,t.jsx)(T.Tooltip,{title:"Apply policies to this key to control guardrails and other settings",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/guardrail_policies",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"policies",className:"mt-4",help:ex?"Select existing policies or enter new ones":"Premium feature - Upgrade to set policies by key",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},disabled:!ex,placeholder:ex?"Select or enter policies":"Premium feature - Upgrade to set policies by key",options:eW.map(e=>({value:e,label:e}))})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Prompts"," ",(0,t.jsx)(T.Tooltip,{title:"Allow this key to use specific prompt templates",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/prompt_management",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"prompts",className:"mt-4",help:ex?"Select existing prompts or enter new ones":"Premium feature - Upgrade to set prompts by key",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},disabled:!ex,placeholder:ex?"Select or enter prompts":"Premium feature - Upgrade to set prompts by key",options:eQ.map(e=>({value:e,label:e}))})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Access Groups"," ",(0,t.jsx)(T.Tooltip,{title:"Assign access groups to this key. Access groups control which models, MCP servers, and agents this key can use",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"access_group_ids",className:"mt-4",help:"Select access groups to assign to this key",children:(0,t.jsx)(E.default,{placeholder:"Select access groups (optional)"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Pass Through Routes"," ",(0,t.jsx)(T.Tooltip,{title:"Allow this key to use specific pass through routes",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/pass_through",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"allowed_passthrough_routes",className:"mt-4",help:ex?"Select existing pass through routes or enter new ones":"Premium feature - Upgrade to set pass through routes by key",children:(0,t.jsx)(D.default,{onChange:e=>eT.setFieldValue("allowed_passthrough_routes",e),value:eT.getFieldValue("allowed_passthrough_routes"),accessToken:ep,placeholder:ex?"Select or enter pass through routes":"Premium feature - Upgrade to set pass through routes by key",disabled:!ex,teamId:eZ?eZ.team_id:null})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Vector Stores"," ",(0,t.jsx)(T.Tooltip,{title:"Select which vector stores this key can access. If none selected, the key will have access to all available vector stores",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"allowed_vector_store_ids",className:"mt-4",help:"Select vector stores this key can access. Leave empty for access to all vector stores",children:(0,t.jsx)(ea.default,{onChange:e=>eT.setFieldValue("allowed_vector_store_ids",e),value:eT.getFieldValue("allowed_vector_store_ids"),accessToken:ep,placeholder:"Select vector stores (optional)"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Metadata"," ",(0,t.jsx)(T.Tooltip,{title:"JSON object with additional information about this key. Used for tracking or custom logic",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"metadata",className:"mt-4",children:(0,t.jsx)(v.Input.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Tags"," ",(0,t.jsx)(T.Tooltip,{title:"Tags for tracking spend and/or doing tag-based routing. Used for analytics and filtering",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"tags",className:"mt-4",help:"Tags for tracking spend and/or doing tag-based routing.",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},placeholder:"Select or enter tags",tokenSeparators:[","],options:eS})}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"MCP Settings"})}),(0,t.jsxs)(m.AccordionBody,{children:[(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed MCP Servers"," ",(0,t.jsx)(T.Tooltip,{title:"Select which MCP servers or access groups this key can access",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"allowed_mcp_servers_and_groups",help:"Select MCP servers or access groups this key can access",children:(0,t.jsx)(Y.default,{onChange:e=>eT.setFieldValue("allowed_mcp_servers_and_groups",e),value:eT.getFieldValue("allowed_mcp_servers_and_groups"),accessToken:ep,teamId:eZ?.team_id??null,placeholder:"Select MCP servers or access groups (optional)",allowNoMcpServers:!0})}),(0,t.jsx)(j.Form.Item,{name:"mcp_tool_permissions",initialValue:{},hidden:!0,children:(0,t.jsx)(v.Input,{type:"hidden"})}),(0,t.jsx)(j.Form.Item,{noStyle:!0,shouldUpdate:(e,t)=>e.allowed_mcp_servers_and_groups!==t.allowed_mcp_servers_and_groups||e.mcp_tool_permissions!==t.mcp_tool_permissions,children:()=>(0,t.jsx)("div",{className:"mt-6",children:(0,t.jsx)(Z.default,{accessToken:ep,selectedServers:(eT.getFieldValue("allowed_mcp_servers_and_groups")?.servers||[]).filter(e=>e!==X.NO_MCP_SERVERS_SENTINEL),toolPermissions:eT.getFieldValue("mcp_tool_permissions")||{},onChange:e=>eT.setFieldsValue({mcp_tool_permissions:e})})})})]})]}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Agent Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Agents"," ",(0,t.jsx)(T.Tooltip,{title:"Select which agents or access groups this key can access",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"allowed_agents_and_groups",help:"Select agents or access groups this key can access",children:(0,t.jsx)(M.default,{onChange:e=>eT.setFieldValue("allowed_agents_and_groups",e),value:eT.getFieldValue("allowed_agents_and_groups"),accessToken:ep,placeholder:"Select agents or access groups (optional)"})})})]}),ex?(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Logging Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(V.default,{value:eY,onChange:eX,premiumUser:!0,disabledCallbacks:tn,onDisabledCallbacksChange:to})})})]}):(0,t.jsx)(T.Tooltip,{title:(0,t.jsxs)("span",{children:["Key-level logging settings is an enterprise feature, get in touch -",(0,t.jsx)("a",{href:"https://www.litellm.ai/enterprise",target:"_blank",children:"https://www.litellm.ai/enterprise"})]}),placement:"top",children:(0,t.jsxs)("div",{style:{position:"relative"},children:[(0,t.jsx)("div",{style:{opacity:.5},children:(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Logging Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(V.default,{value:eY,onChange:eX,premiumUser:!1,disabledCallbacks:tn,onDisabledCallbacksChange:to})})})]})}),(0,t.jsx)("div",{style:{position:"absolute",inset:0,cursor:"not-allowed"}})]})}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Router Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4 w-full",children:(0,t.jsx)(U.default,{accessToken:ep||"",value:ty||void 0,onChange:tf,modelData:eE.length>0?{data:eE.map(e=>({model_name:e}))}:void 0},tk)})})]},`router-settings-accordion-${tk}`),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Model Aliases"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsxs)("div",{className:"mt-4",children:[(0,t.jsx)(y.Text,{className:"text-sm text-gray-600 mb-4",children:"Create custom aliases for models that can be used in API calls. This allows you to create shortcuts for specific models."}),(0,t.jsx)(R.default,{accessToken:ep,initialModelAliases:tu,onAliasUpdate:tm,showExampleConfig:!1})]})})]}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Key Lifecycle"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)($.default,{form:eT,autoRotationEnabled:tp,onAutoRotationChange:tg,rotationInterval:th,onRotationIntervalChange:tx,isCreateMode:!0})})}),(0,t.jsx)(j.Form.Item,{name:"duration",hidden:!0,initialValue:null,children:(0,t.jsx)(v.Input,{})})]}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("b",{children:"Advanced Settings"}),(0,t.jsx)(T.Tooltip,{title:(0,t.jsxs)("span",{children:["Learn more about advanced settings in our"," ",(0,t.jsx)("a",{href:et.proxyBaseUrl?`${et.proxyBaseUrl}/#/key%20management/generate_key_fn_key_generate_post`:"/#/key%20management/generate_key_fn_key_generate_post",target:"_blank",rel:"noopener noreferrer",className:"text-blue-400 hover:text-blue-300",children:"documentation"})]}),children:(0,t.jsx)(d.InfoCircleOutlined,{className:"text-gray-400 hover:text-gray-300 cursor-help"})})]})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)(B.default,{schemaComponent:"GenerateKeyRequest",form:eT,excludedFields:["key_alias","team_id","organization_id","models","duration","metadata","tags","guardrails","max_budget","budget_duration","tpm_limit","rpm_limit",...ek?["key"]:[]]})})]})]})]})}),(0,t.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,t.jsx)(_.Button,{htmlType:"submit",disabled:tM,style:{opacity:tM?.5:1},children:"Create Key"})})]})}),e5&&(0,t.jsx)(w.Modal,{title:"Create New User",open:e5,onCancel:()=>e6(!1),footer:null,width:800,children:(0,t.jsx)(W.CreateUserButton,{userID:eg,accessToken:ep,teams:eo,possibleUIRoles:e8,onUserCreated:e=>{e9(e),eT.setFieldsValue({user_id:e}),e6(!1)},isEmbedded:!0})}),eL&&(0,t.jsx)(w.Modal,{open:eI,onOk:tL,onCancel:tF,footer:null,children:(0,t.jsxs)(x.Grid,{numItems:1,className:"gap-2 w-full",children:[(0,t.jsx)(b.Title,{children:"Save your Key"}),(0,t.jsx)(h.Col,{numColSpan:1,children:null!=eL?(0,t.jsx)(es.default,{apiKey:eL}):(0,t.jsx)(y.Text,{children:"Key being created, this might take 30s"})})]})})]})},"fetchTeamModels",0,ei,"fetchUserModels",0,en],702597)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/00q4mtjboprhm.js b/litellm/proxy/_experimental/out/_next/static/chunks/00q4mtjboprhm.js new file mode 100644 index 00000000000..a2355d3675e --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/00q4mtjboprhm.js @@ -0,0 +1,4 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,152990,682830,e=>{"use strict";var t=e.i(271645);function l(e,t){return"function"==typeof e?e(t):e}function n(e,t){return n=>{t.setState(t=>({...t,[e]:l(n,t[e])}))}}function o(e){return e instanceof Function}function i(e,t,l){let n,o=[];return i=>{let r,a;l.key&&l.debug&&(r=Date.now());let u=e(i);if(!(u.length!==o.length||u.some((e,t)=>o[t]!==e)))return n;if(o=u,l.key&&l.debug&&(a=Date.now()),n=t(...u),null==l||null==l.onChange||l.onChange(n),l.key&&l.debug&&null!=l&&l.debug()){let e=Math.round((Date.now()-r)*100)/100,t=Math.round((Date.now()-a)*100)/100,n=t/16,o=(e,t)=>{for(e=String(e);e.length{var l;return null!=(l=null==e?void 0:e.debugAll)?l:e[t]},key:!1,onChange:n}}e.i(247167);let a="debugHeaders";function u(e,t,l){var n;let o={id:null!=(n=l.id)?n:t.id,column:t,index:l.index,isPlaceholder:!!l.isPlaceholder,placeholderId:l.placeholderId,depth:l.depth,subHeaders:[],colSpan:0,rowSpan:0,headerGroup:null,getLeafHeaders:()=>{let e=[],t=l=>{l.subHeaders&&l.subHeaders.length&&l.subHeaders.map(t),e.push(l)};return t(o),e},getContext:()=>({table:e,header:o,column:t})};return e._features.forEach(t=>{null==t.createHeader||t.createHeader(o,e)}),o}function g(e,t,l,n){var o,i;let r=0,a=function(e,t){void 0===t&&(t=1),r=Math.max(r,t),e.filter(e=>e.getIsVisible()).forEach(e=>{var l;null!=(l=e.columns)&&l.length&&a(e.columns,t+1)},0)};a(e);let g=[],s=(e,t)=>{let o={depth:t,id:[n,`${t}`].filter(Boolean).join("_"),headers:[]},i=[];e.forEach(e=>{let r,a=[...i].reverse()[0],g=e.column.depth===o.depth,s=!1;if(g&&e.column.parent?r=e.column.parent:(r=e.column,s=!0),a&&(null==a?void 0:a.column)===r)a.subHeaders.push(e);else{let o=u(l,r,{id:[n,t,r.id,null==e?void 0:e.id].filter(Boolean).join("_"),isPlaceholder:s,placeholderId:s?`${i.filter(e=>e.column===r).length}`:void 0,depth:t,index:i.length});o.subHeaders.push(e),i.push(o)}o.headers.push(e),e.headerGroup=o}),g.push(o),t>0&&s(i,t-1)};s(t.map((e,t)=>u(l,e,{depth:r,index:t})),r-1),g.reverse();let d=e=>e.filter(e=>e.column.getIsVisible()).map(e=>{let t=0,l=0,n=[0];return e.subHeaders&&e.subHeaders.length?(n=[],d(e.subHeaders).forEach(e=>{let{colSpan:l,rowSpan:o}=e;t+=l,n.push(o)})):t=1,l+=Math.min(...n),e.colSpan=t,e.rowSpan=l,{colSpan:t,rowSpan:l}});return d(null!=(o=null==(i=g[0])?void 0:i.headers)?o:[]),g}let s=(e,t,l,n,o,a,u)=>{let g={id:t,index:n,original:l,depth:o,parentId:u,_valuesCache:{},_uniqueValuesCache:{},getValue:t=>{if(g._valuesCache.hasOwnProperty(t))return g._valuesCache[t];let l=e.getColumn(t);if(null!=l&&l.accessorFn)return g._valuesCache[t]=l.accessorFn(g.original,n),g._valuesCache[t]},getUniqueValues:t=>{if(g._uniqueValuesCache.hasOwnProperty(t))return g._uniqueValuesCache[t];let l=e.getColumn(t);if(null!=l&&l.accessorFn)return l.columnDef.getUniqueValues?g._uniqueValuesCache[t]=l.columnDef.getUniqueValues(g.original,n):g._uniqueValuesCache[t]=[g.getValue(t)],g._uniqueValuesCache[t]},renderValue:t=>{var l;return null!=(l=g.getValue(t))?l:e.options.renderFallbackValue},subRows:null!=a?a:[],getLeafRows:()=>{var e,t;let l,n;return e=g.subRows,t=e=>e.subRows,l=[],(n=e=>{e.forEach(e=>{l.push(e);let o=t(e);null!=o&&o.length&&n(o)})})(e),l},getParentRow:()=>g.parentId?e.getRow(g.parentId,!0):void 0,getParentRows:()=>{let e=[],t=g;for(;;){let l=t.getParentRow();if(!l)break;e.push(l),t=l}return e.reverse()},getAllCells:i(()=>[e.getAllLeafColumns()],t=>t.map(t=>{var l;let n;return l=t.id,n={id:`${g.id}_${t.id}`,row:g,column:t,getValue:()=>g.getValue(l),renderValue:()=>{var t;return null!=(t=n.getValue())?t:e.options.renderFallbackValue},getContext:i(()=>[e,t,g,n],(e,t,l,n)=>({table:e,column:t,row:l,cell:n,getValue:n.getValue,renderValue:n.renderValue}),r(e.options,"debugCells","cell.getContext"))},e._features.forEach(l=>{null==l.createCell||l.createCell(n,t,g,e)},{}),n}),r(e.options,"debugRows","getAllCells")),_getAllCellsByColumnId:i(()=>[g.getAllCells()],e=>e.reduce((e,t)=>(e[t.column.id]=t,e),{}),r(e.options,"debugRows","getAllCellsByColumnId"))};for(let t=0;t{var n,o;let i=null==l||null==(n=l.toString())?void 0:n.toLowerCase();return!!(null==(o=e.getValue(t))||null==(o=o.toString())||null==(o=o.toLowerCase())?void 0:o.includes(i))};d.autoRemove=e=>h(e);let p=(e,t,l)=>{var n;return!!(null==(n=e.getValue(t))||null==(n=n.toString())?void 0:n.includes(l))};p.autoRemove=e=>h(e);let c=(e,t,l)=>{var n;return(null==(n=e.getValue(t))||null==(n=n.toString())?void 0:n.toLowerCase())===(null==l?void 0:l.toLowerCase())};c.autoRemove=e=>h(e);let f=(e,t,l)=>{var n;return null==(n=e.getValue(t))?void 0:n.includes(l)};f.autoRemove=e=>h(e);let m=(e,t,l)=>!l.some(l=>{var n;return!(null!=(n=e.getValue(t))&&n.includes(l))});m.autoRemove=e=>h(e)||!(null!=e&&e.length);let C=(e,t,l)=>l.some(l=>{var n;return null==(n=e.getValue(t))?void 0:n.includes(l)});C.autoRemove=e=>h(e)||!(null!=e&&e.length);let w=(e,t,l)=>e.getValue(t)===l;w.autoRemove=e=>h(e);let S=(e,t,l)=>e.getValue(t)==l;S.autoRemove=e=>h(e);let R=(e,t,l)=>{let[n,o]=l,i=e.getValue(t);return i>=n&&i<=o};R.resolveFilterValue=e=>{let[t,l]=e,n="number"!=typeof t?parseFloat(t):t,o="number"!=typeof l?parseFloat(l):l,i=null===t||Number.isNaN(n)?-1/0:n,r=null===l||Number.isNaN(o)?1/0:o;if(i>r){let e=i;i=r,r=e}return[i,r]},R.autoRemove=e=>h(e)||h(e[0])&&h(e[1]);let v={includesString:d,includesStringSensitive:p,equalsString:c,arrIncludes:f,arrIncludesAll:m,arrIncludesSome:C,equals:w,weakEquals:S,inNumberRange:R};function h(e){return null==e||""===e}function b(e,t,l){return!!e&&!!e.autoRemove&&e.autoRemove(t,l)||void 0===t||"string"==typeof t&&!t}let F={sum:(e,t,l)=>l.reduce((t,l)=>{let n=l.getValue(e);return t+("number"==typeof n?n:0)},0),min:(e,t,l)=>{let n;return l.forEach(t=>{let l=t.getValue(e);null!=l&&(n>l||void 0===n&&l>=l)&&(n=l)}),n},max:(e,t,l)=>{let n;return l.forEach(t=>{let l=t.getValue(e);null!=l&&(n=l)&&(n=l)}),n},extent:(e,t,l)=>{let n,o;return l.forEach(t=>{let l=t.getValue(e);null!=l&&(void 0===n?l>=l&&(n=o=l):(n>l&&(n=l),o{let l=0,n=0;if(t.forEach(t=>{let o=t.getValue(e);null!=o&&(o*=1)>=o&&(++l,n+=o)}),l)return n/l},median:(e,t)=>{if(!t.length)return;let l=t.map(t=>t.getValue(e));if(!(Array.isArray(l)&&l.every(e=>"number"==typeof e)))return;if(1===l.length)return l[0];let n=Math.floor(l.length/2),o=l.sort((e,t)=>e-t);return l.length%2!=0?o[n]:(o[n-1]+o[n])/2},unique:(e,t)=>Array.from(new Set(t.map(t=>t.getValue(e))).values()),uniqueCount:(e,t)=>new Set(t.map(t=>t.getValue(e))).size,count:(e,t)=>t.length},M=()=>({left:[],right:[]}),V={size:150,minSize:20,maxSize:Number.MAX_SAFE_INTEGER},P=()=>({startOffset:null,startSize:null,deltaOffset:null,deltaPercentage:null,isResizingColumn:!1,columnSizingStart:[]}),I=null;function x(e){return"touchstart"===e.type}function _(e,t){return t?"center"===t?e.getCenterVisibleLeafColumns():"left"===t?e.getLeftVisibleLeafColumns():e.getRightVisibleLeafColumns():e.getVisibleLeafColumns()}let y=()=>({pageIndex:0,pageSize:10}),E=()=>({top:[],bottom:[]}),G=(e,t,l,n,o)=>{var i;let r=o.getRow(t,!0);l?(r.getCanMultiSelect()||Object.keys(e).forEach(t=>delete e[t]),r.getCanSelect()&&(e[t]=!0)):delete e[t],n&&null!=(i=r.subRows)&&i.length&&r.getCanSelectSubRows()&&r.subRows.forEach(t=>G(e,t.id,l,n,o))};function L(e,t){let l=e.getState().rowSelection,n=[],o={},i=function(e,t){return e.map(e=>{var t;let r=A(e,l);if(r&&(n.push(e),o[e.id]=e),null!=(t=e.subRows)&&t.length&&(e={...e,subRows:i(e.subRows)}),r)return e}).filter(Boolean)};return{rows:i(t.rows),flatRows:n,rowsById:o}}function A(e,t){var l;return null!=(l=t[e.id])&&l}function H(e,t,l){var n;if(!(null!=(n=e.subRows)&&n.length))return!1;let o=!0,i=!1;return e.subRows.forEach(e=>{if((!i||o)&&(e.getCanSelect()&&(A(e,t)?i=!0:o=!1),e.subRows&&e.subRows.length)){let l=H(e,t);"all"===l?i=!0:("some"===l&&(i=!0),o=!1)}}),o?"all":!!i&&"some"}let D=/([0-9]+)/gm;function z(e,t){return e===t?0:e>t?1:-1}function O(e){return"number"==typeof e?isNaN(e)||e===1/0||e===-1/0?"":String(e):"string"==typeof e?e:""}function T(e,t){let l=e.split(D).filter(Boolean),n=t.split(D).filter(Boolean);for(;l.length&&n.length;){let e=l.shift(),t=n.shift(),o=parseInt(e,10),i=parseInt(t,10),r=[o,i].sort();if(isNaN(r[0])){if(e>t)return 1;if(t>e)return -1;continue}if(isNaN(r[1]))return isNaN(o)?-1:1;if(o>i)return 1;if(i>o)return -1}return l.length-n.length}let B={alphanumeric:(e,t,l)=>T(O(e.getValue(l)).toLowerCase(),O(t.getValue(l)).toLowerCase()),alphanumericCaseSensitive:(e,t,l)=>T(O(e.getValue(l)),O(t.getValue(l))),text:(e,t,l)=>z(O(e.getValue(l)).toLowerCase(),O(t.getValue(l)).toLowerCase()),textCaseSensitive:(e,t,l)=>z(O(e.getValue(l)),O(t.getValue(l))),datetime:(e,t,l)=>{let n=e.getValue(l),o=t.getValue(l);return n>o?1:nz(e.getValue(l),t.getValue(l))},q=[{createTable:e=>{e.getHeaderGroups=i(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.left,e.getState().columnPinning.right],(t,l,n,o)=>{var i,r;let a=null!=(i=null==n?void 0:n.map(e=>l.find(t=>t.id===e)).filter(Boolean))?i:[],u=null!=(r=null==o?void 0:o.map(e=>l.find(t=>t.id===e)).filter(Boolean))?r:[];return g(t,[...a,...l.filter(e=>!(null!=n&&n.includes(e.id))&&!(null!=o&&o.includes(e.id))),...u],e)},r(e.options,a,"getHeaderGroups")),e.getCenterHeaderGroups=i(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.left,e.getState().columnPinning.right],(t,l,n,o)=>g(t,l=l.filter(e=>!(null!=n&&n.includes(e.id))&&!(null!=o&&o.includes(e.id))),e,"center"),r(e.options,a,"getCenterHeaderGroups")),e.getLeftHeaderGroups=i(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.left],(t,l,n)=>{var o;return g(t,null!=(o=null==n?void 0:n.map(e=>l.find(t=>t.id===e)).filter(Boolean))?o:[],e,"left")},r(e.options,a,"getLeftHeaderGroups")),e.getRightHeaderGroups=i(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.right],(t,l,n)=>{var o;return g(t,null!=(o=null==n?void 0:n.map(e=>l.find(t=>t.id===e)).filter(Boolean))?o:[],e,"right")},r(e.options,a,"getRightHeaderGroups")),e.getFooterGroups=i(()=>[e.getHeaderGroups()],e=>[...e].reverse(),r(e.options,a,"getFooterGroups")),e.getLeftFooterGroups=i(()=>[e.getLeftHeaderGroups()],e=>[...e].reverse(),r(e.options,a,"getLeftFooterGroups")),e.getCenterFooterGroups=i(()=>[e.getCenterHeaderGroups()],e=>[...e].reverse(),r(e.options,a,"getCenterFooterGroups")),e.getRightFooterGroups=i(()=>[e.getRightHeaderGroups()],e=>[...e].reverse(),r(e.options,a,"getRightFooterGroups")),e.getFlatHeaders=i(()=>[e.getHeaderGroups()],e=>e.map(e=>e.headers).flat(),r(e.options,a,"getFlatHeaders")),e.getLeftFlatHeaders=i(()=>[e.getLeftHeaderGroups()],e=>e.map(e=>e.headers).flat(),r(e.options,a,"getLeftFlatHeaders")),e.getCenterFlatHeaders=i(()=>[e.getCenterHeaderGroups()],e=>e.map(e=>e.headers).flat(),r(e.options,a,"getCenterFlatHeaders")),e.getRightFlatHeaders=i(()=>[e.getRightHeaderGroups()],e=>e.map(e=>e.headers).flat(),r(e.options,a,"getRightFlatHeaders")),e.getCenterLeafHeaders=i(()=>[e.getCenterFlatHeaders()],e=>e.filter(e=>{var t;return!(null!=(t=e.subHeaders)&&t.length)}),r(e.options,a,"getCenterLeafHeaders")),e.getLeftLeafHeaders=i(()=>[e.getLeftFlatHeaders()],e=>e.filter(e=>{var t;return!(null!=(t=e.subHeaders)&&t.length)}),r(e.options,a,"getLeftLeafHeaders")),e.getRightLeafHeaders=i(()=>[e.getRightFlatHeaders()],e=>e.filter(e=>{var t;return!(null!=(t=e.subHeaders)&&t.length)}),r(e.options,a,"getRightLeafHeaders")),e.getLeafHeaders=i(()=>[e.getLeftHeaderGroups(),e.getCenterHeaderGroups(),e.getRightHeaderGroups()],(e,t,l)=>{var n,o,i,r,a,u;return[...null!=(n=null==(o=e[0])?void 0:o.headers)?n:[],...null!=(i=null==(r=t[0])?void 0:r.headers)?i:[],...null!=(a=null==(u=l[0])?void 0:u.headers)?a:[]].map(e=>e.getLeafHeaders()).flat()},r(e.options,a,"getLeafHeaders"))}},{getInitialState:e=>({columnVisibility:{},...e}),getDefaultOptions:e=>({onColumnVisibilityChange:n("columnVisibility",e)}),createColumn:(e,t)=>{e.toggleVisibility=l=>{e.getCanHide()&&t.setColumnVisibility(t=>({...t,[e.id]:null!=l?l:!e.getIsVisible()}))},e.getIsVisible=()=>{var l,n;let o=e.columns;return null==(l=o.length?o.some(e=>e.getIsVisible()):null==(n=t.getState().columnVisibility)?void 0:n[e.id])||l},e.getCanHide=()=>{var l,n;return(null==(l=e.columnDef.enableHiding)||l)&&(null==(n=t.options.enableHiding)||n)},e.getToggleVisibilityHandler=()=>t=>{null==e.toggleVisibility||e.toggleVisibility(t.target.checked)}},createRow:(e,t)=>{e._getAllVisibleCells=i(()=>[e.getAllCells(),t.getState().columnVisibility],e=>e.filter(e=>e.column.getIsVisible()),r(t.options,"debugRows","_getAllVisibleCells")),e.getVisibleCells=i(()=>[e.getLeftVisibleCells(),e.getCenterVisibleCells(),e.getRightVisibleCells()],(e,t,l)=>[...e,...t,...l],r(t.options,"debugRows","getVisibleCells"))},createTable:e=>{let t=(t,l)=>i(()=>[l(),l().filter(e=>e.getIsVisible()).map(e=>e.id).join("_")],e=>e.filter(e=>null==e.getIsVisible?void 0:e.getIsVisible()),r(e.options,"debugColumns",t));e.getVisibleFlatColumns=t("getVisibleFlatColumns",()=>e.getAllFlatColumns()),e.getVisibleLeafColumns=t("getVisibleLeafColumns",()=>e.getAllLeafColumns()),e.getLeftVisibleLeafColumns=t("getLeftVisibleLeafColumns",()=>e.getLeftLeafColumns()),e.getRightVisibleLeafColumns=t("getRightVisibleLeafColumns",()=>e.getRightLeafColumns()),e.getCenterVisibleLeafColumns=t("getCenterVisibleLeafColumns",()=>e.getCenterLeafColumns()),e.setColumnVisibility=t=>null==e.options.onColumnVisibilityChange?void 0:e.options.onColumnVisibilityChange(t),e.resetColumnVisibility=t=>{var l;e.setColumnVisibility(t?{}:null!=(l=e.initialState.columnVisibility)?l:{})},e.toggleAllColumnsVisible=t=>{var l;t=null!=(l=t)?l:!e.getIsAllColumnsVisible(),e.setColumnVisibility(e.getAllLeafColumns().reduce((e,l)=>({...e,[l.id]:t||!(null!=l.getCanHide&&l.getCanHide())}),{}))},e.getIsAllColumnsVisible=()=>!e.getAllLeafColumns().some(e=>!(null!=e.getIsVisible&&e.getIsVisible())),e.getIsSomeColumnsVisible=()=>e.getAllLeafColumns().some(e=>null==e.getIsVisible?void 0:e.getIsVisible()),e.getToggleAllColumnsVisibilityHandler=()=>t=>{var l;e.toggleAllColumnsVisible(null==(l=t.target)?void 0:l.checked)}}},{getInitialState:e=>({columnOrder:[],...e}),getDefaultOptions:e=>({onColumnOrderChange:n("columnOrder",e)}),createColumn:(e,t)=>{e.getIndex=i(e=>[_(t,e)],t=>t.findIndex(t=>t.id===e.id),r(t.options,"debugColumns","getIndex")),e.getIsFirstColumn=l=>{var n;return(null==(n=_(t,l)[0])?void 0:n.id)===e.id},e.getIsLastColumn=l=>{var n;let o=_(t,l);return(null==(n=o[o.length-1])?void 0:n.id)===e.id}},createTable:e=>{e.setColumnOrder=t=>null==e.options.onColumnOrderChange?void 0:e.options.onColumnOrderChange(t),e.resetColumnOrder=t=>{var l;e.setColumnOrder(t?[]:null!=(l=e.initialState.columnOrder)?l:[])},e._getOrderColumnsFn=i(()=>[e.getState().columnOrder,e.getState().grouping,e.options.groupedColumnMode],(e,t,l)=>n=>{let o=[];if(null!=e&&e.length){let t=[...e],l=[...n];for(;l.length&&t.length;){let e=t.shift(),n=l.findIndex(t=>t.id===e);n>-1&&o.push(l.splice(n,1)[0])}o=[...o,...l]}else o=n;var i=o;if(!(null!=t&&t.length)||!l)return i;let r=i.filter(e=>!t.includes(e.id));return"remove"===l?r:[...t.map(e=>i.find(t=>t.id===e)).filter(Boolean),...r]},r(e.options,"debugTable","_getOrderColumnsFn"))}},{getInitialState:e=>({columnPinning:M(),...e}),getDefaultOptions:e=>({onColumnPinningChange:n("columnPinning",e)}),createColumn:(e,t)=>{e.pin=l=>{let n=e.getLeafColumns().map(e=>e.id).filter(Boolean);t.setColumnPinning(e=>{var t,o,i,r,a,u;return"right"===l?{left:(null!=(i=null==e?void 0:e.left)?i:[]).filter(e=>!(null!=n&&n.includes(e))),right:[...(null!=(r=null==e?void 0:e.right)?r:[]).filter(e=>!(null!=n&&n.includes(e))),...n]}:"left"===l?{left:[...(null!=(a=null==e?void 0:e.left)?a:[]).filter(e=>!(null!=n&&n.includes(e))),...n],right:(null!=(u=null==e?void 0:e.right)?u:[]).filter(e=>!(null!=n&&n.includes(e)))}:{left:(null!=(t=null==e?void 0:e.left)?t:[]).filter(e=>!(null!=n&&n.includes(e))),right:(null!=(o=null==e?void 0:e.right)?o:[]).filter(e=>!(null!=n&&n.includes(e)))}})},e.getCanPin=()=>e.getLeafColumns().some(e=>{var l,n,o;return(null==(l=e.columnDef.enablePinning)||l)&&(null==(n=null!=(o=t.options.enableColumnPinning)?o:t.options.enablePinning)||n)}),e.getIsPinned=()=>{let l=e.getLeafColumns().map(e=>e.id),{left:n,right:o}=t.getState().columnPinning,i=l.some(e=>null==n?void 0:n.includes(e)),r=l.some(e=>null==o?void 0:o.includes(e));return i?"left":!!r&&"right"},e.getPinnedIndex=()=>{var l,n;let o=e.getIsPinned();return o?null!=(l=null==(n=t.getState().columnPinning)||null==(n=n[o])?void 0:n.indexOf(e.id))?l:-1:0}},createRow:(e,t)=>{e.getCenterVisibleCells=i(()=>[e._getAllVisibleCells(),t.getState().columnPinning.left,t.getState().columnPinning.right],(e,t,l)=>{let n=[...null!=t?t:[],...null!=l?l:[]];return e.filter(e=>!n.includes(e.column.id))},r(t.options,"debugRows","getCenterVisibleCells")),e.getLeftVisibleCells=i(()=>[e._getAllVisibleCells(),t.getState().columnPinning.left],(e,t)=>(null!=t?t:[]).map(t=>e.find(e=>e.column.id===t)).filter(Boolean).map(e=>({...e,position:"left"})),r(t.options,"debugRows","getLeftVisibleCells")),e.getRightVisibleCells=i(()=>[e._getAllVisibleCells(),t.getState().columnPinning.right],(e,t)=>(null!=t?t:[]).map(t=>e.find(e=>e.column.id===t)).filter(Boolean).map(e=>({...e,position:"right"})),r(t.options,"debugRows","getRightVisibleCells"))},createTable:e=>{e.setColumnPinning=t=>null==e.options.onColumnPinningChange?void 0:e.options.onColumnPinningChange(t),e.resetColumnPinning=t=>{var l,n;return e.setColumnPinning(t?M():null!=(l=null==(n=e.initialState)?void 0:n.columnPinning)?l:M())},e.getIsSomeColumnsPinned=t=>{var l,n,o;let i=e.getState().columnPinning;return t?!!(null==(l=i[t])?void 0:l.length):!!((null==(n=i.left)?void 0:n.length)||(null==(o=i.right)?void 0:o.length))},e.getLeftLeafColumns=i(()=>[e.getAllLeafColumns(),e.getState().columnPinning.left],(e,t)=>(null!=t?t:[]).map(t=>e.find(e=>e.id===t)).filter(Boolean),r(e.options,"debugColumns","getLeftLeafColumns")),e.getRightLeafColumns=i(()=>[e.getAllLeafColumns(),e.getState().columnPinning.right],(e,t)=>(null!=t?t:[]).map(t=>e.find(e=>e.id===t)).filter(Boolean),r(e.options,"debugColumns","getRightLeafColumns")),e.getCenterLeafColumns=i(()=>[e.getAllLeafColumns(),e.getState().columnPinning.left,e.getState().columnPinning.right],(e,t,l)=>{let n=[...null!=t?t:[],...null!=l?l:[]];return e.filter(e=>!n.includes(e.id))},r(e.options,"debugColumns","getCenterLeafColumns"))}},{createColumn:(e,t)=>{e._getFacetedRowModel=t.options.getFacetedRowModel&&t.options.getFacetedRowModel(t,e.id),e.getFacetedRowModel=()=>e._getFacetedRowModel?e._getFacetedRowModel():t.getPreFilteredRowModel(),e._getFacetedUniqueValues=t.options.getFacetedUniqueValues&&t.options.getFacetedUniqueValues(t,e.id),e.getFacetedUniqueValues=()=>e._getFacetedUniqueValues?e._getFacetedUniqueValues():new Map,e._getFacetedMinMaxValues=t.options.getFacetedMinMaxValues&&t.options.getFacetedMinMaxValues(t,e.id),e.getFacetedMinMaxValues=()=>{if(e._getFacetedMinMaxValues)return e._getFacetedMinMaxValues()}}},{getDefaultColumnDef:()=>({filterFn:"auto"}),getInitialState:e=>({columnFilters:[],...e}),getDefaultOptions:e=>({onColumnFiltersChange:n("columnFilters",e),filterFromLeafRows:!1,maxLeafRowFilterDepth:100}),createColumn:(e,t)=>{e.getAutoFilterFn=()=>{let l=t.getCoreRowModel().flatRows[0],n=null==l?void 0:l.getValue(e.id);return"string"==typeof n?v.includesString:"number"==typeof n?v.inNumberRange:"boolean"==typeof n||null!==n&&"object"==typeof n?v.equals:Array.isArray(n)?v.arrIncludes:v.weakEquals},e.getFilterFn=()=>{var l,n;return o(e.columnDef.filterFn)?e.columnDef.filterFn:"auto"===e.columnDef.filterFn?e.getAutoFilterFn():null!=(l=null==(n=t.options.filterFns)?void 0:n[e.columnDef.filterFn])?l:v[e.columnDef.filterFn]},e.getCanFilter=()=>{var l,n,o;return(null==(l=e.columnDef.enableColumnFilter)||l)&&(null==(n=t.options.enableColumnFilters)||n)&&(null==(o=t.options.enableFilters)||o)&&!!e.accessorFn},e.getIsFiltered=()=>e.getFilterIndex()>-1,e.getFilterValue=()=>{var l;return null==(l=t.getState().columnFilters)||null==(l=l.find(t=>t.id===e.id))?void 0:l.value},e.getFilterIndex=()=>{var l,n;return null!=(l=null==(n=t.getState().columnFilters)?void 0:n.findIndex(t=>t.id===e.id))?l:-1},e.setFilterValue=n=>{t.setColumnFilters(t=>{var o,i;let r=e.getFilterFn(),a=null==t?void 0:t.find(t=>t.id===e.id),u=l(n,a?a.value:void 0);if(b(r,u,e))return null!=(o=null==t?void 0:t.filter(t=>t.id!==e.id))?o:[];let g={id:e.id,value:u};return a?null!=(i=null==t?void 0:t.map(t=>t.id===e.id?g:t))?i:[]:null!=t&&t.length?[...t,g]:[g]})}},createRow:(e,t)=>{e.columnFilters={},e.columnFiltersMeta={}},createTable:e=>{e.setColumnFilters=t=>{let n=e.getAllLeafColumns();null==e.options.onColumnFiltersChange||e.options.onColumnFiltersChange(e=>{var o;return null==(o=l(t,e))?void 0:o.filter(e=>{let t=n.find(t=>t.id===e.id);return!(t&&b(t.getFilterFn(),e.value,t))&&!0})})},e.resetColumnFilters=t=>{var l,n;e.setColumnFilters(t?[]:null!=(l=null==(n=e.initialState)?void 0:n.columnFilters)?l:[])},e.getPreFilteredRowModel=()=>e.getCoreRowModel(),e.getFilteredRowModel=()=>(!e._getFilteredRowModel&&e.options.getFilteredRowModel&&(e._getFilteredRowModel=e.options.getFilteredRowModel(e)),e.options.manualFiltering||!e._getFilteredRowModel)?e.getPreFilteredRowModel():e._getFilteredRowModel()}},{createTable:e=>{e._getGlobalFacetedRowModel=e.options.getFacetedRowModel&&e.options.getFacetedRowModel(e,"__global__"),e.getGlobalFacetedRowModel=()=>e.options.manualFiltering||!e._getGlobalFacetedRowModel?e.getPreFilteredRowModel():e._getGlobalFacetedRowModel(),e._getGlobalFacetedUniqueValues=e.options.getFacetedUniqueValues&&e.options.getFacetedUniqueValues(e,"__global__"),e.getGlobalFacetedUniqueValues=()=>e._getGlobalFacetedUniqueValues?e._getGlobalFacetedUniqueValues():new Map,e._getGlobalFacetedMinMaxValues=e.options.getFacetedMinMaxValues&&e.options.getFacetedMinMaxValues(e,"__global__"),e.getGlobalFacetedMinMaxValues=()=>{if(e._getGlobalFacetedMinMaxValues)return e._getGlobalFacetedMinMaxValues()}}},{getInitialState:e=>({globalFilter:void 0,...e}),getDefaultOptions:e=>({onGlobalFilterChange:n("globalFilter",e),globalFilterFn:"auto",getColumnCanGlobalFilter:t=>{var l;let n=null==(l=e.getCoreRowModel().flatRows[0])||null==(l=l._getAllCellsByColumnId()[t.id])?void 0:l.getValue();return"string"==typeof n||"number"==typeof n}}),createColumn:(e,t)=>{e.getCanGlobalFilter=()=>{var l,n,o,i;return(null==(l=e.columnDef.enableGlobalFilter)||l)&&(null==(n=t.options.enableGlobalFilter)||n)&&(null==(o=t.options.enableFilters)||o)&&(null==(i=null==t.options.getColumnCanGlobalFilter?void 0:t.options.getColumnCanGlobalFilter(e))||i)&&!!e.accessorFn}},createTable:e=>{e.getGlobalAutoFilterFn=()=>v.includesString,e.getGlobalFilterFn=()=>{var t,l;let{globalFilterFn:n}=e.options;return o(n)?n:"auto"===n?e.getGlobalAutoFilterFn():null!=(t=null==(l=e.options.filterFns)?void 0:l[n])?t:v[n]},e.setGlobalFilter=t=>{null==e.options.onGlobalFilterChange||e.options.onGlobalFilterChange(t)},e.resetGlobalFilter=t=>{e.setGlobalFilter(t?void 0:e.initialState.globalFilter)}}},{getInitialState:e=>({sorting:[],...e}),getDefaultColumnDef:()=>({sortingFn:"auto",sortUndefined:1}),getDefaultOptions:e=>({onSortingChange:n("sorting",e),isMultiSortEvent:e=>e.shiftKey}),createColumn:(e,t)=>{e.getAutoSortingFn=()=>{let l=t.getFilteredRowModel().flatRows.slice(10),n=!1;for(let t of l){let l=null==t?void 0:t.getValue(e.id);if("[object Date]"===Object.prototype.toString.call(l))return B.datetime;if("string"==typeof l&&(n=!0,l.split(D).length>1))return B.alphanumeric}return n?B.text:B.basic},e.getAutoSortDir=()=>{let l=t.getFilteredRowModel().flatRows[0];return"string"==typeof(null==l?void 0:l.getValue(e.id))?"asc":"desc"},e.getSortingFn=()=>{var l,n;if(!e)throw Error();return o(e.columnDef.sortingFn)?e.columnDef.sortingFn:"auto"===e.columnDef.sortingFn?e.getAutoSortingFn():null!=(l=null==(n=t.options.sortingFns)?void 0:n[e.columnDef.sortingFn])?l:B[e.columnDef.sortingFn]},e.toggleSorting=(l,n)=>{let o=e.getNextSortingOrder(),i=null!=l;t.setSorting(r=>{let a,u=null==r?void 0:r.find(t=>t.id===e.id),g=null==r?void 0:r.findIndex(t=>t.id===e.id),s=[],d=i?l:"desc"===o;if("toggle"!=(a=null!=r&&r.length&&e.getCanMultiSort()&&n?u?"toggle":"add":null!=r&&r.length&&g!==r.length-1?"replace":u?"toggle":"replace")||i||o||(a="remove"),"add"===a){var p;(s=[...r,{id:e.id,desc:d}]).splice(0,s.length-(null!=(p=t.options.maxMultiSortColCount)?p:Number.MAX_SAFE_INTEGER))}else s="toggle"===a?r.map(t=>t.id===e.id?{...t,desc:d}:t):"remove"===a?r.filter(t=>t.id!==e.id):[{id:e.id,desc:d}];return s})},e.getFirstSortDir=()=>{var l,n;return(null!=(l=null!=(n=e.columnDef.sortDescFirst)?n:t.options.sortDescFirst)?l:"desc"===e.getAutoSortDir())?"desc":"asc"},e.getNextSortingOrder=l=>{var n,o;let i=e.getFirstSortDir(),r=e.getIsSorted();return r?(r===i||null!=(n=t.options.enableSortingRemoval)&&!n||!!l&&null!=(o=t.options.enableMultiRemove)&&!o)&&("desc"===r?"asc":"desc"):i},e.getCanSort=()=>{var l,n;return(null==(l=e.columnDef.enableSorting)||l)&&(null==(n=t.options.enableSorting)||n)&&!!e.accessorFn},e.getCanMultiSort=()=>{var l,n;return null!=(l=null!=(n=e.columnDef.enableMultiSort)?n:t.options.enableMultiSort)?l:!!e.accessorFn},e.getIsSorted=()=>{var l;let n=null==(l=t.getState().sorting)?void 0:l.find(t=>t.id===e.id);return!!n&&(n.desc?"desc":"asc")},e.getSortIndex=()=>{var l,n;return null!=(l=null==(n=t.getState().sorting)?void 0:n.findIndex(t=>t.id===e.id))?l:-1},e.clearSorting=()=>{t.setSorting(t=>null!=t&&t.length?t.filter(t=>t.id!==e.id):[])},e.getToggleSortingHandler=()=>{let l=e.getCanSort();return n=>{l&&(null==n.persist||n.persist(),null==e.toggleSorting||e.toggleSorting(void 0,!!e.getCanMultiSort()&&(null==t.options.isMultiSortEvent?void 0:t.options.isMultiSortEvent(n))))}}},createTable:e=>{e.setSorting=t=>null==e.options.onSortingChange?void 0:e.options.onSortingChange(t),e.resetSorting=t=>{var l,n;e.setSorting(t?[]:null!=(l=null==(n=e.initialState)?void 0:n.sorting)?l:[])},e.getPreSortedRowModel=()=>e.getGroupedRowModel(),e.getSortedRowModel=()=>(!e._getSortedRowModel&&e.options.getSortedRowModel&&(e._getSortedRowModel=e.options.getSortedRowModel(e)),e.options.manualSorting||!e._getSortedRowModel)?e.getPreSortedRowModel():e._getSortedRowModel()}},{getDefaultColumnDef:()=>({aggregatedCell:e=>{var t,l;return null!=(t=null==(l=e.getValue())||null==l.toString?void 0:l.toString())?t:null},aggregationFn:"auto"}),getInitialState:e=>({grouping:[],...e}),getDefaultOptions:e=>({onGroupingChange:n("grouping",e),groupedColumnMode:"reorder"}),createColumn:(e,t)=>{e.toggleGrouping=()=>{t.setGrouping(t=>null!=t&&t.includes(e.id)?t.filter(t=>t!==e.id):[...null!=t?t:[],e.id])},e.getCanGroup=()=>{var l,n;return(null==(l=e.columnDef.enableGrouping)||l)&&(null==(n=t.options.enableGrouping)||n)&&(!!e.accessorFn||!!e.columnDef.getGroupingValue)},e.getIsGrouped=()=>{var l;return null==(l=t.getState().grouping)?void 0:l.includes(e.id)},e.getGroupedIndex=()=>{var l;return null==(l=t.getState().grouping)?void 0:l.indexOf(e.id)},e.getToggleGroupingHandler=()=>{let t=e.getCanGroup();return()=>{t&&e.toggleGrouping()}},e.getAutoAggregationFn=()=>{let l=t.getCoreRowModel().flatRows[0],n=null==l?void 0:l.getValue(e.id);return"number"==typeof n?F.sum:"[object Date]"===Object.prototype.toString.call(n)?F.extent:void 0},e.getAggregationFn=()=>{var l,n;if(!e)throw Error();return o(e.columnDef.aggregationFn)?e.columnDef.aggregationFn:"auto"===e.columnDef.aggregationFn?e.getAutoAggregationFn():null!=(l=null==(n=t.options.aggregationFns)?void 0:n[e.columnDef.aggregationFn])?l:F[e.columnDef.aggregationFn]}},createTable:e=>{e.setGrouping=t=>null==e.options.onGroupingChange?void 0:e.options.onGroupingChange(t),e.resetGrouping=t=>{var l,n;e.setGrouping(t?[]:null!=(l=null==(n=e.initialState)?void 0:n.grouping)?l:[])},e.getPreGroupedRowModel=()=>e.getFilteredRowModel(),e.getGroupedRowModel=()=>(!e._getGroupedRowModel&&e.options.getGroupedRowModel&&(e._getGroupedRowModel=e.options.getGroupedRowModel(e)),e.options.manualGrouping||!e._getGroupedRowModel)?e.getPreGroupedRowModel():e._getGroupedRowModel()},createRow:(e,t)=>{e.getIsGrouped=()=>!!e.groupingColumnId,e.getGroupingValue=l=>{if(e._groupingValuesCache.hasOwnProperty(l))return e._groupingValuesCache[l];let n=t.getColumn(l);return null!=n&&n.columnDef.getGroupingValue?(e._groupingValuesCache[l]=n.columnDef.getGroupingValue(e.original),e._groupingValuesCache[l]):e.getValue(l)},e._groupingValuesCache={}},createCell:(e,t,l,n)=>{e.getIsGrouped=()=>t.getIsGrouped()&&t.id===l.groupingColumnId,e.getIsPlaceholder=()=>!e.getIsGrouped()&&t.getIsGrouped(),e.getIsAggregated=()=>{var t;return!e.getIsGrouped()&&!e.getIsPlaceholder()&&!!(null!=(t=l.subRows)&&t.length)}}},{getInitialState:e=>({expanded:{},...e}),getDefaultOptions:e=>({onExpandedChange:n("expanded",e),paginateExpandedRows:!0}),createTable:e=>{let t=!1,l=!1;e._autoResetExpanded=()=>{var n,o;if(!t)return void e._queue(()=>{t=!0});if(null!=(n=null!=(o=e.options.autoResetAll)?o:e.options.autoResetExpanded)?n:!e.options.manualExpanding){if(l)return;l=!0,e._queue(()=>{e.resetExpanded(),l=!1})}},e.setExpanded=t=>null==e.options.onExpandedChange?void 0:e.options.onExpandedChange(t),e.toggleAllRowsExpanded=t=>{(null!=t?t:!e.getIsAllRowsExpanded())?e.setExpanded(!0):e.setExpanded({})},e.resetExpanded=t=>{var l,n;e.setExpanded(t?{}:null!=(l=null==(n=e.initialState)?void 0:n.expanded)?l:{})},e.getCanSomeRowsExpand=()=>e.getPrePaginationRowModel().flatRows.some(e=>e.getCanExpand()),e.getToggleAllRowsExpandedHandler=()=>t=>{null==t.persist||t.persist(),e.toggleAllRowsExpanded()},e.getIsSomeRowsExpanded=()=>{let t=e.getState().expanded;return!0===t||Object.values(t).some(Boolean)},e.getIsAllRowsExpanded=()=>{let t=e.getState().expanded;return"boolean"==typeof t?!0===t:!(!Object.keys(t).length||e.getRowModel().flatRows.some(e=>!e.getIsExpanded()))},e.getExpandedDepth=()=>{let t=0;return(!0===e.getState().expanded?Object.keys(e.getRowModel().rowsById):Object.keys(e.getState().expanded)).forEach(e=>{let l=e.split(".");t=Math.max(t,l.length)}),t},e.getPreExpandedRowModel=()=>e.getSortedRowModel(),e.getExpandedRowModel=()=>(!e._getExpandedRowModel&&e.options.getExpandedRowModel&&(e._getExpandedRowModel=e.options.getExpandedRowModel(e)),e.options.manualExpanding||!e._getExpandedRowModel)?e.getPreExpandedRowModel():e._getExpandedRowModel()},createRow:(e,t)=>{e.toggleExpanded=l=>{t.setExpanded(n=>{var o;let i=!0===n||!!(null!=n&&n[e.id]),r={};if(!0===n?Object.keys(t.getRowModel().rowsById).forEach(e=>{r[e]=!0}):r=n,l=null!=(o=l)?o:!i,!i&&l)return{...r,[e.id]:!0};if(i&&!l){let{[e.id]:t,...l}=r;return l}return n})},e.getIsExpanded=()=>{var l;let n=t.getState().expanded;return!!(null!=(l=null==t.options.getIsRowExpanded?void 0:t.options.getIsRowExpanded(e))?l:!0===n||(null==n?void 0:n[e.id]))},e.getCanExpand=()=>{var l,n,o;return null!=(l=null==t.options.getRowCanExpand?void 0:t.options.getRowCanExpand(e))?l:(null==(n=t.options.enableExpanding)||n)&&!!(null!=(o=e.subRows)&&o.length)},e.getIsAllParentsExpanded=()=>{let l=!0,n=e;for(;l&&n.parentId;)l=(n=t.getRow(n.parentId,!0)).getIsExpanded();return l},e.getToggleExpandedHandler=()=>{let t=e.getCanExpand();return()=>{t&&e.toggleExpanded()}}}},{getInitialState:e=>({...e,pagination:{...y(),...null==e?void 0:e.pagination}}),getDefaultOptions:e=>({onPaginationChange:n("pagination",e)}),createTable:e=>{let t=!1,n=!1;e._autoResetPageIndex=()=>{var l,o;if(!t)return void e._queue(()=>{t=!0});if(null!=(l=null!=(o=e.options.autoResetAll)?o:e.options.autoResetPageIndex)?l:!e.options.manualPagination){if(n)return;n=!0,e._queue(()=>{e.resetPageIndex(),n=!1})}},e.setPagination=t=>null==e.options.onPaginationChange?void 0:e.options.onPaginationChange(e=>l(t,e)),e.resetPagination=t=>{var l;e.setPagination(t?y():null!=(l=e.initialState.pagination)?l:y())},e.setPageIndex=t=>{e.setPagination(n=>{let o=l(t,n.pageIndex);return o=Math.max(0,Math.min(o,void 0===e.options.pageCount||-1===e.options.pageCount?Number.MAX_SAFE_INTEGER:e.options.pageCount-1)),{...n,pageIndex:o}})},e.resetPageIndex=t=>{var l,n;e.setPageIndex(t?0:null!=(l=null==(n=e.initialState)||null==(n=n.pagination)?void 0:n.pageIndex)?l:0)},e.resetPageSize=t=>{var l,n;e.setPageSize(t?10:null!=(l=null==(n=e.initialState)||null==(n=n.pagination)?void 0:n.pageSize)?l:10)},e.setPageSize=t=>{e.setPagination(e=>{let n=Math.max(1,l(t,e.pageSize)),o=Math.floor(e.pageSize*e.pageIndex/n);return{...e,pageIndex:o,pageSize:n}})},e.setPageCount=t=>e.setPagination(n=>{var o;let i=l(t,null!=(o=e.options.pageCount)?o:-1);return"number"==typeof i&&(i=Math.max(-1,i)),{...n,pageCount:i}}),e.getPageOptions=i(()=>[e.getPageCount()],e=>{let t=[];return e&&e>0&&(t=[...Array(e)].fill(null).map((e,t)=>t)),t},r(e.options,"debugTable","getPageOptions")),e.getCanPreviousPage=()=>e.getState().pagination.pageIndex>0,e.getCanNextPage=()=>{let{pageIndex:t}=e.getState().pagination,l=e.getPageCount();return -1===l||0!==l&&te.setPageIndex(e=>e-1),e.nextPage=()=>e.setPageIndex(e=>e+1),e.firstPage=()=>e.setPageIndex(0),e.lastPage=()=>e.setPageIndex(e.getPageCount()-1),e.getPrePaginationRowModel=()=>e.getExpandedRowModel(),e.getPaginationRowModel=()=>(!e._getPaginationRowModel&&e.options.getPaginationRowModel&&(e._getPaginationRowModel=e.options.getPaginationRowModel(e)),e.options.manualPagination||!e._getPaginationRowModel)?e.getPrePaginationRowModel():e._getPaginationRowModel(),e.getPageCount=()=>{var t;return null!=(t=e.options.pageCount)?t:Math.ceil(e.getRowCount()/e.getState().pagination.pageSize)},e.getRowCount=()=>{var t;return null!=(t=e.options.rowCount)?t:e.getPrePaginationRowModel().rows.length}}},{getInitialState:e=>({rowPinning:E(),...e}),getDefaultOptions:e=>({onRowPinningChange:n("rowPinning",e)}),createRow:(e,t)=>{e.pin=(l,n,o)=>{let i=n?e.getLeafRows().map(e=>{let{id:t}=e;return t}):[],r=new Set([...o?e.getParentRows().map(e=>{let{id:t}=e;return t}):[],e.id,...i]);t.setRowPinning(e=>{var t,n,o,i,a,u;return"bottom"===l?{top:(null!=(o=null==e?void 0:e.top)?o:[]).filter(e=>!(null!=r&&r.has(e))),bottom:[...(null!=(i=null==e?void 0:e.bottom)?i:[]).filter(e=>!(null!=r&&r.has(e))),...Array.from(r)]}:"top"===l?{top:[...(null!=(a=null==e?void 0:e.top)?a:[]).filter(e=>!(null!=r&&r.has(e))),...Array.from(r)],bottom:(null!=(u=null==e?void 0:e.bottom)?u:[]).filter(e=>!(null!=r&&r.has(e)))}:{top:(null!=(t=null==e?void 0:e.top)?t:[]).filter(e=>!(null!=r&&r.has(e))),bottom:(null!=(n=null==e?void 0:e.bottom)?n:[]).filter(e=>!(null!=r&&r.has(e)))}})},e.getCanPin=()=>{var l;let{enableRowPinning:n,enablePinning:o}=t.options;return"function"==typeof n?n(e):null==(l=null!=n?n:o)||l},e.getIsPinned=()=>{let l=[e.id],{top:n,bottom:o}=t.getState().rowPinning,i=l.some(e=>null==n?void 0:n.includes(e)),r=l.some(e=>null==o?void 0:o.includes(e));return i?"top":!!r&&"bottom"},e.getPinnedIndex=()=>{var l,n;let o=e.getIsPinned();if(!o)return -1;let i=null==(l="top"===o?t.getTopRows():t.getBottomRows())?void 0:l.map(e=>{let{id:t}=e;return t});return null!=(n=null==i?void 0:i.indexOf(e.id))?n:-1}},createTable:e=>{e.setRowPinning=t=>null==e.options.onRowPinningChange?void 0:e.options.onRowPinningChange(t),e.resetRowPinning=t=>{var l,n;return e.setRowPinning(t?E():null!=(l=null==(n=e.initialState)?void 0:n.rowPinning)?l:E())},e.getIsSomeRowsPinned=t=>{var l,n,o;let i=e.getState().rowPinning;return t?!!(null==(l=i[t])?void 0:l.length):!!((null==(n=i.top)?void 0:n.length)||(null==(o=i.bottom)?void 0:o.length))},e._getPinnedRows=(t,l,n)=>{var o;return(null==(o=e.options.keepPinnedRows)||o?(null!=l?l:[]).map(t=>{let l=e.getRow(t,!0);return l.getIsAllParentsExpanded()?l:null}):(null!=l?l:[]).map(e=>t.find(t=>t.id===e))).filter(Boolean).map(e=>({...e,position:n}))},e.getTopRows=i(()=>[e.getRowModel().rows,e.getState().rowPinning.top],(t,l)=>e._getPinnedRows(t,l,"top"),r(e.options,"debugRows","getTopRows")),e.getBottomRows=i(()=>[e.getRowModel().rows,e.getState().rowPinning.bottom],(t,l)=>e._getPinnedRows(t,l,"bottom"),r(e.options,"debugRows","getBottomRows")),e.getCenterRows=i(()=>[e.getRowModel().rows,e.getState().rowPinning.top,e.getState().rowPinning.bottom],(e,t,l)=>{let n=new Set([...null!=t?t:[],...null!=l?l:[]]);return e.filter(e=>!n.has(e.id))},r(e.options,"debugRows","getCenterRows"))}},{getInitialState:e=>({rowSelection:{},...e}),getDefaultOptions:e=>({onRowSelectionChange:n("rowSelection",e),enableRowSelection:!0,enableMultiRowSelection:!0,enableSubRowSelection:!0}),createTable:e=>{e.setRowSelection=t=>null==e.options.onRowSelectionChange?void 0:e.options.onRowSelectionChange(t),e.resetRowSelection=t=>{var l;return e.setRowSelection(t?{}:null!=(l=e.initialState.rowSelection)?l:{})},e.toggleAllRowsSelected=t=>{e.setRowSelection(l=>{t=void 0!==t?t:!e.getIsAllRowsSelected();let n={...l},o=e.getPreGroupedRowModel().flatRows;return t?o.forEach(e=>{e.getCanSelect()&&(n[e.id]=!0)}):o.forEach(e=>{delete n[e.id]}),n})},e.toggleAllPageRowsSelected=t=>e.setRowSelection(l=>{let n=void 0!==t?t:!e.getIsAllPageRowsSelected(),o={...l};return e.getRowModel().rows.forEach(t=>{G(o,t.id,n,!0,e)}),o}),e.getPreSelectedRowModel=()=>e.getCoreRowModel(),e.getSelectedRowModel=i(()=>[e.getState().rowSelection,e.getCoreRowModel()],(t,l)=>Object.keys(t).length?L(e,l):{rows:[],flatRows:[],rowsById:{}},r(e.options,"debugTable","getSelectedRowModel")),e.getFilteredSelectedRowModel=i(()=>[e.getState().rowSelection,e.getFilteredRowModel()],(t,l)=>Object.keys(t).length?L(e,l):{rows:[],flatRows:[],rowsById:{}},r(e.options,"debugTable","getFilteredSelectedRowModel")),e.getGroupedSelectedRowModel=i(()=>[e.getState().rowSelection,e.getSortedRowModel()],(t,l)=>Object.keys(t).length?L(e,l):{rows:[],flatRows:[],rowsById:{}},r(e.options,"debugTable","getGroupedSelectedRowModel")),e.getIsAllRowsSelected=()=>{let t=e.getFilteredRowModel().flatRows,{rowSelection:l}=e.getState(),n=!!(t.length&&Object.keys(l).length);return n&&t.some(e=>e.getCanSelect()&&!l[e.id])&&(n=!1),n},e.getIsAllPageRowsSelected=()=>{let t=e.getPaginationRowModel().flatRows.filter(e=>e.getCanSelect()),{rowSelection:l}=e.getState(),n=!!t.length;return n&&t.some(e=>!l[e.id])&&(n=!1),n},e.getIsSomeRowsSelected=()=>{var t;let l=Object.keys(null!=(t=e.getState().rowSelection)?t:{}).length;return l>0&&l{let t=e.getPaginationRowModel().flatRows;return!e.getIsAllPageRowsSelected()&&t.filter(e=>e.getCanSelect()).some(e=>e.getIsSelected()||e.getIsSomeSelected())},e.getToggleAllRowsSelectedHandler=()=>t=>{e.toggleAllRowsSelected(t.target.checked)},e.getToggleAllPageRowsSelectedHandler=()=>t=>{e.toggleAllPageRowsSelected(t.target.checked)}},createRow:(e,t)=>{e.toggleSelected=(l,n)=>{let o=e.getIsSelected();t.setRowSelection(i=>{var r;if(l=void 0!==l?l:!o,e.getCanSelect()&&o===l)return i;let a={...i};return G(a,e.id,l,null==(r=null==n?void 0:n.selectChildren)||r,t),a})},e.getIsSelected=()=>{let{rowSelection:l}=t.getState();return A(e,l)},e.getIsSomeSelected=()=>{let{rowSelection:l}=t.getState();return"some"===H(e,l)},e.getIsAllSubRowsSelected=()=>{let{rowSelection:l}=t.getState();return"all"===H(e,l)},e.getCanSelect=()=>{var l;return"function"==typeof t.options.enableRowSelection?t.options.enableRowSelection(e):null==(l=t.options.enableRowSelection)||l},e.getCanSelectSubRows=()=>{var l;return"function"==typeof t.options.enableSubRowSelection?t.options.enableSubRowSelection(e):null==(l=t.options.enableSubRowSelection)||l},e.getCanMultiSelect=()=>{var l;return"function"==typeof t.options.enableMultiRowSelection?t.options.enableMultiRowSelection(e):null==(l=t.options.enableMultiRowSelection)||l},e.getToggleSelectedHandler=()=>{let t=e.getCanSelect();return l=>{var n;t&&e.toggleSelected(null==(n=l.target)?void 0:n.checked)}}}},{getDefaultColumnDef:()=>V,getInitialState:e=>({columnSizing:{},columnSizingInfo:P(),...e}),getDefaultOptions:e=>({columnResizeMode:"onEnd",columnResizeDirection:"ltr",onColumnSizingChange:n("columnSizing",e),onColumnSizingInfoChange:n("columnSizingInfo",e)}),createColumn:(e,t)=>{e.getSize=()=>{var l,n,o;let i=t.getState().columnSizing[e.id];return Math.min(Math.max(null!=(l=e.columnDef.minSize)?l:V.minSize,null!=(n=null!=i?i:e.columnDef.size)?n:V.size),null!=(o=e.columnDef.maxSize)?o:V.maxSize)},e.getStart=i(e=>[e,_(t,e),t.getState().columnSizing],(t,l)=>l.slice(0,e.getIndex(t)).reduce((e,t)=>e+t.getSize(),0),r(t.options,"debugColumns","getStart")),e.getAfter=i(e=>[e,_(t,e),t.getState().columnSizing],(t,l)=>l.slice(e.getIndex(t)+1).reduce((e,t)=>e+t.getSize(),0),r(t.options,"debugColumns","getAfter")),e.resetSize=()=>{t.setColumnSizing(t=>{let{[e.id]:l,...n}=t;return n})},e.getCanResize=()=>{var l,n;return(null==(l=e.columnDef.enableResizing)||l)&&(null==(n=t.options.enableColumnResizing)||n)},e.getIsResizing=()=>t.getState().columnSizingInfo.isResizingColumn===e.id},createHeader:(e,t)=>{e.getSize=()=>{let t=0,l=e=>{if(e.subHeaders.length)e.subHeaders.forEach(l);else{var n;t+=null!=(n=e.column.getSize())?n:0}};return l(e),t},e.getStart=()=>{if(e.index>0){let t=e.headerGroup.headers[e.index-1];return t.getStart()+t.getSize()}return 0},e.getResizeHandler=l=>{let n=t.getColumn(e.column.id),o=null==n?void 0:n.getCanResize();return i=>{if(!n||!o||(null==i.persist||i.persist(),x(i)&&i.touches&&i.touches.length>1))return;let r=e.getSize(),a=e?e.getLeafHeaders().map(e=>[e.column.id,e.column.getSize()]):[[n.id,n.getSize()]],u=x(i)?Math.round(i.touches[0].clientX):i.clientX,g={},s=(e,l)=>{"number"==typeof l&&(t.setColumnSizingInfo(e=>{var n,o;let i="rtl"===t.options.columnResizeDirection?-1:1,r=(l-(null!=(n=null==e?void 0:e.startOffset)?n:0))*i,a=Math.max(r/(null!=(o=null==e?void 0:e.startSize)?o:0),-.999999);return e.columnSizingStart.forEach(e=>{let[t,l]=e;g[t]=Math.round(100*Math.max(l+l*a,0))/100}),{...e,deltaOffset:r,deltaPercentage:a}}),("onChange"===t.options.columnResizeMode||"end"===e)&&t.setColumnSizing(e=>({...e,...g})))},d=e=>{s("end",e),t.setColumnSizingInfo(e=>({...e,isResizingColumn:!1,startOffset:null,startSize:null,deltaOffset:null,deltaPercentage:null,columnSizingStart:[]}))},p=l||("u">typeof document?document:null),c={moveHandler:e=>s("move",e.clientX),upHandler:e=>{null==p||p.removeEventListener("mousemove",c.moveHandler),null==p||p.removeEventListener("mouseup",c.upHandler),d(e.clientX)}},f={moveHandler:e=>(e.cancelable&&(e.preventDefault(),e.stopPropagation()),s("move",e.touches[0].clientX),!1),upHandler:e=>{var t;null==p||p.removeEventListener("touchmove",f.moveHandler),null==p||p.removeEventListener("touchend",f.upHandler),e.cancelable&&(e.preventDefault(),e.stopPropagation()),d(null==(t=e.touches[0])?void 0:t.clientX)}},m=!!function(){if("boolean"==typeof I)return I;let e=!1;try{let t=()=>{};window.addEventListener("test",t,{get passive(){return e=!0,!1}}),window.removeEventListener("test",t)}catch(t){e=!1}return I=e}()&&{passive:!1};x(i)?(null==p||p.addEventListener("touchmove",f.moveHandler,m),null==p||p.addEventListener("touchend",f.upHandler,m)):(null==p||p.addEventListener("mousemove",c.moveHandler,m),null==p||p.addEventListener("mouseup",c.upHandler,m)),t.setColumnSizingInfo(e=>({...e,startOffset:u,startSize:r,deltaOffset:0,deltaPercentage:0,columnSizingStart:a,isResizingColumn:n.id}))}}},createTable:e=>{e.setColumnSizing=t=>null==e.options.onColumnSizingChange?void 0:e.options.onColumnSizingChange(t),e.setColumnSizingInfo=t=>null==e.options.onColumnSizingInfoChange?void 0:e.options.onColumnSizingInfoChange(t),e.resetColumnSizing=t=>{var l;e.setColumnSizing(t?{}:null!=(l=e.initialState.columnSizing)?l:{})},e.resetHeaderSizeInfo=t=>{var l;e.setColumnSizingInfo(t?P():null!=(l=e.initialState.columnSizingInfo)?l:P())},e.getTotalSize=()=>{var t,l;return null!=(t=null==(l=e.getHeaderGroups()[0])?void 0:l.headers.reduce((e,t)=>e+t.getSize(),0))?t:0},e.getLeftTotalSize=()=>{var t,l;return null!=(t=null==(l=e.getLeftHeaderGroups()[0])?void 0:l.headers.reduce((e,t)=>e+t.getSize(),0))?t:0},e.getCenterTotalSize=()=>{var t,l;return null!=(t=null==(l=e.getCenterHeaderGroups()[0])?void 0:l.headers.reduce((e,t)=>e+t.getSize(),0))?t:0},e.getRightTotalSize=()=>{var t,l;return null!=(t=null==(l=e.getRightHeaderGroups()[0])?void 0:l.headers.reduce((e,t)=>e+t.getSize(),0))?t:0}}}];function j(e){var t,n;let o=[...q,...null!=(t=e._features)?t:[]],a={_features:o},u=a._features.reduce((e,t)=>Object.assign(e,null==t.getDefaultOptions?void 0:t.getDefaultOptions(a)),{}),g={...null!=(n=e.initialState)?n:{}};a._features.forEach(e=>{var t;g=null!=(t=null==e.getInitialState?void 0:e.getInitialState(g))?t:g});let s=[],d=!1,p={_features:o,options:{...u,...e},initialState:g,_queue:e=>{s.push(e),d||(d=!0,Promise.resolve().then(()=>{for(;s.length;)s.shift()();d=!1}).catch(e=>setTimeout(()=>{throw e})))},reset:()=>{a.setState(a.initialState)},setOptions:e=>{var t;t=l(e,a.options),a.options=a.options.mergeOptions?a.options.mergeOptions(u,t):{...u,...t}},getState:()=>a.options.state,setState:e=>{null==a.options.onStateChange||a.options.onStateChange(e)},_getRowId:(e,t,l)=>{var n;return null!=(n=null==a.options.getRowId?void 0:a.options.getRowId(e,t,l))?n:`${l?[l.id,t].join("."):t}`},getCoreRowModel:()=>(a._getCoreRowModel||(a._getCoreRowModel=a.options.getCoreRowModel(a)),a._getCoreRowModel()),getRowModel:()=>a.getPaginationRowModel(),getRow:(e,t)=>{let l=(t?a.getPrePaginationRowModel():a.getRowModel()).rowsById[e];if(!l&&!(l=a.getCoreRowModel().rowsById[e]))throw Error();return l},_getDefaultColumnDef:i(()=>[a.options.defaultColumn],e=>{var t;return e=null!=(t=e)?t:{},{header:e=>{let t=e.header.column.columnDef;return t.accessorKey?t.accessorKey:t.accessorFn?t.id:null},cell:e=>{var t,l;return null!=(t=null==(l=e.renderValue())||null==l.toString?void 0:l.toString())?t:null},...a._features.reduce((e,t)=>Object.assign(e,null==t.getDefaultColumnDef?void 0:t.getDefaultColumnDef()),{}),...e}},r(e,"debugColumns","_getDefaultColumnDef")),_getColumnDefs:()=>a.options.columns,getAllColumns:i(()=>[a._getColumnDefs()],e=>{let t=function(e,l,n){return void 0===n&&(n=0),e.map(e=>{let o=function(e,t,l,n){var o,a;let u,g={...e._getDefaultColumnDef(),...t},s=g.accessorKey,d=null!=(o=null!=(a=g.id)?a:s?"function"==typeof String.prototype.replaceAll?s.replaceAll(".","_"):s.replace(/\./g,"_"):void 0)?o:"string"==typeof g.header?g.header:void 0;if(g.accessorFn?u=g.accessorFn:s&&(u=s.includes(".")?e=>{let t=e;for(let e of s.split(".")){var l;t=null==(l=t)?void 0:l[e]}return t}:e=>e[g.accessorKey]),!d)throw Error();let p={id:`${String(d)}`,accessorFn:u,parent:n,depth:l,columnDef:g,columns:[],getFlatColumns:i(()=>[!0],()=>{var e;return[p,...null==(e=p.columns)?void 0:e.flatMap(e=>e.getFlatColumns())]},r(e.options,"debugColumns","column.getFlatColumns")),getLeafColumns:i(()=>[e._getOrderColumnsFn()],e=>{var t;return null!=(t=p.columns)&&t.length?e(p.columns.flatMap(e=>e.getLeafColumns())):[p]},r(e.options,"debugColumns","column.getLeafColumns"))};for(let t of e._features)null==t.createColumn||t.createColumn(p,e);return p}(a,e,n,l);return o.columns=e.columns?t(e.columns,o,n+1):[],o})};return t(e)},r(e,"debugColumns","getAllColumns")),getAllFlatColumns:i(()=>[a.getAllColumns()],e=>e.flatMap(e=>e.getFlatColumns()),r(e,"debugColumns","getAllFlatColumns")),_getAllFlatColumnsById:i(()=>[a.getAllFlatColumns()],e=>e.reduce((e,t)=>(e[t.id]=t,e),{}),r(e,"debugColumns","getAllFlatColumnsById")),getAllLeafColumns:i(()=>[a.getAllColumns(),a._getOrderColumnsFn()],(e,t)=>t(e.flatMap(e=>e.getLeafColumns())),r(e,"debugColumns","getAllLeafColumns")),getColumn:e=>a._getAllFlatColumnsById()[e]};Object.assign(a,p);for(let e=0;e{var n;t.push(e),null!=(n=e.subRows)&&n.length&&e.getIsExpanded()&&e.subRows.forEach(l)};return e.rows.forEach(l),{rows:t,flatRows:e.flatRows,rowsById:e.rowsById}}e.s(["createTable",0,j,"getCoreRowModel",0,function(){return e=>i(()=>[e.options.data],t=>{let l={rows:[],flatRows:[],rowsById:{}},n=function(t,o,i){void 0===o&&(o=0);let r=[];for(let u=0;ue._autoResetPageIndex()))},"getExpandedRowModel",0,function(){return e=>i(()=>[e.getState().expanded,e.getPreExpandedRowModel(),e.options.paginateExpandedRows],(e,t,l)=>t.rows.length&&(!0===e||Object.keys(null!=e?e:{}).length)&&l?k(t):t,r(e.options,"debugTable","getExpandedRowModel"))},"getPaginationRowModel",0,function(e){return e=>i(()=>[e.getState().pagination,e.getPrePaginationRowModel(),e.options.paginateExpandedRows?void 0:e.getState().expanded],(t,l)=>{let n;if(!l.rows.length)return l;let{pageSize:o,pageIndex:i}=t,{rows:r,flatRows:a,rowsById:u}=l,g=o*i;r=r.slice(g,g+o),(n=e.options.paginateExpandedRows?{rows:r,flatRows:a,rowsById:u}:k({rows:r,flatRows:a,rowsById:u})).flatRows=[];let s=e=>{n.flatRows.push(e),e.subRows.length&&e.subRows.forEach(s)};return n.rows.forEach(s),n},r(e.options,"debugTable","getPaginationRowModel"))},"getSortedRowModel",0,function(){return e=>i(()=>[e.getState().sorting,e.getPreSortedRowModel()],(t,l)=>{if(!l.rows.length||!(null!=t&&t.length))return l;let n=e.getState().sorting,o=[],i=n.filter(t=>{var l;return null==(l=e.getColumn(t.id))?void 0:l.getCanSort()}),r={};i.forEach(t=>{let l=e.getColumn(t.id);l&&(r[t.id]={sortUndefined:l.columnDef.sortUndefined,invertSorting:l.columnDef.invertSorting,sortingFn:l.getSortingFn()})});let a=e=>{let t=e.map(e=>({...e}));return t.sort((e,t)=>{for(let n=0;n{var t;o.push(e),null!=(t=e.subRows)&&t.length&&(e.subRows=a(e.subRows))}),t};return{rows:a(l.rows),flatRows:o,rowsById:l.rowsById}},r(e.options,"debugTable","getSortedRowModel",()=>e._autoResetPageIndex()))}],682830),e.s(["flexRender",0,function(e,l){var n,o,i;let r;return e?"function"==typeof(o=n=e)&&(r=Object.getPrototypeOf(o)).prototype&&r.prototype.isReactComponent||"function"==typeof n||"object"==typeof(i=n)&&"symbol"==typeof i.$$typeof&&["react.memo","react.forward_ref"].includes(i.$$typeof.description)?t.createElement(e,l):e:null},"useReactTable",0,function(e){let l={state:{},onStateChange:()=>{},renderFallbackValue:null,...e},[n]=t.useState(()=>({current:j(l)})),[o,i]=t.useState(()=>n.current.initialState);return n.current.setOptions(t=>({...t,...e,state:{...o,...e.state},onStateChange:t=>{i(t),null==e.onStateChange||e.onStateChange(t)}})),n.current}],152990)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/010e8lif45kbo.js b/litellm/proxy/_experimental/out/_next/static/chunks/010e8lif45kbo.js new file mode 100644 index 00000000000..6cdee9105cd --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/010e8lif45kbo.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,362024,e=>{"use strict";var r=e.i(988122);e.s(["Collapse",()=>r.default])},21548,e=>{"use strict";var r=e.i(616303);e.s(["Empty",()=>r.default])},166406,e=>{"use strict";var r=e.i(190144);e.s(["CopyOutlined",()=>r.default])},599724,936325,e=>{"use strict";var r=e.i(95779),t=e.i(444755),a=e.i(673706),o=e.i(271645);let l=o.default.forwardRef((e,l)=>{let{color:s,className:n,children:i}=e;return o.default.createElement("p",{ref:l,className:(0,t.tremorTwMerge)("text-tremor-default",s?(0,a.getColorClassNames)(s,r.colorPalette.text).textColor:(0,t.tremorTwMerge)("text-tremor-content","dark:text-dark-tremor-content"),n)},i)});l.displayName="Text",e.s(["default",0,l],936325),e.s(["Text",0,l],599724)},994388,e=>{"use strict";var r=e.i(290571),t=e.i(829087),a=e.i(271645);let o=["preEnter","entering","entered","preExit","exiting","exited","unmounted"],l=e=>({_s:e,status:o[e],isEnter:e<3,isMounted:6!==e,isResolved:2===e||e>4}),s=e=>e?6:5,n=(e,r,t,a,o)=>{clearTimeout(a.current);let s=l(e);r(s),t.current=s,o&&o({current:s})};var i=e.i(480731),d=e.i(444755),c=e.i(673706);let m=e=>{var t=(0,r.__rest)(e,[]);return a.default.createElement("svg",Object.assign({},t,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"}),a.default.createElement("path",{fill:"none",d:"M0 0h24v24H0z"}),a.default.createElement("path",{d:"M18.364 5.636L16.95 7.05A7 7 0 1 0 19 12h2a9 9 0 1 1-2.636-6.364z"}))};var u=e.i(95779);let f={xs:{height:"h-4",width:"w-4"},sm:{height:"h-5",width:"w-5"},md:{height:"h-5",width:"w-5"},lg:{height:"h-6",width:"w-6"},xl:{height:"h-6",width:"w-6"}},g=(e,r)=>{switch(e){case"primary":return{textColor:r?(0,c.getColorClassNames)("white").textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",hoverTextColor:r?(0,c.getColorClassNames)("white").textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:r?(0,c.getColorClassNames)(r,u.colorPalette.background).bgColor:"bg-tremor-brand dark:bg-dark-tremor-brand",hoverBgColor:r?(0,c.getColorClassNames)(r,u.colorPalette.darkBackground).hoverBgColor:"hover:bg-tremor-brand-emphasis dark:hover:bg-dark-tremor-brand-emphasis",borderColor:r?(0,c.getColorClassNames)(r,u.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand",hoverBorderColor:r?(0,c.getColorClassNames)(r,u.colorPalette.darkBorder).hoverBorderColor:"hover:border-tremor-brand-emphasis dark:hover:border-dark-tremor-brand-emphasis"};case"secondary":return{textColor:r?(0,c.getColorClassNames)(r,u.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",hoverTextColor:r?(0,c.getColorClassNames)(r,u.colorPalette.text).textColor:"hover:text-tremor-brand-emphasis dark:hover:text-dark-tremor-brand-emphasis",bgColor:(0,c.getColorClassNames)("transparent").bgColor,hoverBgColor:r?(0,d.tremorTwMerge)((0,c.getColorClassNames)(r,u.colorPalette.background).hoverBgColor,"hover:bg-opacity-20 dark:hover:bg-opacity-20"):"hover:bg-tremor-brand-faint dark:hover:bg-dark-tremor-brand-faint",borderColor:r?(0,c.getColorClassNames)(r,u.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand"};case"light":return{textColor:r?(0,c.getColorClassNames)(r,u.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",hoverTextColor:r?(0,c.getColorClassNames)(r,u.colorPalette.darkText).hoverTextColor:"hover:text-tremor-brand-emphasis dark:hover:text-dark-tremor-brand-emphasis",bgColor:(0,c.getColorClassNames)("transparent").bgColor,borderColor:"",hoverBorderColor:""}}},p=(0,c.makeClassName)("Button"),b=({loading:e,iconSize:r,iconPosition:t,Icon:o,needMargin:l,transitionStatus:s})=>{let n=l?t===i.HorizontalPositions.Left?(0,d.tremorTwMerge)("-ml-1","mr-1.5"):(0,d.tremorTwMerge)("-mr-1","ml-1.5"):"",c=(0,d.tremorTwMerge)("w-0 h-0"),u={default:c,entering:c,entered:r,exiting:r,exited:c};return e?a.default.createElement(m,{className:(0,d.tremorTwMerge)(p("icon"),"animate-spin shrink-0",n,u.default,u[s]),style:{transition:"width 150ms"}}):a.default.createElement(o,{className:(0,d.tremorTwMerge)(p("icon"),"shrink-0",r,n)})},h=a.default.forwardRef((e,o)=>{let{icon:m,iconPosition:u=i.HorizontalPositions.Left,size:h=i.Sizes.SM,color:y,variant:v="primary",disabled:x,loading:C=!1,loadingText:w,children:k,tooltip:N,className:T}=e,O=(0,r.__rest)(e,["icon","iconPosition","size","color","variant","disabled","loading","loadingText","children","tooltip","className"]),E=C||x,M=void 0!==m||C,j=C&&w,P=!(!k&&!j),S=(0,d.tremorTwMerge)(f[h].height,f[h].width),_="light"!==v?(0,d.tremorTwMerge)("rounded-tremor-default border","shadow-tremor-input","dark:shadow-dark-tremor-input"):"",z=g(v,y),R=("light"!==v?{xs:{paddingX:"px-2.5",paddingY:"py-1.5",fontSize:"text-xs"},sm:{paddingX:"px-4",paddingY:"py-2",fontSize:"text-sm"},md:{paddingX:"px-4",paddingY:"py-2",fontSize:"text-md"},lg:{paddingX:"px-4",paddingY:"py-2.5",fontSize:"text-lg"},xl:{paddingX:"px-4",paddingY:"py-3",fontSize:"text-xl"}}:{xs:{paddingX:"",paddingY:"",fontSize:"text-xs"},sm:{paddingX:"",paddingY:"",fontSize:"text-sm"},md:{paddingX:"",paddingY:"",fontSize:"text-md"},lg:{paddingX:"",paddingY:"",fontSize:"text-lg"},xl:{paddingX:"",paddingY:"",fontSize:"text-xl"}})[h],{tooltipProps:B,getReferenceProps:$}=(0,t.useTooltip)(300),[L,H]=(({enter:e=!0,exit:r=!0,preEnter:t,preExit:o,timeout:i,initialEntered:d,mountOnEnter:c,unmountOnExit:m,onStateChange:u}={})=>{let[f,g]=(0,a.useState)(()=>l(d?2:s(c))),p=(0,a.useRef)(f),b=(0,a.useRef)(0),[h,y]="object"==typeof i?[i.enter,i.exit]:[i,i],v=(0,a.useCallback)(()=>{let e=((e,r)=>{switch(e){case 1:case 0:return 2;case 4:case 3:return s(r)}})(p.current._s,m);e&&n(e,g,p,b,u)},[u,m]);return[f,(0,a.useCallback)(a=>{let l=e=>{switch(n(e,g,p,b,u),e){case 1:h>=0&&(b.current=((...e)=>setTimeout(...e))(v,h));break;case 4:y>=0&&(b.current=((...e)=>setTimeout(...e))(v,y));break;case 0:case 3:b.current=((...e)=>setTimeout(...e))(()=>{isNaN(document.body.offsetTop)||l(e+1)},0)}},i=p.current.isEnter;"boolean"!=typeof a&&(a=!i),a?i||l(e?+!t:2):i&&l(r?o?3:4:s(m))},[v,u,e,r,t,o,h,y,m]),v]})({timeout:50});return(0,a.useEffect)(()=>{H(C)},[C]),a.default.createElement("button",Object.assign({ref:(0,c.mergeRefs)([o,B.refs.setReference]),className:(0,d.tremorTwMerge)(p("root"),"shrink-0 inline-flex justify-center items-center group font-medium outline-none",_,R.paddingX,R.paddingY,R.fontSize,z.textColor,z.bgColor,z.borderColor,z.hoverBorderColor,E?"opacity-50 cursor-not-allowed":(0,d.tremorTwMerge)(g(v,y).hoverTextColor,g(v,y).hoverBgColor,g(v,y).hoverBorderColor),T),disabled:E},$,O),a.default.createElement(t.default,Object.assign({text:N},B)),M&&u!==i.HorizontalPositions.Right?a.default.createElement(b,{loading:C,iconSize:S,iconPosition:u,Icon:m,transitionStatus:L.status,needMargin:P}):null,j||k?a.default.createElement("span",{className:(0,d.tremorTwMerge)(p("text"),"text-tremor-default whitespace-nowrap")},j?w:k):null,M&&u===i.HorizontalPositions.Right?a.default.createElement(b,{loading:C,iconSize:S,iconPosition:u,Icon:m,transitionStatus:L.status,needMargin:P}):null)});h.displayName="Button",e.s(["Button",0,h],994388)},304967,e=>{"use strict";var r=e.i(290571),t=e.i(271645),a=e.i(480731),o=e.i(95779),l=e.i(444755),s=e.i(673706);let n=(0,s.makeClassName)("Card"),i=t.default.forwardRef((e,i)=>{let{decoration:d="",decorationColor:c,children:m,className:u}=e,f=(0,r.__rest)(e,["decoration","decorationColor","children","className"]);return t.default.createElement("div",Object.assign({ref:i,className:(0,l.tremorTwMerge)(n("root"),"relative w-full text-left ring-1 rounded-tremor-default p-6","bg-tremor-background ring-tremor-ring shadow-tremor-card","dark:bg-dark-tremor-background dark:ring-dark-tremor-ring dark:shadow-dark-tremor-card",c?(0,s.getColorClassNames)(c,o.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand",(e=>{if(!e)return"";switch(e){case a.HorizontalPositions.Left:return"border-l-4";case a.VerticalPositions.Top:return"border-t-4";case a.HorizontalPositions.Right:return"border-r-4";case a.VerticalPositions.Bottom:return"border-b-4";default:return""}})(d),u)},f),m)});i.displayName="Card",e.s(["Card",0,i],304967)},629569,e=>{"use strict";var r=e.i(290571),t=e.i(95779),a=e.i(444755),o=e.i(673706),l=e.i(271645);let s=l.default.forwardRef((e,s)=>{let{color:n,children:i,className:d}=e,c=(0,r.__rest)(e,["color","children","className"]);return l.default.createElement("p",Object.assign({ref:s,className:(0,a.tremorTwMerge)("font-medium text-tremor-title",n?(0,o.getColorClassNames)(n,t.colorPalette.darkText).textColor:"text-tremor-content-strong dark:text-dark-tremor-content-strong",d)},c),i)});s.displayName="Title",e.s(["Title",0,s],629569)},653496,e=>{"use strict";var r=e.i(721369);e.s(["Tabs",()=>r.default])},637235,e=>{"use strict";e.i(247167);var r=e.i(931067),t=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"}},{tag:"path",attrs:{d:"M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z"}}]},name:"clock-circle",theme:"outlined"};var o=e.i(9583),l=t.forwardRef(function(e,l){return t.createElement(o.default,(0,r.default)({},e,{ref:l,icon:a}))});e.s(["ClockCircleOutlined",0,l],637235)},525720,e=>{"use strict";e.i(247167);var r=e.i(271645),t=e.i(343794),a=e.i(529681),o=e.i(908286),l=e.i(242064),s=e.i(246422),n=e.i(838378);let i=["wrap","nowrap","wrap-reverse"],d=["flex-start","flex-end","start","end","center","space-between","space-around","space-evenly","stretch","normal","left","right"],c=["center","start","end","flex-start","flex-end","self-start","self-end","baseline","normal","stretch"],m=function(e,r){let a,o,l;return(0,t.default)(Object.assign(Object.assign(Object.assign({},(a=!0===r.wrap?"wrap":r.wrap,{[`${e}-wrap-${a}`]:a&&i.includes(a)})),(o={},c.forEach(t=>{o[`${e}-align-${t}`]=r.align===t}),o[`${e}-align-stretch`]=!r.align&&!!r.vertical,o)),(l={},d.forEach(t=>{l[`${e}-justify-${t}`]=r.justify===t}),l)))},u=(0,s.genStyleHooks)("Flex",e=>{let{paddingXS:r,padding:t,paddingLG:a}=e,o=(0,n.mergeToken)(e,{flexGapSM:r,flexGap:t,flexGapLG:a});return[(e=>{let{componentCls:r}=e;return{[r]:{display:"flex",margin:0,padding:0,"&-vertical":{flexDirection:"column"},"&-rtl":{direction:"rtl"},"&:empty":{display:"none"}}}})(o),(e=>{let{componentCls:r}=e;return{[r]:{"&-gap-small":{gap:e.flexGapSM},"&-gap-middle":{gap:e.flexGap},"&-gap-large":{gap:e.flexGapLG}}}})(o),(e=>{let{componentCls:r}=e,t={};return i.forEach(e=>{t[`${r}-wrap-${e}`]={flexWrap:e}}),t})(o),(e=>{let{componentCls:r}=e,t={};return c.forEach(e=>{t[`${r}-align-${e}`]={alignItems:e}}),t})(o),(e=>{let{componentCls:r}=e,t={};return d.forEach(e=>{t[`${r}-justify-${e}`]={justifyContent:e}}),t})(o)]},()=>({}),{resetStyle:!1});var f=function(e,r){var t={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&0>r.indexOf(a)&&(t[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,a=Object.getOwnPropertySymbols(e);or.indexOf(a[o])&&Object.prototype.propertyIsEnumerable.call(e,a[o])&&(t[a[o]]=e[a[o]]);return t};let g=r.default.forwardRef((e,s)=>{let{prefixCls:n,rootClassName:i,className:d,style:c,flex:g,gap:p,vertical:b=!1,component:h="div",children:y}=e,v=f(e,["prefixCls","rootClassName","className","style","flex","gap","vertical","component","children"]),{flex:x,direction:C,getPrefixCls:w}=r.default.useContext(l.ConfigContext),k=w("flex",n),[N,T,O]=u(k),E=null!=b?b:null==x?void 0:x.vertical,M=(0,t.default)(d,i,null==x?void 0:x.className,k,T,O,m(k,e),{[`${k}-rtl`]:"rtl"===C,[`${k}-gap-${p}`]:(0,o.isPresetSize)(p),[`${k}-vertical`]:E}),j=Object.assign(Object.assign({},null==x?void 0:x.style),c);return g&&(j.flex=g),p&&!(0,o.isPresetSize)(p)&&(j.gap=p),N(r.default.createElement(h,Object.assign({ref:s,className:M,style:j},(0,a.default)(v,["justify","wrap","align"])),y))});e.s(["Flex",0,g],525720)},743151,(e,r,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.CopyToClipboard=void 0;var a=s(e.r(844343)),o=s(e.r(271645)),l=["text","onCopy","options","children"];function s(e){return e&&e.__esModule?e:{default:e}}function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);r&&(a=a.filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable})),t.push.apply(t,a)}return t}function d(e){for(var r=1;r{"use strict";var a=e.r(743151).CopyToClipboard;a.CopyToClipboard=a,r.exports=a},269200,e=>{"use strict";var r=e.i(290571),t=e.i(271645),a=e.i(444755);let o=(0,e.i(673706).makeClassName)("Table"),l=t.default.forwardRef((e,l)=>{let{children:s,className:n}=e,i=(0,r.__rest)(e,["children","className"]);return t.default.createElement("div",{className:(0,a.tremorTwMerge)(o("root"),"overflow-auto",n)},t.default.createElement("table",Object.assign({ref:l,className:(0,a.tremorTwMerge)(o("table"),"w-full text-tremor-default","text-tremor-content","dark:text-dark-tremor-content")},i),s))});l.displayName="Table",e.s(["Table",0,l],269200)},942232,e=>{"use strict";var r=e.i(290571),t=e.i(271645),a=e.i(444755);let o=(0,e.i(673706).makeClassName)("TableBody"),l=t.default.forwardRef((e,l)=>{let{children:s,className:n}=e,i=(0,r.__rest)(e,["children","className"]);return t.default.createElement(t.default.Fragment,null,t.default.createElement("tbody",Object.assign({ref:l,className:(0,a.tremorTwMerge)(o("root"),"align-top divide-y","divide-tremor-border","dark:divide-dark-tremor-border",n)},i),s))});l.displayName="TableBody",e.s(["TableBody",0,l],942232)},977572,e=>{"use strict";var r=e.i(290571),t=e.i(271645),a=e.i(444755);let o=(0,e.i(673706).makeClassName)("TableCell"),l=t.default.forwardRef((e,l)=>{let{children:s,className:n}=e,i=(0,r.__rest)(e,["children","className"]);return t.default.createElement(t.default.Fragment,null,t.default.createElement("td",Object.assign({ref:l,className:(0,a.tremorTwMerge)(o("root"),"align-middle whitespace-nowrap text-left p-4",n)},i),s))});l.displayName="TableCell",e.s(["TableCell",0,l],977572)},427612,e=>{"use strict";var r=e.i(290571),t=e.i(271645),a=e.i(444755);let o=(0,e.i(673706).makeClassName)("TableHead"),l=t.default.forwardRef((e,l)=>{let{children:s,className:n}=e,i=(0,r.__rest)(e,["children","className"]);return t.default.createElement(t.default.Fragment,null,t.default.createElement("thead",Object.assign({ref:l,className:(0,a.tremorTwMerge)(o("root"),"text-left","text-tremor-content","dark:text-dark-tremor-content",n)},i),s))});l.displayName="TableHead",e.s(["TableHead",0,l],427612)},64848,e=>{"use strict";var r=e.i(290571),t=e.i(271645),a=e.i(444755);let o=(0,e.i(673706).makeClassName)("TableHeaderCell"),l=t.default.forwardRef((e,l)=>{let{children:s,className:n}=e,i=(0,r.__rest)(e,["children","className"]);return t.default.createElement(t.default.Fragment,null,t.default.createElement("th",Object.assign({ref:l,className:(0,a.tremorTwMerge)(o("root"),"whitespace-nowrap text-left font-semibold top-0 px-4 py-3.5","text-tremor-content-strong","dark:text-dark-tremor-content-strong",n)},i),s))});l.displayName="TableHeaderCell",e.s(["TableHeaderCell",0,l],64848)},496020,e=>{"use strict";var r=e.i(290571),t=e.i(271645),a=e.i(444755);let o=(0,e.i(673706).makeClassName)("TableRow"),l=t.default.forwardRef((e,l)=>{let{children:s,className:n}=e,i=(0,r.__rest)(e,["children","className"]);return t.default.createElement(t.default.Fragment,null,t.default.createElement("tr",Object.assign({ref:l,className:(0,a.tremorTwMerge)(o("row"),n)},i),s))});l.displayName="TableRow",e.s(["TableRow",0,l],496020)},536916,e=>{"use strict";var r=e.i(374276);e.s(["Checkbox",()=>r.default])},350967,46757,e=>{"use strict";var r=e.i(290571),t=e.i(444755),a=e.i(673706),o=e.i(271645);let l={0:"grid-cols-none",1:"grid-cols-1",2:"grid-cols-2",3:"grid-cols-3",4:"grid-cols-4",5:"grid-cols-5",6:"grid-cols-6",7:"grid-cols-7",8:"grid-cols-8",9:"grid-cols-9",10:"grid-cols-10",11:"grid-cols-11",12:"grid-cols-12"},s={0:"sm:grid-cols-none",1:"sm:grid-cols-1",2:"sm:grid-cols-2",3:"sm:grid-cols-3",4:"sm:grid-cols-4",5:"sm:grid-cols-5",6:"sm:grid-cols-6",7:"sm:grid-cols-7",8:"sm:grid-cols-8",9:"sm:grid-cols-9",10:"sm:grid-cols-10",11:"sm:grid-cols-11",12:"sm:grid-cols-12"},n={0:"md:grid-cols-none",1:"md:grid-cols-1",2:"md:grid-cols-2",3:"md:grid-cols-3",4:"md:grid-cols-4",5:"md:grid-cols-5",6:"md:grid-cols-6",7:"md:grid-cols-7",8:"md:grid-cols-8",9:"md:grid-cols-9",10:"md:grid-cols-10",11:"md:grid-cols-11",12:"md:grid-cols-12"},i={0:"lg:grid-cols-none",1:"lg:grid-cols-1",2:"lg:grid-cols-2",3:"lg:grid-cols-3",4:"lg:grid-cols-4",5:"lg:grid-cols-5",6:"lg:grid-cols-6",7:"lg:grid-cols-7",8:"lg:grid-cols-8",9:"lg:grid-cols-9",10:"lg:grid-cols-10",11:"lg:grid-cols-11",12:"lg:grid-cols-12"};e.s(["colSpan",0,{1:"col-span-1",2:"col-span-2",3:"col-span-3",4:"col-span-4",5:"col-span-5",6:"col-span-6",7:"col-span-7",8:"col-span-8",9:"col-span-9",10:"col-span-10",11:"col-span-11",12:"col-span-12",13:"col-span-13"},"colSpanLg",0,{1:"lg:col-span-1",2:"lg:col-span-2",3:"lg:col-span-3",4:"lg:col-span-4",5:"lg:col-span-5",6:"lg:col-span-6",7:"lg:col-span-7",8:"lg:col-span-8",9:"lg:col-span-9",10:"lg:col-span-10",11:"lg:col-span-11",12:"lg:col-span-12",13:"lg:col-span-13"},"colSpanMd",0,{1:"md:col-span-1",2:"md:col-span-2",3:"md:col-span-3",4:"md:col-span-4",5:"md:col-span-5",6:"md:col-span-6",7:"md:col-span-7",8:"md:col-span-8",9:"md:col-span-9",10:"md:col-span-10",11:"md:col-span-11",12:"md:col-span-12",13:"md:col-span-13"},"colSpanSm",0,{1:"sm:col-span-1",2:"sm:col-span-2",3:"sm:col-span-3",4:"sm:col-span-4",5:"sm:col-span-5",6:"sm:col-span-6",7:"sm:col-span-7",8:"sm:col-span-8",9:"sm:col-span-9",10:"sm:col-span-10",11:"sm:col-span-11",12:"sm:col-span-12",13:"sm:col-span-13"},"gridCols",0,l,"gridColsLg",0,i,"gridColsMd",0,n,"gridColsSm",0,s],46757);let d=(0,a.makeClassName)("Grid"),c=(e,r)=>e&&Object.keys(r).includes(String(e))?r[e]:"",m=o.default.forwardRef((e,a)=>{let{numItems:m=1,numItemsSm:u,numItemsMd:f,numItemsLg:g,children:p,className:b}=e,h=(0,r.__rest)(e,["numItems","numItemsSm","numItemsMd","numItemsLg","children","className"]),y=c(m,l),v=c(u,s),x=c(f,n),C=c(g,i),w=(0,t.tremorTwMerge)(y,v,x,C);return o.default.createElement("div",Object.assign({ref:a,className:(0,t.tremorTwMerge)(d("root"),"grid",w,b)},h),p)});m.displayName="Grid",e.s(["Grid",0,m],350967)},981339,e=>{"use strict";var r=e.i(185793);e.s(["Skeleton",()=>r.default])},596239,e=>{"use strict";e.i(247167);var r=e.i(931067),t=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M574 665.4a8.03 8.03 0 00-11.3 0L446.5 781.6c-53.8 53.8-144.6 59.5-204 0-59.5-59.5-53.8-150.2 0-204l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3l-39.8-39.8a8.03 8.03 0 00-11.3 0L191.4 526.5c-84.6 84.6-84.6 221.5 0 306s221.5 84.6 306 0l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3L574 665.4zm258.6-474c-84.6-84.6-221.5-84.6-306 0L410.3 307.6a8.03 8.03 0 000 11.3l39.7 39.7c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c53.8-53.8 144.6-59.5 204 0 59.5 59.5 53.8 150.2 0 204L665.3 562.6a8.03 8.03 0 000 11.3l39.8 39.8c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c84.5-84.6 84.5-221.5 0-306.1zM610.1 372.3a8.03 8.03 0 00-11.3 0L372.3 598.7a8.03 8.03 0 000 11.3l39.6 39.6c3.1 3.1 8.2 3.1 11.3 0l226.4-226.4c3.1-3.1 3.1-8.2 0-11.3l-39.5-39.6z"}}]},name:"link",theme:"outlined"};var o=e.i(9583),l=t.forwardRef(function(e,l){return t.createElement(o.default,(0,r.default)({},e,{ref:l,icon:a}))});e.s(["LinkOutlined",0,l],596239)},751904,e=>{"use strict";var r=e.i(401361);e.s(["EditOutlined",()=>r.default])},727612,e=>{"use strict";let r=(0,e.i(475254).default)("trash-2",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}],["line",{x1:"10",x2:"10",y1:"11",y2:"17",key:"1uufr5"}],["line",{x1:"14",x2:"14",y1:"11",y2:"17",key:"xtxkd"}]]);e.s(["Trash2",0,r],727612)},823429,e=>{"use strict";let r=(0,e.i(475254).default)("square-pen",[["path",{d:"M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7",key:"1m0v6g"}],["path",{d:"M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z",key:"ohrbg2"}]]);e.s(["default",0,r])},465261,e=>{"use strict";let r=(0,e.i(475254).default)("key-round",[["path",{d:"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z",key:"1s6t7t"}],["circle",{cx:"16.5",cy:"7.5",r:".5",fill:"currentColor",key:"w0ekpg"}]]);e.s(["KeyRound",0,r],465261)},688511,e=>{"use strict";var r=e.i(823429);e.s(["Edit",()=>r.default])},700514,e=>{"use strict";var r=e.i(271645);e.s(["defaultPageSize",0,25,"useBaseUrl",0,()=>{let[e,t]=(0,r.useState)("http://localhost:4000");return(0,r.useEffect)(()=>{{let{protocol:e,host:r}=window.location;t(`${e}//${r}`)}},[]),e}])},98919,e=>{"use strict";let r=(0,e.i(475254).default)("shield",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}]]);e.s(["Shield",0,r],98919)},114600,e=>{"use strict";var r=e.i(290571),t=e.i(444755),a=e.i(673706),o=e.i(271645);let l=(0,a.makeClassName)("Divider"),s=o.default.forwardRef((e,a)=>{let{className:s,children:n}=e,i=(0,r.__rest)(e,["className","children"]);return o.default.createElement("div",Object.assign({ref:a,className:(0,t.tremorTwMerge)(l("root"),"w-full mx-auto my-6 flex justify-between gap-3 items-center text-tremor-default","text-tremor-content","dark:text-dark-tremor-content",s)},i),n?o.default.createElement(o.default.Fragment,null,o.default.createElement("div",{className:(0,t.tremorTwMerge)("w-full h-[1px] bg-tremor-border dark:bg-dark-tremor-border")}),o.default.createElement("div",{className:(0,t.tremorTwMerge)("text-inherit whitespace-nowrap")},n),o.default.createElement("div",{className:(0,t.tremorTwMerge)("w-full h-[1px] bg-tremor-border dark:bg-dark-tremor-border")})):o.default.createElement("div",{className:(0,t.tremorTwMerge)("w-full h-[1px] bg-tremor-border dark:bg-dark-tremor-border")}))});s.displayName="Divider",e.s(["Divider",0,s],114600)},366283,e=>{"use strict";var r=e.i(290571),t=e.i(271645),a=e.i(95779),o=e.i(444755),l=e.i(673706);let s=(0,l.makeClassName)("Callout"),n=t.default.forwardRef((e,n)=>{let{title:i,icon:d,color:c,className:m,children:u}=e,f=(0,r.__rest)(e,["title","icon","color","className","children"]);return t.default.createElement("div",Object.assign({ref:n,className:(0,o.tremorTwMerge)(s("root"),"flex flex-col overflow-hidden rounded-tremor-default text-tremor-default border-l-4 py-3 pr-3 pl-4",c?(0,o.tremorTwMerge)((0,l.getColorClassNames)(c,a.colorPalette.background).bgColor,(0,l.getColorClassNames)(c,a.colorPalette.darkBorder).borderColor,(0,l.getColorClassNames)(c,a.colorPalette.darkText).textColor,"dark:bg-opacity-10 bg-opacity-10"):(0,o.tremorTwMerge)("bg-tremor-brand-faint border-tremor-brand-emphasis text-tremor-brand-emphasis","dark:bg-dark-tremor-brand-muted/70 dark:border-dark-tremor-brand-emphasis dark:text-dark-tremor-brand-emphasis"),m)},f),t.default.createElement("div",{className:(0,o.tremorTwMerge)(s("header"),"flex items-start")},d?t.default.createElement(d,{className:(0,o.tremorTwMerge)(s("icon"),"flex-none h-5 w-5 mr-1.5")}):null,t.default.createElement("h4",{className:(0,o.tremorTwMerge)(s("title"),"font-semibold")},i)),t.default.createElement("p",{className:(0,o.tremorTwMerge)(s("body"),"overflow-y-auto",u?"mt-2":"")},u))});n.displayName="Callout",e.s(["Callout",0,n],366283)},475647,e=>{"use strict";e.i(247167);var r=e.i(931067),t=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M696 480H544V328c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v152H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h152v152c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V544h152c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8z"}},{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"}}]},name:"plus-circle",theme:"outlined"};var o=e.i(9583),l=t.forwardRef(function(e,l){return t.createElement(o.default,(0,r.default)({},e,{ref:l,icon:a}))});e.s(["PlusCircleOutlined",0,l],475647)},153472,e=>{"use strict";var r,t,a=e.i(266027),o=e.i(954616),l=e.i(912598),s=e.i(243652),n=e.i(135214),i=e.i(602869),d=e.i(431703),c=((r={}).GENERAL_SETTINGS="general_settings",r),m=((t={}).MAXIMUM_SPEND_LOGS_RETENTION_PERIOD="maximum_spend_logs_retention_period",t);let u=async(e,r)=>{try{let t=i.proxyBaseUrl?`${i.proxyBaseUrl}/config/list?config_type=${r}`:`/config/list?config_type=${r}`,a=await fetch(t,{method:"GET",headers:{[(0,i.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!a.ok){let e=await a.json(),r=(0,d.deriveErrorMessage)(e);throw(0,i.handleError)(r),Error(r)}return await a.json()}catch(e){throw console.error(`Failed to get proxy config for ${r}:`,e),e}},f=(0,s.createQueryKeys)("proxyConfig"),g=async(e,r)=>{try{let t=i.proxyBaseUrl?`${i.proxyBaseUrl}/config/field/delete`:"/config/field/delete",a=await fetch(t,{method:"POST",headers:{[(0,i.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify(r)});if(!a.ok){let e=await a.json(),r=(0,d.deriveErrorMessage)(e);throw(0,i.handleError)(r),Error(r)}return await a.json()}catch(e){throw console.error(`Failed to delete proxy config field ${r.field_name}:`,e),e}};e.s(["ConfigType",()=>c,"GeneralSettingsFieldName",()=>m,"proxyConfigKeys",0,f,"useDeleteProxyConfigField",0,()=>{let{accessToken:e}=(0,n.default)(),r=(0,l.useQueryClient)();return(0,o.useMutation)({mutationFn:async r=>{if(!e)throw Error("Access token is required");return await g(e,r)},onSuccess:()=>{r.invalidateQueries({queryKey:f.all})}})},"useProxyConfig",0,e=>{let{accessToken:r}=(0,n.default)();return(0,a.useQuery)({queryKey:f.list({filters:{configType:e}}),queryFn:async()=>await u(r,e),enabled:!!r})}])},286536,77705,e=>{"use strict";var r=e.i(475254);let t=(0,r.default)("eye",[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);e.s(["Eye",0,t],286536);let a=(0,r.default)("eye-off",[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]]);e.s(["EyeOff",0,a],77705)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/011mgw.-67gs_.js b/litellm/proxy/_experimental/out/_next/static/chunks/011mgw.-67gs_.js new file mode 100644 index 00000000000..6fff53bedce --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/011mgw.-67gs_.js @@ -0,0 +1,10 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,597440,e=>{"use strict";e.i(247167);var t=e.i(931067),n=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"}}]},name:"delete",theme:"outlined"};var l=e.i(9583),r=n.forwardRef(function(e,r){return n.createElement(l.default,(0,t.default)({},e,{ref:r,icon:i}))});e.s(["default",0,r],597440)},955135,e=>{"use strict";var t=e.i(597440);e.s(["DeleteOutlined",()=>t.default])},646563,e=>{"use strict";var t=e.i(959013);e.s(["PlusOutlined",()=>t.default])},954616,e=>{"use strict";var t=e.i(271645),n=e.i(114272),i=e.i(540143),l=e.i(915823),r=e.i(619273),a=class extends l.Subscribable{#e;#t=void 0;#n;#i;constructor(e,t){super(),this.#e=e,this.setOptions(t),this.bindMethods(),this.#l()}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(e){let t=this.options;this.options=this.#e.defaultMutationOptions(e),(0,r.shallowEqualObjects)(this.options,t)||this.#e.getMutationCache().notify({type:"observerOptionsUpdated",mutation:this.#n,observer:this}),t?.mutationKey&&this.options.mutationKey&&(0,r.hashKey)(t.mutationKey)!==(0,r.hashKey)(this.options.mutationKey)?this.reset():this.#n?.state.status==="pending"&&this.#n.setOptions(this.options)}onUnsubscribe(){this.hasListeners()||this.#n?.removeObserver(this)}onMutationUpdate(e){this.#l(),this.#r(e)}getCurrentResult(){return this.#t}reset(){this.#n?.removeObserver(this),this.#n=void 0,this.#l(),this.#r()}mutate(e,t){return this.#i=t,this.#n?.removeObserver(this),this.#n=this.#e.getMutationCache().build(this.#e,this.options),this.#n.addObserver(this),this.#n.execute(e)}#l(){let e=this.#n?.state??(0,n.getDefaultState)();this.#t={...e,isPending:"pending"===e.status,isSuccess:"success"===e.status,isError:"error"===e.status,isIdle:"idle"===e.status,mutate:this.mutate,reset:this.reset}}#r(e){i.notifyManager.batch(()=>{if(this.#i&&this.hasListeners()){let t=this.#t.variables,n=this.#t.context,i={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};if(e?.type==="success"){try{this.#i.onSuccess?.(e.data,t,n,i)}catch(e){Promise.reject(e)}try{this.#i.onSettled?.(e.data,null,t,n,i)}catch(e){Promise.reject(e)}}else if(e?.type==="error"){try{this.#i.onError?.(e.error,t,n,i)}catch(e){Promise.reject(e)}try{this.#i.onSettled?.(void 0,e.error,t,n,i)}catch(e){Promise.reject(e)}}}this.listeners.forEach(e=>{e(this.#t)})})}},o=e.i(912598);e.s(["useMutation",0,function(e,n){let l=(0,o.useQueryClient)(n),[s]=t.useState(()=>new a(l,e));t.useEffect(()=>{s.setOptions(e)},[s,e]);let c=t.useSyncExternalStore(t.useCallback(e=>s.subscribe(i.notifyManager.batchCalls(e)),[s]),()=>s.getCurrentResult(),()=>s.getCurrentResult()),d=t.useCallback((e,t)=>{s.mutate(e,t).catch(r.noop)},[s]);if(c.error&&(0,r.shouldThrowError)(s.options.throwOnError,[c.error]))throw c.error;return{...c,mutate:d,mutateAsync:c.mutate}}],954616)},270377,e=>{"use strict";e.i(247167);var t=e.i(931067),n=e.i(271645);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"}},{tag:"path",attrs:{d:"M464 688a48 48 0 1096 0 48 48 0 10-96 0zm24-112h48c4.4 0 8-3.6 8-8V296c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8z"}}]},name:"exclamation-circle",theme:"outlined"};var l=e.i(9583),r=n.forwardRef(function(e,r){return n.createElement(l.default,(0,t.default)({},e,{ref:r,icon:i}))});e.s(["ExclamationCircleOutlined",0,r],270377)},175712,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(343794),i=e.i(529681),l=e.i(242064),r=e.i(517455),a=e.i(185793),o=e.i(721369),s=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,i=Object.getOwnPropertySymbols(e);lt.indexOf(i[l])&&Object.prototype.propertyIsEnumerable.call(e,i[l])&&(n[i[l]]=e[i[l]]);return n};let c=e=>{var{prefixCls:i,className:r,hoverable:a=!0}=e,o=s(e,["prefixCls","className","hoverable"]);let{getPrefixCls:c}=t.useContext(l.ConfigContext),d=c("card",i),u=(0,n.default)(`${d}-grid`,r,{[`${d}-grid-hoverable`]:a});return t.createElement("div",Object.assign({},o,{className:u}))};e.i(296059);var d=e.i(915654),u=e.i(183293),g=e.i(246422),b=e.i(838378);let m=(0,g.genStyleHooks)("Card",e=>{let t=(0,b.mergeToken)(e,{cardShadow:e.boxShadowCard,cardHeadPadding:e.padding,cardPaddingBase:e.paddingLG,cardActionsIconSize:e.fontSize});return[(e=>{let{componentCls:t,cardShadow:n,cardHeadPadding:i,colorBorderSecondary:l,boxShadowTertiary:r,bodyPadding:a,extraColor:o}=e;return{[t]:Object.assign(Object.assign({},(0,u.resetComponent)(e)),{position:"relative",background:e.colorBgContainer,borderRadius:e.borderRadiusLG,[`&:not(${t}-bordered)`]:{boxShadow:r},[`${t}-head`]:(e=>{let{antCls:t,componentCls:n,headerHeight:i,headerPadding:l,tabsMarginBottom:r}=e;return Object.assign(Object.assign({display:"flex",justifyContent:"center",flexDirection:"column",minHeight:i,marginBottom:-1,padding:`0 ${(0,d.unit)(l)}`,color:e.colorTextHeading,fontWeight:e.fontWeightStrong,fontSize:e.headerFontSize,background:e.headerBg,borderBottom:`${(0,d.unit)(e.lineWidth)} ${e.lineType} ${e.colorBorderSecondary}`,borderRadius:`${(0,d.unit)(e.borderRadiusLG)} ${(0,d.unit)(e.borderRadiusLG)} 0 0`},(0,u.clearFix)()),{"&-wrapper":{width:"100%",display:"flex",alignItems:"center"},"&-title":Object.assign(Object.assign({display:"inline-block",flex:1},u.textEllipsis),{[` + > ${n}-typography, + > ${n}-typography-edit-content + `]:{insetInlineStart:0,marginTop:0,marginBottom:0}}),[`${t}-tabs-top`]:{clear:"both",marginBottom:r,color:e.colorText,fontWeight:"normal",fontSize:e.fontSize,"&-bar":{borderBottom:`${(0,d.unit)(e.lineWidth)} ${e.lineType} ${e.colorBorderSecondary}`}}})})(e),[`${t}-extra`]:{marginInlineStart:"auto",color:o,fontWeight:"normal",fontSize:e.fontSize},[`${t}-body`]:{padding:a,borderRadius:`0 0 ${(0,d.unit)(e.borderRadiusLG)} ${(0,d.unit)(e.borderRadiusLG)}`},[`${t}-grid`]:(e=>{let{cardPaddingBase:t,colorBorderSecondary:n,cardShadow:i,lineWidth:l}=e;return{width:"33.33%",padding:t,border:0,borderRadius:0,boxShadow:` + ${(0,d.unit)(l)} 0 0 0 ${n}, + 0 ${(0,d.unit)(l)} 0 0 ${n}, + ${(0,d.unit)(l)} ${(0,d.unit)(l)} 0 0 ${n}, + ${(0,d.unit)(l)} 0 0 0 ${n} inset, + 0 ${(0,d.unit)(l)} 0 0 ${n} inset; + `,transition:`all ${e.motionDurationMid}`,"&-hoverable:hover":{position:"relative",zIndex:1,boxShadow:i}}})(e),[`${t}-cover`]:{"> *":{display:"block",width:"100%",borderRadius:`${(0,d.unit)(e.borderRadiusLG)} ${(0,d.unit)(e.borderRadiusLG)} 0 0`}},[`${t}-actions`]:(e=>{let{componentCls:t,iconCls:n,actionsLiMargin:i,cardActionsIconSize:l,colorBorderSecondary:r,actionsBg:a}=e;return Object.assign(Object.assign({margin:0,padding:0,listStyle:"none",background:a,borderTop:`${(0,d.unit)(e.lineWidth)} ${e.lineType} ${r}`,display:"flex",borderRadius:`0 0 ${(0,d.unit)(e.borderRadiusLG)} ${(0,d.unit)(e.borderRadiusLG)}`},(0,u.clearFix)()),{"& > li":{margin:i,color:e.colorTextDescription,textAlign:"center","> span":{position:"relative",display:"block",minWidth:e.calc(e.cardActionsIconSize).mul(2).equal(),fontSize:e.fontSize,lineHeight:e.lineHeight,cursor:"pointer","&:hover":{color:e.colorPrimary,transition:`color ${e.motionDurationMid}`},[`a:not(${t}-btn), > ${n}`]:{display:"inline-block",width:"100%",color:e.colorIcon,lineHeight:(0,d.unit)(e.fontHeight),transition:`color ${e.motionDurationMid}`,"&:hover":{color:e.colorPrimary}},[`> ${n}`]:{fontSize:l,lineHeight:(0,d.unit)(e.calc(l).mul(e.lineHeight).equal())}},"&:not(:last-child)":{borderInlineEnd:`${(0,d.unit)(e.lineWidth)} ${e.lineType} ${r}`}}})})(e),[`${t}-meta`]:Object.assign(Object.assign({margin:`${(0,d.unit)(e.calc(e.marginXXS).mul(-1).equal())} 0`,display:"flex"},(0,u.clearFix)()),{"&-avatar":{paddingInlineEnd:e.padding},"&-detail":{overflow:"hidden",flex:1,"> div:not(:last-child)":{marginBottom:e.marginXS}},"&-title":Object.assign({color:e.colorTextHeading,fontWeight:e.fontWeightStrong,fontSize:e.fontSizeLG},u.textEllipsis),"&-description":{color:e.colorTextDescription}})}),[`${t}-bordered`]:{border:`${(0,d.unit)(e.lineWidth)} ${e.lineType} ${l}`,[`${t}-cover`]:{marginTop:-1,marginInlineStart:-1,marginInlineEnd:-1}},[`${t}-hoverable`]:{cursor:"pointer",transition:`box-shadow ${e.motionDurationMid}, border-color ${e.motionDurationMid}`,"&:hover":{borderColor:"transparent",boxShadow:n}},[`${t}-contain-grid`]:{borderRadius:`${(0,d.unit)(e.borderRadiusLG)} ${(0,d.unit)(e.borderRadiusLG)} 0 0 `,[`${t}-body`]:{display:"flex",flexWrap:"wrap"},[`&:not(${t}-loading) ${t}-body`]:{marginBlockStart:e.calc(e.lineWidth).mul(-1).equal(),marginInlineStart:e.calc(e.lineWidth).mul(-1).equal(),padding:0}},[`${t}-contain-tabs`]:{[`> div${t}-head`]:{minHeight:0,[`${t}-head-title, ${t}-extra`]:{paddingTop:i}}},[`${t}-type-inner`]:(e=>{let{componentCls:t,colorFillAlter:n,headerPadding:i,bodyPadding:l}=e;return{[`${t}-head`]:{padding:`0 ${(0,d.unit)(i)}`,background:n,"&-title":{fontSize:e.fontSize}},[`${t}-body`]:{padding:`${(0,d.unit)(e.padding)} ${(0,d.unit)(l)}`}}})(e),[`${t}-loading`]:(e=>{let{componentCls:t}=e;return{overflow:"hidden",[`${t}-body`]:{userSelect:"none"}}})(e),[`${t}-rtl`]:{direction:"rtl"}}})(t),(e=>{let{componentCls:t,bodyPaddingSM:n,headerPaddingSM:i,headerHeightSM:l,headerFontSizeSM:r}=e;return{[`${t}-small`]:{[`> ${t}-head`]:{minHeight:l,padding:`0 ${(0,d.unit)(i)}`,fontSize:r,[`> ${t}-head-wrapper`]:{[`> ${t}-extra`]:{fontSize:e.fontSize}}},[`> ${t}-body`]:{padding:n}},[`${t}-small${t}-contain-tabs`]:{[`> ${t}-head`]:{[`${t}-head-title, ${t}-extra`]:{paddingTop:0,display:"flex",alignItems:"center"}}}}})(t)]},e=>{var t,n;return{headerBg:"transparent",headerFontSize:e.fontSizeLG,headerFontSizeSM:e.fontSize,headerHeight:e.fontSizeLG*e.lineHeightLG+2*e.padding,headerHeightSM:e.fontSize*e.lineHeight+2*e.paddingXS,actionsBg:e.colorBgContainer,actionsLiMargin:`${e.paddingSM}px 0`,tabsMarginBottom:-e.padding-e.lineWidth,extraColor:e.colorText,bodyPaddingSM:12,headerPaddingSM:12,bodyPadding:null!=(t=e.bodyPadding)?t:e.paddingLG,headerPadding:null!=(n=e.headerPadding)?n:e.paddingLG}});var p=e.i(792812),h=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,i=Object.getOwnPropertySymbols(e);lt.indexOf(i[l])&&Object.prototype.propertyIsEnumerable.call(e,i[l])&&(n[i[l]]=e[i[l]]);return n};let f=e=>{let{actionClasses:n,actions:i=[],actionStyle:l}=e;return t.createElement("ul",{className:n,style:l},i.map((e,n)=>{let l=`action-${n}`;return t.createElement("li",{style:{width:`${100/i.length}%`},key:l},t.createElement("span",null,e))}))},y=t.forwardRef((e,s)=>{let d,{prefixCls:u,className:g,rootClassName:b,style:y,extra:$,headStyle:v={},bodyStyle:O={},title:j,loading:x,bordered:S,variant:C,size:E,type:w,cover:z,actions:M,tabList:B,children:N,activeTabKey:T,defaultActiveTabKey:P,tabBarExtraContent:k,hoverable:R,tabProps:L={},classNames:H,styles:I}=e,G=h(e,["prefixCls","className","rootClassName","style","extra","headStyle","bodyStyle","title","loading","bordered","variant","size","type","cover","actions","tabList","children","activeTabKey","defaultActiveTabKey","tabBarExtraContent","hoverable","tabProps","classNames","styles"]),{getPrefixCls:W,direction:D,card:A}=t.useContext(l.ConfigContext),[F]=(0,p.default)("card",C,S),X=e=>{var t;return(0,n.default)(null==(t=null==A?void 0:A.classNames)?void 0:t[e],null==H?void 0:H[e])},K=e=>{var t;return Object.assign(Object.assign({},null==(t=null==A?void 0:A.styles)?void 0:t[e]),null==I?void 0:I[e])},q=t.useMemo(()=>{let e=!1;return t.Children.forEach(N,t=>{(null==t?void 0:t.type)===c&&(e=!0)}),e},[N]),U=W("card",u),[Q,V,_]=m(U),J=t.createElement(a.default,{loading:!0,active:!0,paragraph:{rows:4},title:!1},N),Y=void 0!==T,Z=Object.assign(Object.assign({},L),{[Y?"activeKey":"defaultActiveKey"]:Y?T:P,tabBarExtraContent:k}),ee=(0,r.default)(E),et=ee&&"default"!==ee?ee:"large",en=B?t.createElement(o.default,Object.assign({size:et},Z,{className:`${U}-head-tabs`,onChange:t=>{var n;null==(n=e.onTabChange)||n.call(e,t)},items:B.map(e=>{var{tab:t}=e;return Object.assign({label:t},h(e,["tab"]))})})):null;if(j||$||en){let e=(0,n.default)(`${U}-head`,X("header")),i=(0,n.default)(`${U}-head-title`,X("title")),l=(0,n.default)(`${U}-extra`,X("extra")),r=Object.assign(Object.assign({},v),K("header"));d=t.createElement("div",{className:e,style:r},t.createElement("div",{className:`${U}-head-wrapper`},j&&t.createElement("div",{className:i,style:K("title")},j),$&&t.createElement("div",{className:l,style:K("extra")},$)),en)}let ei=(0,n.default)(`${U}-cover`,X("cover")),el=z?t.createElement("div",{className:ei,style:K("cover")},z):null,er=(0,n.default)(`${U}-body`,X("body")),ea=Object.assign(Object.assign({},O),K("body")),eo=t.createElement("div",{className:er,style:ea},x?J:N),es=(0,n.default)(`${U}-actions`,X("actions")),ec=(null==M?void 0:M.length)?t.createElement(f,{actionClasses:es,actionStyle:K("actions"),actions:M}):null,ed=(0,i.default)(G,["onTabChange"]),eu=(0,n.default)(U,null==A?void 0:A.className,{[`${U}-loading`]:x,[`${U}-bordered`]:"borderless"!==F,[`${U}-hoverable`]:R,[`${U}-contain-grid`]:q,[`${U}-contain-tabs`]:null==B?void 0:B.length,[`${U}-${ee}`]:ee,[`${U}-type-${w}`]:!!w,[`${U}-rtl`]:"rtl"===D},g,b,V,_),eg=Object.assign(Object.assign({},null==A?void 0:A.style),y);return Q(t.createElement("div",Object.assign({ref:s},ed,{className:eu,style:eg}),d,el,eo,ec))});var $=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,i=Object.getOwnPropertySymbols(e);lt.indexOf(i[l])&&Object.prototype.propertyIsEnumerable.call(e,i[l])&&(n[i[l]]=e[i[l]]);return n};y.Grid=c,y.Meta=e=>{let{prefixCls:i,className:r,avatar:a,title:o,description:s}=e,c=$(e,["prefixCls","className","avatar","title","description"]),{getPrefixCls:d}=t.useContext(l.ConfigContext),u=d("card",i),g=(0,n.default)(`${u}-meta`,r),b=a?t.createElement("div",{className:`${u}-meta-avatar`},a):null,m=o?t.createElement("div",{className:`${u}-meta-title`},o):null,p=s?t.createElement("div",{className:`${u}-meta-description`},s):null,h=m||p?t.createElement("div",{className:`${u}-meta-detail`},m,p):null;return t.createElement("div",Object.assign({},c,{className:g}),b,h)},e.s(["Card",0,y],175712)},869216,e=>{"use strict";e.i(247167);var t=e.i(271645),n=e.i(343794),i=e.i(908206),l=e.i(242064),r=e.i(517455),a=e.i(150073);let o={xxl:3,xl:3,lg:3,md:3,sm:2,xs:1},s=t.default.createContext({});var c=e.i(876556),d=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,i=Object.getOwnPropertySymbols(e);lt.indexOf(i[l])&&Object.prototype.propertyIsEnumerable.call(e,i[l])&&(n[i[l]]=e[i[l]]);return n},u=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,i=Object.getOwnPropertySymbols(e);lt.indexOf(i[l])&&Object.prototype.propertyIsEnumerable.call(e,i[l])&&(n[i[l]]=e[i[l]]);return n};let g=e=>{let{itemPrefixCls:i,component:l,span:r,className:a,style:o,labelStyle:c,contentStyle:d,bordered:u,label:g,content:b,colon:m,type:p,styles:h}=e,{classNames:f}=t.useContext(s),y=Object.assign(Object.assign({},c),null==h?void 0:h.label),$=Object.assign(Object.assign({},d),null==h?void 0:h.content);if(u)return t.createElement(l,{colSpan:r,style:o,className:(0,n.default)(a,{[`${i}-item-${p}`]:"label"===p||"content"===p,[null==f?void 0:f.label]:(null==f?void 0:f.label)&&"label"===p,[null==f?void 0:f.content]:(null==f?void 0:f.content)&&"content"===p})},null!=g&&t.createElement("span",{style:y},g),null!=b&&t.createElement("span",{style:$},b));return t.createElement(l,{colSpan:r,style:o,className:(0,n.default)(`${i}-item`,a)},t.createElement("div",{className:`${i}-item-container`},null!=g&&t.createElement("span",{style:y,className:(0,n.default)(`${i}-item-label`,null==f?void 0:f.label,{[`${i}-item-no-colon`]:!m})},g),null!=b&&t.createElement("span",{style:$,className:(0,n.default)(`${i}-item-content`,null==f?void 0:f.content)},b)))};function b(e,{colon:n,prefixCls:i,bordered:l},{component:r,type:a,showLabel:o,showContent:s,labelStyle:c,contentStyle:d,styles:u}){return e.map(({label:e,children:b,prefixCls:m=i,className:p,style:h,labelStyle:f,contentStyle:y,span:$=1,key:v,styles:O},j)=>"string"==typeof r?t.createElement(g,{key:`${a}-${v||j}`,className:p,style:h,styles:{label:Object.assign(Object.assign(Object.assign(Object.assign({},c),null==u?void 0:u.label),f),null==O?void 0:O.label),content:Object.assign(Object.assign(Object.assign(Object.assign({},d),null==u?void 0:u.content),y),null==O?void 0:O.content)},span:$,colon:n,component:r,itemPrefixCls:m,bordered:l,label:o?e:null,content:s?b:null,type:a}):[t.createElement(g,{key:`label-${v||j}`,className:p,style:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},c),null==u?void 0:u.label),h),f),null==O?void 0:O.label),span:1,colon:n,component:r[0],itemPrefixCls:m,bordered:l,label:e,type:"label"}),t.createElement(g,{key:`content-${v||j}`,className:p,style:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},d),null==u?void 0:u.content),h),y),null==O?void 0:O.content),span:2*$-1,component:r[1],itemPrefixCls:m,bordered:l,content:b,type:"content"})])}let m=e=>{let n=t.useContext(s),{prefixCls:i,vertical:l,row:r,index:a,bordered:o}=e;return l?t.createElement(t.Fragment,null,t.createElement("tr",{key:`label-${a}`,className:`${i}-row`},b(r,e,Object.assign({component:"th",type:"label",showLabel:!0},n))),t.createElement("tr",{key:`content-${a}`,className:`${i}-row`},b(r,e,Object.assign({component:"td",type:"content",showContent:!0},n)))):t.createElement("tr",{key:a,className:`${i}-row`},b(r,e,Object.assign({component:o?["th","td"]:"td",type:"item",showLabel:!0,showContent:!0},n)))};e.i(296059);var p=e.i(915654),h=e.i(183293),f=e.i(246422),y=e.i(838378);let $=(0,f.genStyleHooks)("Descriptions",e=>(e=>{let{componentCls:t,extraColor:n,itemPaddingBottom:i,itemPaddingEnd:l,colonMarginRight:r,colonMarginLeft:a,titleMarginBottom:o}=e;return{[t]:Object.assign(Object.assign(Object.assign({},(0,h.resetComponent)(e)),(e=>{let{componentCls:t,labelBg:n}=e;return{[`&${t}-bordered`]:{[`> ${t}-view`]:{border:`${(0,p.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,"> table":{tableLayout:"auto"},[`${t}-row`]:{borderBottom:`${(0,p.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,"&:first-child":{"> th:first-child, > td:first-child":{borderStartStartRadius:e.borderRadiusLG}},"&:last-child":{borderBottom:"none","> th:first-child, > td:first-child":{borderEndStartRadius:e.borderRadiusLG}},[`> ${t}-item-label, > ${t}-item-content`]:{padding:`${(0,p.unit)(e.padding)} ${(0,p.unit)(e.paddingLG)}`,borderInlineEnd:`${(0,p.unit)(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,"&:last-child":{borderInlineEnd:"none"}},[`> ${t}-item-label`]:{color:e.colorTextSecondary,backgroundColor:n,"&::after":{display:"none"}}}},[`&${t}-middle`]:{[`${t}-row`]:{[`> ${t}-item-label, > ${t}-item-content`]:{padding:`${(0,p.unit)(e.paddingSM)} ${(0,p.unit)(e.paddingLG)}`}}},[`&${t}-small`]:{[`${t}-row`]:{[`> ${t}-item-label, > ${t}-item-content`]:{padding:`${(0,p.unit)(e.paddingXS)} ${(0,p.unit)(e.padding)}`}}}}}})(e)),{"&-rtl":{direction:"rtl"},[`${t}-header`]:{display:"flex",alignItems:"center",marginBottom:o},[`${t}-title`]:Object.assign(Object.assign({},h.textEllipsis),{flex:"auto",color:e.titleColor,fontWeight:e.fontWeightStrong,fontSize:e.fontSizeLG,lineHeight:e.lineHeightLG}),[`${t}-extra`]:{marginInlineStart:"auto",color:n,fontSize:e.fontSize},[`${t}-view`]:{width:"100%",borderRadius:e.borderRadiusLG,table:{width:"100%",tableLayout:"fixed",borderCollapse:"collapse"}},[`${t}-row`]:{"> th, > td":{paddingBottom:i,paddingInlineEnd:l},"> th:last-child, > td:last-child":{paddingInlineEnd:0},"&:last-child":{borderBottom:"none","> th, > td":{paddingBottom:0}}},[`${t}-item-label`]:{color:e.labelColor,fontWeight:"normal",fontSize:e.fontSize,lineHeight:e.lineHeight,textAlign:"start","&::after":{content:'":"',position:"relative",top:-.5,marginInline:`${(0,p.unit)(a)} ${(0,p.unit)(r)}`},[`&${t}-item-no-colon::after`]:{content:'""'}},[`${t}-item-no-label`]:{"&::after":{margin:0,content:'""'}},[`${t}-item-content`]:{display:"table-cell",flex:1,color:e.contentColor,fontSize:e.fontSize,lineHeight:e.lineHeight,wordBreak:"break-word",overflowWrap:"break-word"},[`${t}-item`]:{paddingBottom:0,verticalAlign:"top","&-container":{display:"flex",[`${t}-item-label`]:{display:"inline-flex",alignItems:"baseline"},[`${t}-item-content`]:{display:"inline-flex",alignItems:"baseline",minWidth:"1em"}}},"&-middle":{[`${t}-row`]:{"> th, > td":{paddingBottom:e.paddingSM}}},"&-small":{[`${t}-row`]:{"> th, > td":{paddingBottom:e.paddingXS}}}})}})((0,y.mergeToken)(e,{})),e=>({labelBg:e.colorFillAlter,labelColor:e.colorTextTertiary,titleColor:e.colorText,titleMarginBottom:e.fontSizeSM*e.lineHeightSM,itemPaddingBottom:e.padding,itemPaddingEnd:e.padding,colonMarginRight:e.marginXS,colonMarginLeft:e.marginXXS/2,contentColor:e.colorText,extraColor:e.colorText}));var v=function(e,t){var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(n[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,i=Object.getOwnPropertySymbols(e);lt.indexOf(i[l])&&Object.prototype.propertyIsEnumerable.call(e,i[l])&&(n[i[l]]=e[i[l]]);return n};let O=e=>{let g,{prefixCls:b,title:p,extra:h,column:f,colon:y=!0,bordered:O,layout:j,children:x,className:S,rootClassName:C,style:E,size:w,labelStyle:z,contentStyle:M,styles:B,items:N,classNames:T}=e,P=v(e,["prefixCls","title","extra","column","colon","bordered","layout","children","className","rootClassName","style","size","labelStyle","contentStyle","styles","items","classNames"]),{getPrefixCls:k,direction:R,className:L,style:H,classNames:I,styles:G}=(0,l.useComponentConfig)("descriptions"),W=k("descriptions",b),D=(0,a.default)(),A=t.useMemo(()=>{var e;return"number"==typeof f?f:null!=(e=(0,i.matchScreen)(D,Object.assign(Object.assign({},o),f)))?e:3},[D,f]),F=(g=t.useMemo(()=>N||(0,c.default)(x).map(e=>Object.assign(Object.assign({},null==e?void 0:e.props),{key:e.key})),[N,x]),t.useMemo(()=>g.map(e=>{var{span:t}=e,n=d(e,["span"]);return"filled"===t?Object.assign(Object.assign({},n),{filled:!0}):Object.assign(Object.assign({},n),{span:"number"==typeof t?t:(0,i.matchScreen)(D,t)})}),[g,D])),X=(0,r.default)(w),K=((e,n)=>{let[i,l]=(0,t.useMemo)(()=>{let t,i,l,r;return t=[],i=[],l=!1,r=0,n.filter(e=>e).forEach(n=>{let{filled:a}=n,o=u(n,["filled"]);if(a){i.push(o),t.push(i),i=[],r=0;return}let s=e-r;(r+=n.span||1)>=e?(r>e?(l=!0,i.push(Object.assign(Object.assign({},o),{span:s}))):i.push(o),t.push(i),i=[],r=0):i.push(o)}),i.length>0&&t.push(i),[t=t.map(t=>{let n=t.reduce((e,t)=>e+(t.span||1),0);if(n({labelStyle:z,contentStyle:M,styles:{content:Object.assign(Object.assign({},G.content),null==B?void 0:B.content),label:Object.assign(Object.assign({},G.label),null==B?void 0:B.label)},classNames:{label:(0,n.default)(I.label,null==T?void 0:T.label),content:(0,n.default)(I.content,null==T?void 0:T.content)}}),[z,M,B,T,I,G]);return q(t.createElement(s.Provider,{value:V},t.createElement("div",Object.assign({className:(0,n.default)(W,L,I.root,null==T?void 0:T.root,{[`${W}-${X}`]:X&&"default"!==X,[`${W}-bordered`]:!!O,[`${W}-rtl`]:"rtl"===R},S,C,U,Q),style:Object.assign(Object.assign(Object.assign(Object.assign({},H),G.root),null==B?void 0:B.root),E)},P),(p||h)&&t.createElement("div",{className:(0,n.default)(`${W}-header`,I.header,null==T?void 0:T.header),style:Object.assign(Object.assign({},G.header),null==B?void 0:B.header)},p&&t.createElement("div",{className:(0,n.default)(`${W}-title`,I.title,null==T?void 0:T.title),style:Object.assign(Object.assign({},G.title),null==B?void 0:B.title)},p),h&&t.createElement("div",{className:(0,n.default)(`${W}-extra`,I.extra,null==T?void 0:T.extra),style:Object.assign(Object.assign({},G.extra),null==B?void 0:B.extra)},h)),t.createElement("div",{className:`${W}-view`},t.createElement("table",null,t.createElement("tbody",null,K.map((e,n)=>t.createElement(m,{key:n,index:n,colon:y,prefixCls:W,vertical:"vertical"===j,bordered:O,row:e}))))))))};O.Item=({children:e})=>e,e.s(["Descriptions",0,O],869216)},368869,e=>{"use strict";e.i(296059);var t=e.i(868297),n=e.i(732961),i=e.i(289882),l=e.i(170517),r=e.i(628882),a=e.i(320890),o=e.i(104458),s=e.i(722319),c=e.i(8398),d=e.i(279728);e.i(765846);var u=e.i(602716),g=e.i(328052),b=e.i(135551);let m=(e,t)=>new b.FastColor(e).setA(t).toRgbString(),p=(e,t)=>new b.FastColor(e).lighten(t).toHexString(),h=e=>{let t=(0,u.generate)(e,{theme:"dark"});return{1:t[0],2:t[1],3:t[2],4:t[3],5:t[6],6:t[5],7:t[4],8:t[6],9:t[5],10:t[4]}},f=(e,t)=>{let n=e||"#000",i=t||"#fff";return{colorBgBase:n,colorTextBase:i,colorText:m(i,.85),colorTextSecondary:m(i,.65),colorTextTertiary:m(i,.45),colorTextQuaternary:m(i,.25),colorFill:m(i,.18),colorFillSecondary:m(i,.12),colorFillTertiary:m(i,.08),colorFillQuaternary:m(i,.04),colorBgSolid:m(i,.95),colorBgSolidHover:m(i,1),colorBgSolidActive:m(i,.9),colorBgElevated:p(n,12),colorBgContainer:p(n,8),colorBgLayout:p(n,0),colorBgSpotlight:p(n,26),colorBgBlur:m(i,.04),colorBorder:p(n,26),colorBorderSecondary:p(n,19)}},y={defaultSeed:a.defaultConfig.token,useToken:function(){let[e,t,n]=(0,o.useToken)();return{theme:e,token:t,hashId:n}},defaultAlgorithm:s.default,darkAlgorithm:(e,t)=>{let n=Object.keys(l.defaultPresetColors).map(t=>{let n=(0,u.generate)(e[t],{theme:"dark"});return Array.from({length:10},()=>1).reduce((e,i,l)=>(e[`${t}-${l+1}`]=n[l],e[`${t}${l+1}`]=n[l],e),{})}).reduce((e,t)=>e=Object.assign(Object.assign({},e),t),{}),i=null!=t?t:(0,s.default)(e),r=(0,g.default)(e,{generateColorPalettes:h,generateNeutralColorPalettes:f});return Object.assign(Object.assign(Object.assign(Object.assign({},i),n),r),{colorPrimaryBg:r.colorPrimaryBorder,colorPrimaryBgHover:r.colorPrimaryBorderHover})},compactAlgorithm:(e,t)=>{let n=null!=t?t:(0,s.default)(e),i=n.fontSizeSM,l=n.controlHeight-4;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},n),function(e){let{sizeUnit:t,sizeStep:n}=e,i=n-2;return{sizeXXL:t*(i+10),sizeXL:t*(i+6),sizeLG:t*(i+2),sizeMD:t*(i+2),sizeMS:t*(i+1),size:t*i,sizeSM:t*i,sizeXS:t*(i-1),sizeXXS:t*(i-1)}}(null!=t?t:e)),(0,d.default)(i)),{controlHeight:l}),(0,c.default)(Object.assign(Object.assign({},n),{controlHeight:l})))},getDesignToken:e=>{let a=(null==e?void 0:e.algorithm)?(0,t.createTheme)(e.algorithm):i.default,o=Object.assign(Object.assign({},l.default),null==e?void 0:e.token);return(0,n.getComputedToken)(o,{override:null==e?void 0:e.token},a,r.default)},defaultConfig:a.defaultConfig,_internalContext:a.DesignTokenContext};e.s(["theme",0,y],368869)},127952,e=>{"use strict";var t=e.i(843476),n=e.i(560445),i=e.i(175712),l=e.i(869216),r=e.i(311451),a=e.i(212931),o=e.i(898586),s=e.i(368869),c=e.i(270377),d=e.i(271645);e.s(["default",0,function({isOpen:e,title:u,alertMessage:g,message:b,resourceInformationTitle:m,resourceInformation:p,onCancel:h,onOk:f,confirmLoading:y,requiredConfirmation:$}){let{Title:v,Text:O}=o.Typography,{token:j}=s.theme.useToken(),[x,S]=(0,d.useState)("");return(0,d.useEffect)(()=>{e&&S("")},[e]),(0,t.jsx)(a.Modal,{title:u,open:e,onOk:f,onCancel:h,confirmLoading:y,okText:y?"Deleting...":"Delete",cancelText:"Cancel",okButtonProps:{danger:!0,disabled:!!$&&x!==$||y},cancelButtonProps:{disabled:y},children:(0,t.jsxs)("div",{className:"space-y-4",children:[g&&(0,t.jsx)(n.Alert,{message:g,type:"warning"}),(0,t.jsx)(i.Card,{title:m,className:"mt-4",styles:{body:{padding:"16px"},header:{backgroundColor:j.colorErrorBg,borderColor:j.colorErrorBorder}},style:{backgroundColor:j.colorErrorBg,borderColor:j.colorErrorBorder},children:(0,t.jsx)(l.Descriptions,{column:1,size:"small",children:p&&p.map(({label:e,value:n,...i})=>(0,t.jsx)(l.Descriptions.Item,{label:(0,t.jsx)("span",{className:"font-semibold",children:e}),children:(0,t.jsx)(O,{...i,children:n??"-"})},e))})}),(0,t.jsx)("div",{children:(0,t.jsx)(O,{children:b})}),$&&(0,t.jsxs)("div",{className:"mb-6 mt-4 pt-4 border-t border-gray-200 dark:border-gray-700",children:[(0,t.jsxs)(O,{className:"block text-base font-medium text-gray-700 dark:text-gray-300 mb-2",children:[(0,t.jsx)(O,{children:"Type "}),(0,t.jsx)(O,{strong:!0,type:"danger",children:$}),(0,t.jsx)(O,{children:" to confirm deletion:"})]}),(0,t.jsx)(r.Input,{value:x,onChange:e=>S(e.target.value),placeholder:$,className:"rounded-md",prefix:(0,t.jsx)(c.ExclamationCircleOutlined,{style:{color:j.colorError}}),autoFocus:!0})]})]})})}])}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/01wjkyxc6hqho.js b/litellm/proxy/_experimental/out/_next/static/chunks/01wjkyxc6hqho.js new file mode 100644 index 00000000000..0c6112b4cc7 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/01wjkyxc6hqho.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,94629,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"}))});e.s(["SwitchVerticalIcon",0,r],94629)},728889,e=>{"use strict";var t=e.i(290571),r=e.i(271645),l=e.i(829087),a=e.i(480731),s=e.i(444755),i=e.i(673706),o=e.i(95779);let n={xs:{paddingX:"px-1.5",paddingY:"py-1.5"},sm:{paddingX:"px-1.5",paddingY:"py-1.5"},md:{paddingX:"px-2",paddingY:"py-2"},lg:{paddingX:"px-2",paddingY:"py-2"},xl:{paddingX:"px-2.5",paddingY:"py-2.5"}},d={xs:{height:"h-3",width:"w-3"},sm:{height:"h-5",width:"w-5"},md:{height:"h-5",width:"w-5"},lg:{height:"h-7",width:"w-7"},xl:{height:"h-9",width:"w-9"}},c={simple:{rounded:"",border:"",ring:"",shadow:""},light:{rounded:"rounded-tremor-default",border:"",ring:"",shadow:""},shadow:{rounded:"rounded-tremor-default",border:"border",ring:"",shadow:"shadow-tremor-card dark:shadow-dark-tremor-card"},solid:{rounded:"rounded-tremor-default",border:"border-2",ring:"ring-1",shadow:""},outlined:{rounded:"rounded-tremor-default",border:"border",ring:"ring-2",shadow:""}},m=(0,i.makeClassName)("Icon"),u=r.default.forwardRef((e,u)=>{let{icon:g,variant:x="simple",tooltip:h,size:p=a.Sizes.SM,color:b,className:f}=e,j=(0,t.__rest)(e,["icon","variant","tooltip","size","color","className"]),w=((e,t)=>{switch(e){case"simple":return{textColor:t?(0,i.getColorClassNames)(t,o.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:"",borderColor:"",ringColor:""};case"light":return{textColor:t?(0,i.getColorClassNames)(t,o.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,s.tremorTwMerge)((0,i.getColorClassNames)(t,o.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-brand-muted dark:bg-dark-tremor-brand-muted",borderColor:"",ringColor:""};case"shadow":return{textColor:t?(0,i.getColorClassNames)(t,o.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,s.tremorTwMerge)((0,i.getColorClassNames)(t,o.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:"border-tremor-border dark:border-dark-tremor-border",ringColor:""};case"solid":return{textColor:t?(0,i.getColorClassNames)(t,o.colorPalette.text).textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:t?(0,s.tremorTwMerge)((0,i.getColorClassNames)(t,o.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-brand dark:bg-dark-tremor-brand",borderColor:"border-tremor-brand-inverted dark:border-dark-tremor-brand-inverted",ringColor:"ring-tremor-ring dark:ring-dark-tremor-ring"};case"outlined":return{textColor:t?(0,i.getColorClassNames)(t,o.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,s.tremorTwMerge)((0,i.getColorClassNames)(t,o.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:t?(0,i.getColorClassNames)(t,o.colorPalette.ring).borderColor:"border-tremor-brand-subtle dark:border-dark-tremor-brand-subtle",ringColor:t?(0,s.tremorTwMerge)((0,i.getColorClassNames)(t,o.colorPalette.ring).ringColor,"ring-opacity-40"):"ring-tremor-brand-muted dark:ring-dark-tremor-brand-muted"}}})(x,b),{tooltipProps:v,getReferenceProps:C}=(0,l.useTooltip)();return r.default.createElement("span",Object.assign({ref:(0,i.mergeRefs)([u,v.refs.setReference]),className:(0,s.tremorTwMerge)(m("root"),"inline-flex shrink-0 items-center justify-center",w.bgColor,w.textColor,w.borderColor,w.ringColor,c[x].rounded,c[x].border,c[x].shadow,c[x].ring,n[p].paddingX,n[p].paddingY,f)},C,j),r.default.createElement(l.default,Object.assign({text:h},v)),r.default.createElement(g,{className:(0,s.tremorTwMerge)(m("icon"),"shrink-0",d[p].height,d[p].width)}))});u.displayName="Icon",e.s(["default",0,u],728889)},752978,e=>{"use strict";var t=e.i(728889);e.s(["Icon",()=>t.default])},591935,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"}))});e.s(["PencilAltIcon",0,r],591935)},871943,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"}))});e.s(["ChevronDownIcon",0,r],871943)},360820,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 15l7-7 7 7"}))});e.s(["ChevronUpIcon",0,r],360820)},269200,e=>{"use strict";var t=e.i(290571),r=e.i(271645),l=e.i(444755);let a=(0,e.i(673706).makeClassName)("Table"),s=r.default.forwardRef((e,s)=>{let{children:i,className:o}=e,n=(0,t.__rest)(e,["children","className"]);return r.default.createElement("div",{className:(0,l.tremorTwMerge)(a("root"),"overflow-auto",o)},r.default.createElement("table",Object.assign({ref:s,className:(0,l.tremorTwMerge)(a("table"),"w-full text-tremor-default","text-tremor-content","dark:text-dark-tremor-content")},n),i))});s.displayName="Table",e.s(["Table",0,s],269200)},427612,e=>{"use strict";var t=e.i(290571),r=e.i(271645),l=e.i(444755);let a=(0,e.i(673706).makeClassName)("TableHead"),s=r.default.forwardRef((e,s)=>{let{children:i,className:o}=e,n=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("thead",Object.assign({ref:s,className:(0,l.tremorTwMerge)(a("root"),"text-left","text-tremor-content","dark:text-dark-tremor-content",o)},n),i))});s.displayName="TableHead",e.s(["TableHead",0,s],427612)},64848,e=>{"use strict";var t=e.i(290571),r=e.i(271645),l=e.i(444755);let a=(0,e.i(673706).makeClassName)("TableHeaderCell"),s=r.default.forwardRef((e,s)=>{let{children:i,className:o}=e,n=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("th",Object.assign({ref:s,className:(0,l.tremorTwMerge)(a("root"),"whitespace-nowrap text-left font-semibold top-0 px-4 py-3.5","text-tremor-content-strong","dark:text-dark-tremor-content-strong",o)},n),i))});s.displayName="TableHeaderCell",e.s(["TableHeaderCell",0,s],64848)},942232,e=>{"use strict";var t=e.i(290571),r=e.i(271645),l=e.i(444755);let a=(0,e.i(673706).makeClassName)("TableBody"),s=r.default.forwardRef((e,s)=>{let{children:i,className:o}=e,n=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("tbody",Object.assign({ref:s,className:(0,l.tremorTwMerge)(a("root"),"align-top divide-y","divide-tremor-border","dark:divide-dark-tremor-border",o)},n),i))});s.displayName="TableBody",e.s(["TableBody",0,s],942232)},496020,e=>{"use strict";var t=e.i(290571),r=e.i(271645),l=e.i(444755);let a=(0,e.i(673706).makeClassName)("TableRow"),s=r.default.forwardRef((e,s)=>{let{children:i,className:o}=e,n=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("tr",Object.assign({ref:s,className:(0,l.tremorTwMerge)(a("row"),o)},n),i))});s.displayName="TableRow",e.s(["TableRow",0,s],496020)},977572,e=>{"use strict";var t=e.i(290571),r=e.i(271645),l=e.i(444755);let a=(0,e.i(673706).makeClassName)("TableCell"),s=r.default.forwardRef((e,s)=>{let{children:i,className:o}=e,n=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("td",Object.assign({ref:s,className:(0,l.tremorTwMerge)(a("root"),"align-middle whitespace-nowrap text-left p-4",o)},n),i))});s.displayName="TableCell",e.s(["TableCell",0,s],977572)},68155,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"}))});e.s(["TrashIcon",0,r],68155)},278587,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"}))});e.s(["RefreshIcon",0,r],278587)},250980,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z"}))});e.s(["PlusCircleIcon",0,r],250980)},991124,e=>{"use strict";let t=(0,e.i(475254).default)("copy",[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]]);e.s(["default",0,t])},678745,e=>{"use strict";let t=(0,e.i(475254).default)("check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]]);e.s(["default",0,t])},678784,e=>{"use strict";var t=e.i(678745);e.s(["CheckIcon",()=>t.default])},118366,e=>{"use strict";var t=e.i(991124);e.s(["CopyIcon",()=>t.default])},601757,e=>{"use strict";var t=e.i(843476),r=e.i(271645),l=e.i(752978),a=e.i(994388),s=e.i(309426),i=e.i(599724),o=e.i(350967),n=e.i(278587),d=e.i(304967),c=e.i(629569),m=e.i(389083),u=e.i(677667),g=e.i(898667),x=e.i(130643),h=e.i(808613),p=e.i(311451),b=e.i(199133),f=e.i(592968),j=e.i(827252),w=e.i(702597),v=e.i(355619),C=e.i(602869),N=e.i(727749),y=e.i(435451),T=e.i(860585),k=e.i(500330),_=e.i(678784),I=e.i(118366),M=e.i(464571);let E=({tagId:e,onClose:l,accessToken:s,is_admin:o,editTag:n})=>{let[E]=h.Form.useForm(),[S,B]=(0,r.useState)(null),[R,L]=(0,r.useState)(n),[D,F]=(0,r.useState)([]),[A,P]=(0,r.useState)({}),O=async(e,t)=>{await (0,k.copyToClipboard)(e)&&(P(e=>({...e,[t]:!0})),setTimeout(()=>{P(e=>({...e,[t]:!1}))},2e3))},H=async()=>{if(s)try{let t=(await (0,C.tagInfoCall)(s,[e]))[e];t&&(B(t),n&&E.setFieldsValue({name:t.name,description:t.description,models:t.models,max_budget:t.litellm_budget_table?.max_budget,budget_duration:t.litellm_budget_table?.budget_duration}))}catch(e){console.error("Error fetching tag details:",e),N.default.fromBackend("Error fetching tag details: "+e)}};(0,r.useEffect)(()=>{H()},[e,s]),(0,r.useEffect)(()=>{s&&(0,w.fetchUserModels)("dummy-user","Admin",s,F)},[s]);let z=async e=>{if(s)try{await (0,C.tagUpdateCall)(s,{name:e.name,description:e.description,models:e.models,max_budget:e.max_budget,tpm_limit:e.tpm_limit,rpm_limit:e.rpm_limit,budget_duration:e.budget_duration}),N.default.success("Tag updated successfully"),L(!1),H()}catch(e){console.error("Error updating tag:",e),N.default.fromBackend("Error updating tag: "+e)}};return S?(0,t.jsxs)("div",{className:"p-4",children:[(0,t.jsxs)("div",{className:"flex justify-between items-center mb-6",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(a.Button,{onClick:l,className:"mb-4",children:"← Back to Tags"}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(i.Text,{className:"font-medium",children:"Tag Name:"}),(0,t.jsx)("span",{className:"font-mono px-2 py-1 bg-gray-100 rounded-sm text-sm border border-gray-200",children:S.name}),(0,t.jsx)(M.Button,{type:"text",size:"small",icon:A["tag-name"]?(0,t.jsx)(_.CheckIcon,{size:12}):(0,t.jsx)(I.CopyIcon,{size:12}),onClick:()=>O(S.name,"tag-name"),className:`transition-all duration-200 ${A["tag-name"]?"text-green-600 bg-green-50 border-green-200":"text-gray-500 hover:text-gray-700 hover:bg-gray-100"}`})]}),(0,t.jsx)(i.Text,{className:"text-gray-500",children:S.description||"No description"})]}),o&&!R&&(0,t.jsx)(a.Button,{onClick:()=>L(!0),children:"Edit Tag"})]}),R?(0,t.jsx)(d.Card,{children:(0,t.jsxs)(h.Form,{form:E,onFinish:z,layout:"vertical",initialValues:S,children:[(0,t.jsx)(h.Form.Item,{label:"Tag Name",name:"name",rules:[{required:!0,message:"Please input a tag name"}],children:(0,t.jsx)(p.Input,{className:"rounded-md border-gray-300"})}),(0,t.jsx)(h.Form.Item,{label:"Description",name:"description",children:(0,t.jsx)(p.Input.TextArea,{rows:4})}),(0,t.jsx)(h.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Models",(0,t.jsx)(f.Tooltip,{title:"Select which models are allowed to process this type of data",children:(0,t.jsx)(j.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"models",children:(0,t.jsx)(b.Select,{mode:"multiple",placeholder:"Select Models",children:D.map(e=>(0,t.jsx)(b.Select.Option,{value:e,children:(0,v.getModelDisplayName)(e)},e))})}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(g.AccordionHeader,{children:(0,t.jsx)(c.Title,{className:"m-0",children:"Budget & Rate Limits"})}),(0,t.jsxs)(x.AccordionBody,{children:[(0,t.jsx)(h.Form.Item,{label:(0,t.jsxs)("span",{children:["Max Budget (USD)"," ",(0,t.jsx)(f.Tooltip,{title:"Maximum amount in USD this tag can spend",children:(0,t.jsx)(j.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"max_budget",children:(0,t.jsx)(y.default,{step:.01,precision:2,width:200})}),(0,t.jsx)(h.Form.Item,{label:(0,t.jsxs)("span",{children:["Reset Budget"," ",(0,t.jsx)(f.Tooltip,{title:"How often the budget should reset",children:(0,t.jsx)(j.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"budget_duration",children:(0,t.jsx)(T.default,{onChange:e=>E.setFieldValue("budget_duration",e)})}),(0,t.jsx)("div",{className:"mt-4 p-3 bg-gray-50 rounded-md border border-gray-200",children:(0,t.jsxs)("p",{className:"text-sm text-gray-600",children:["TPM/RPM limits for tags are not currently supported. If you need this feature, please"," ",(0,t.jsx)("a",{href:"https://github.com/BerriAI/litellm/issues/new",target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:text-blue-800 underline",children:"create a GitHub issue"}),"."]})})]})]}),(0,t.jsxs)("div",{className:"flex justify-end space-x-2",children:[(0,t.jsx)(a.Button,{onClick:()=>L(!1),children:"Cancel"}),(0,t.jsx)(a.Button,{type:"submit",children:"Save Changes"})]})]})}):(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)(d.Card,{children:[(0,t.jsx)(c.Title,{children:"Tag Details"}),(0,t.jsxs)("div",{className:"space-y-4 mt-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(i.Text,{className:"font-medium",children:"Name"}),(0,t.jsx)(i.Text,{children:S.name})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(i.Text,{className:"font-medium",children:"Description"}),(0,t.jsx)(i.Text,{children:S.description||"-"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(i.Text,{className:"font-medium",children:"Allowed Models"}),(0,t.jsx)("div",{className:"flex flex-wrap gap-2 mt-2",children:S.models&&0!==S.models.length?S.models.map(e=>(0,t.jsx)(m.Badge,{color:"blue",children:(0,t.jsx)(f.Tooltip,{title:`ID: ${e}`,children:S.model_info?.[e]||e})},e)):(0,t.jsx)(m.Badge,{color:"red",children:"All Models"})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(i.Text,{className:"font-medium",children:"Created"}),(0,t.jsx)(i.Text,{children:S.created_at?new Date(S.created_at).toLocaleString():"-"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(i.Text,{className:"font-medium",children:"Last Updated"}),(0,t.jsx)(i.Text,{children:S.updated_at?new Date(S.updated_at).toLocaleString():"-"})]})]})]}),S.litellm_budget_table&&(0,t.jsxs)(d.Card,{children:[(0,t.jsx)(c.Title,{children:"Budget & Rate Limits"}),(0,t.jsxs)("div",{className:"space-y-4 mt-4",children:[void 0!==S.litellm_budget_table.max_budget&&null!==S.litellm_budget_table.max_budget&&(0,t.jsxs)("div",{children:[(0,t.jsx)(i.Text,{className:"font-medium",children:"Max Budget"}),(0,t.jsxs)(i.Text,{children:["$",S.litellm_budget_table.max_budget]})]}),S.litellm_budget_table.budget_duration&&(0,t.jsxs)("div",{children:[(0,t.jsx)(i.Text,{className:"font-medium",children:"Budget Duration"}),(0,t.jsx)(i.Text,{children:S.litellm_budget_table.budget_duration})]}),void 0!==S.litellm_budget_table.tpm_limit&&null!==S.litellm_budget_table.tpm_limit&&(0,t.jsxs)("div",{children:[(0,t.jsx)(i.Text,{className:"font-medium",children:"TPM Limit"}),(0,t.jsx)(i.Text,{children:S.litellm_budget_table.tpm_limit.toLocaleString()})]}),void 0!==S.litellm_budget_table.rpm_limit&&null!==S.litellm_budget_table.rpm_limit&&(0,t.jsxs)("div",{children:[(0,t.jsx)(i.Text,{className:"font-medium",children:"RPM Limit"}),(0,t.jsx)(i.Text,{children:S.litellm_budget_table.rpm_limit.toLocaleString()})]})]})]})]})]}):(0,t.jsx)("div",{children:"Loading..."})};var S=e.i(871943),B=e.i(360820),R=e.i(591935),L=e.i(94629),D=e.i(68155),F=e.i(152990),A=e.i(682830),P=e.i(269200),O=e.i(942232),H=e.i(977572),z=e.i(427612),U=e.i(64848),V=e.i(496020);let W="This is just a spend tag that was passed dynamically in a request. It does not control any LLM models.",Y=({data:e,onEdit:s,onDelete:o,onSelectTag:n})=>{let[d,c]=r.default.useState([{id:"created_at",desc:!0}]),u=[{header:"Tag Name",accessorKey:"name",cell:({row:e})=>{let r=e.original,l=r.description===W;return(0,t.jsx)("div",{className:"overflow-hidden",children:(0,t.jsx)(f.Tooltip,{title:l?"You cannot view the information of a dynamically generated spend tag":r.name,children:(0,t.jsx)(a.Button,{size:"xs",variant:"light",className:"font-mono text-blue-500 bg-blue-50 hover:bg-blue-100 text-xs font-normal px-2 py-0.5",onClick:()=>n(r.name),disabled:l,children:r.name})})})}},{header:"Description",accessorKey:"description",cell:({row:e})=>{let r=e.original;return(0,t.jsx)(f.Tooltip,{title:r.description,children:(0,t.jsx)("span",{className:"text-xs",children:r.description||"-"})})}},{header:"Allowed Models",accessorKey:"models",cell:({row:e})=>{let r=e.original;return(0,t.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:r?.models?.length===0?(0,t.jsx)(m.Badge,{size:"xs",className:"mb-1",color:"red",children:"All Models"}):r?.models?.map(e=>(0,t.jsx)(m.Badge,{size:"xs",className:"mb-1",color:"blue",children:(0,t.jsx)(f.Tooltip,{title:`ID: ${e}`,children:(0,t.jsx)(i.Text,{children:r.model_info?.[e]||e})})},e))})}},{header:"Created",accessorKey:"created_at",sortingFn:"datetime",cell:({row:e})=>{let r=e.original;return(0,t.jsx)("span",{className:"text-xs",children:new Date(r.created_at).toLocaleDateString()})}},{id:"actions",header:"Actions",cell:({row:e})=>{let r=e.original,a=r.description===W;return(0,t.jsxs)("div",{className:"flex space-x-2",children:[a?(0,t.jsx)(f.Tooltip,{title:"Dynamically generated spend tags cannot be edited",children:(0,t.jsx)(l.Icon,{icon:R.PencilAltIcon,size:"sm",className:"opacity-50 cursor-not-allowed","aria-label":"Edit tag (disabled)"})}):(0,t.jsx)(f.Tooltip,{title:"Edit tag",children:(0,t.jsx)(l.Icon,{icon:R.PencilAltIcon,size:"sm",onClick:()=>s(r),className:"cursor-pointer hover:text-blue-500"})}),a?(0,t.jsx)(f.Tooltip,{title:"Dynamically generated spend tags cannot be deleted",children:(0,t.jsx)(l.Icon,{icon:D.TrashIcon,size:"sm",className:"opacity-50 cursor-not-allowed","aria-label":"Delete tag (disabled)"})}):(0,t.jsx)(f.Tooltip,{title:"Delete tag",children:(0,t.jsx)(l.Icon,{icon:D.TrashIcon,size:"sm",onClick:()=>o(r.name),className:"cursor-pointer hover:text-red-500"})})]})}}],g=(0,F.useReactTable)({data:e,columns:u,state:{sorting:d},onSortingChange:c,getCoreRowModel:(0,A.getCoreRowModel)(),getSortedRowModel:(0,A.getSortedRowModel)(),enableSorting:!0});return(0,t.jsx)("div",{className:"rounded-lg custom-border relative",children:(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsxs)(P.Table,{className:"[&_td]:py-0.5 [&_th]:py-1",children:[(0,t.jsx)(z.TableHead,{children:g.getHeaderGroups().map(e=>(0,t.jsx)(V.TableRow,{children:e.headers.map(e=>(0,t.jsx)(U.TableHeaderCell,{className:`py-1 h-8 ${"actions"===e.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)]":""}`,onClick:e.column.getToggleSortingHandler(),children:(0,t.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,t.jsx)("div",{className:"flex items-center",children:e.isPlaceholder?null:(0,F.flexRender)(e.column.columnDef.header,e.getContext())}),"actions"!==e.id&&(0,t.jsx)("div",{className:"w-4",children:e.column.getIsSorted()?({asc:(0,t.jsx)(B.ChevronUpIcon,{className:"h-4 w-4 text-blue-500"}),desc:(0,t.jsx)(S.ChevronDownIcon,{className:"h-4 w-4 text-blue-500"})})[e.column.getIsSorted()]:(0,t.jsx)(L.SwitchVerticalIcon,{className:"h-4 w-4 text-gray-400"})})]})},e.id))},e.id))}),(0,t.jsx)(O.TableBody,{children:g.getRowModel().rows.length>0?g.getRowModel().rows.map(e=>(0,t.jsx)(V.TableRow,{className:"h-8",children:e.getVisibleCells().map(e=>(0,t.jsx)(H.TableCell,{className:`py-0.5 max-h-8 overflow-hidden text-ellipsis whitespace-nowrap ${"actions"===e.column.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)]":""}`,children:(0,F.flexRender)(e.column.columnDef.cell,e.getContext())},e.id))},e.id)):(0,t.jsx)(V.TableRow,{children:(0,t.jsx)(H.TableCell,{colSpan:u.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:"No tags found"})})})})})]})})})};var q=e.i(779241),K=e.i(212931);let X=({visible:e,onCancel:r,onSubmit:l,availableModels:s})=>{let[i]=h.Form.useForm();return(0,t.jsx)(K.Modal,{title:"Create New Tag",open:e,width:800,footer:null,onCancel:()=>{i.resetFields(),r()},children:(0,t.jsxs)(h.Form,{form:i,onFinish:e=>{l(e),i.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,t.jsx)(h.Form.Item,{label:"Tag Name",name:"tag_name",rules:[{required:!0,message:"Please input a tag name"}],children:(0,t.jsx)(q.TextInput,{})}),(0,t.jsx)(h.Form.Item,{label:"Description",name:"description",children:(0,t.jsx)(p.Input.TextArea,{rows:4})}),(0,t.jsx)(h.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Models",(0,t.jsx)(f.Tooltip,{title:"Select which models are allowed to process requests from this tag",children:(0,t.jsx)(j.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"allowed_llms",children:(0,t.jsx)(b.Select,{mode:"multiple",placeholder:"Select Models",children:s.map(e=>(0,t.jsx)(b.Select.Option,{value:e.model_info.id,children:(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{children:e.model_name}),(0,t.jsxs)("span",{className:"text-gray-400 ml-2",children:["(",e.model_info.id,")"]})]})},e.model_info.id))})}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(g.AccordionHeader,{children:(0,t.jsx)(c.Title,{className:"m-0",children:"Budget & Rate Limits (Optional)"})}),(0,t.jsxs)(x.AccordionBody,{children:[(0,t.jsx)(h.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Max Budget (USD)"," ",(0,t.jsx)(f.Tooltip,{title:"Maximum amount in USD this tag can spend. When reached, requests with this tag will be blocked",children:(0,t.jsx)(j.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"max_budget",children:(0,t.jsx)(y.default,{step:.01,precision:2,width:200})}),(0,t.jsx)(h.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Reset Budget"," ",(0,t.jsx)(f.Tooltip,{title:"How often the budget should reset. For example, setting 'daily' will reset the budget every 24 hours",children:(0,t.jsx)(j.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"budget_duration",children:(0,t.jsx)(T.default,{onChange:e=>i.setFieldValue("budget_duration",e)})}),(0,t.jsx)("div",{className:"mt-4 p-3 bg-gray-50 rounded-md border border-gray-200",children:(0,t.jsxs)("p",{className:"text-sm text-gray-600",children:["TPM/RPM limits for tags are not currently supported. If you need this feature, please"," ",(0,t.jsx)("a",{href:"https://github.com/BerriAI/litellm/issues/new",target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:text-blue-800 underline",children:"create a GitHub issue"}),"."]})})]})]}),(0,t.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,t.jsx)(a.Button,{type:"submit",children:"Create Tag"})})]})})},$=({accessToken:e,userID:d,userRole:c})=>{let[m,u]=(0,r.useState)([]),[g,x]=(0,r.useState)(!1),[h,p]=(0,r.useState)(null),[b,f]=(0,r.useState)(!1),[j,w]=(0,r.useState)(!1),[v,y]=(0,r.useState)(null),[T,k]=(0,r.useState)(""),[_,I]=(0,r.useState)([]),M=async()=>{if(e)try{let t=await (0,C.tagListCall)(e);u(Object.values(t))}catch(e){console.error("Error fetching tags:",e),N.default.fromBackend("Error fetching tags: "+e)}},S=async t=>{if(e)try{await (0,C.tagCreateCall)(e,{name:t.tag_name,description:t.description,models:t.allowed_llms,max_budget:t.max_budget,soft_budget:t.soft_budget,tpm_limit:t.tpm_limit,rpm_limit:t.rpm_limit,budget_duration:t.budget_duration}),N.default.success("Tag created successfully"),x(!1),M()}catch(e){console.error("Error creating tag:",e),N.default.fromBackend("Error creating tag: "+e)}},B=async e=>{y(e),w(!0)},R=async()=>{if(e&&v){try{await (0,C.tagDeleteCall)(e,v),N.default.success("Tag deleted successfully"),M()}catch(e){console.error("Error deleting tag:",e),N.default.fromBackend("Error deleting tag: "+e)}w(!1),y(null)}};return(0,r.useEffect)(()=>{d&&c&&e&&(async()=>{try{let t=await (0,C.modelInfoCall)(e,d,c);t&&t.data&&I(t.data)}catch(e){console.error("Error fetching models:",e),N.default.fromBackend("Error fetching models: "+e)}})()},[e,d,c]),(0,r.useEffect)(()=>{M()},[e]),(0,t.jsx)("div",{className:"w-full mx-4 h-[75vh]",children:h?(0,t.jsx)(E,{tagId:h,onClose:()=>{p(null),f(!1)},accessToken:e,is_admin:"Admin"===c,editTag:b}):(0,t.jsxs)("div",{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,t.jsxs)("div",{className:"flex justify-between mt-2 w-full items-center mb-4",children:[(0,t.jsx)("h1",{children:"Tag Management"}),(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[T&&(0,t.jsxs)(i.Text,{children:["Last Refreshed: ",T]}),(0,t.jsx)(l.Icon,{icon:n.RefreshIcon,variant:"shadow",size:"xs",className:"self-center cursor-pointer",onClick:()=>{M(),k(new Date().toLocaleString())}})]})]}),(0,t.jsxs)(i.Text,{className:"mb-4",children:["Click on a tag name to view and edit its details.",(0,t.jsxs)("p",{children:["You can use tags to restrict the usage of certain LLMs based on tags passed in the request. Read more about tag routing"," ",(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/tag_routing",target:"_blank",rel:"noopener noreferrer",children:"here"}),"."]})]}),(0,t.jsx)(a.Button,{className:"mb-4",onClick:()=>x(!0),children:"+ Create New Tag"}),(0,t.jsx)(o.Grid,{numItems:1,className:"gap-2 pt-2 pb-2 h-[75vh] w-full mt-2",children:(0,t.jsx)(s.Col,{numColSpan:1,children:(0,t.jsx)(Y,{data:m,onEdit:e=>{p(e.name),f(!0)},onDelete:B,onSelectTag:p})})}),(0,t.jsx)(X,{visible:g,onCancel:()=>x(!1),onSubmit:S,availableModels:_}),j&&(0,t.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,t.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,t.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,t.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,t.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,t.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,t.jsx)("div",{className:"sm:flex sm:items-start",children:(0,t.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,t.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Tag"}),(0,t.jsx)("div",{className:"mt-2",children:(0,t.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this tag?"})})]})})}),(0,t.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,t.jsx)(a.Button,{onClick:R,color:"red",className:"ml-2",children:"Delete"}),(0,t.jsx)(a.Button,{onClick:()=>{w(!1),y(null)},children:"Cancel"})]})]})]})})]})})};var G=e.i(135214);e.s(["default",0,function(){let{accessToken:e,userRole:r,userId:l}=(0,G.default)();return(0,t.jsx)($,{accessToken:e,userRole:r,userID:l})}],601757)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/01y._o853f7le.js b/litellm/proxy/_experimental/out/_next/static/chunks/01y._o853f7le.js new file mode 100644 index 00000000000..cf74c1c9c1f --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/01y._o853f7le.js @@ -0,0 +1,4 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,783222,433336,80758,402155,368578,544508,746725,835696,941444,914189,394487,e=>{"use strict";let t;e.i(247167);let r=e=>e?.ownerDocument??document,n=e=>e&&"window"in e&&e.window===e?e:r(e).defaultView||window;function o(e,t){return!!t&&!!e&&e.contains(t)}function s(e){return e.target}let a=null;"u">typeof Element&&Element.prototype;let i=["input:not([disabled]):not([type=hidden])","select:not([disabled])","textarea:not([disabled])","button:not([disabled])","a[href]","area[href]","summary","iframe","object","embed","audio[controls]","video[controls]",'[contenteditable]:not([contenteditable^="false"])',"permission"];i.join(":not([hidden]),"),i.push('[tabindex]:not([tabindex="-1"]):not([disabled])'),i.join(':not([hidden]):not([tabindex="-1"]),');var l=e.i(271645);let u="u">typeof document?l.default.useLayoutEffect:()=>{};function c(e){return e.nativeEvent=e,e.isDefaultPrevented=()=>e.defaultPrevented,e.isPropagationStopped=()=>e.cancelBubble,e.persist=()=>{},e}function d(e){let t=(0,l.useRef)({isFocused:!1,observer:null});return u(()=>{let e=t.current;return()=>{e.observer&&(e.observer.disconnect(),e.observer=null)}},[]),(0,l.useCallback)(r=>{let n=s(r);(n instanceof HTMLButtonElement||n instanceof HTMLInputElement||n instanceof HTMLTextAreaElement||n instanceof HTMLSelectElement)&&(t.current.isFocused=!0,n.addEventListener("focusout",r=>{if(t.current.isFocused=!1,n.disabled){let t=c(r);e?.(t)}t.current.observer&&(t.current.observer.disconnect(),t.current.observer=null)},{once:!0}),t.current.observer=new MutationObserver(()=>{if(t.current.isFocused&&n.disabled){t.current.observer?.disconnect();let e=n===((e=document)=>e.activeElement)()?null:((e=document)=>e.activeElement)();n.dispatchEvent(new FocusEvent("blur",{relatedTarget:e})),n.dispatchEvent(new FocusEvent("focusout",{bubbles:!0,relatedTarget:e}))}}),t.current.observer.observe(n,{attributes:!0,attributeFilter:["disabled"]}))},[e])}function f(e){if("u"e.test(t.brand))||e.test(window.navigator.userAgent)}function p(e){return"u">typeof window&&null!=window.navigator&&e.test(window.navigator.userAgentData?.platform||window.navigator.platform)}function m(e){let t=null;return()=>(null==t&&(t=e()),t)}let b=m(function(){return p(/^Mac/i)}),v=m(function(){return p(/^iPhone/i)}),h=m(function(){return p(/^iPad/i)||b()&&navigator.maxTouchPoints>1}),g=m(function(){return v()||h()});m(function(){return b()||g()});let y=m(function(){return f(/AppleWebKit/i)&&!E()}),E=m(function(){return f(/Chrome/i)}),T=m(function(){return f(/Android/i)}),w=m(function(){return f(/Firefox/i)});function x(e,t,r=!0){let{metaKey:n,ctrlKey:o,altKey:s,shiftKey:i}=t;w()&&window.event?.type?.startsWith("key")&&"_blank"===e.target&&(b()?n=!0:o=!0);let l=y()&&b()&&!h()&&1?new KeyboardEvent("keydown",{keyIdentifier:"Enter",metaKey:n,ctrlKey:o,altKey:s,shiftKey:i}):new MouseEvent("click",{metaKey:n,ctrlKey:o,altKey:s,shiftKey:i,detail:1,bubbles:!0,cancelable:!0});x.isOpening=r;if(function(){if(null==a){a=!1;try{document.createElement("div").focus({get preventScroll(){return a=!0,!0}})}catch{}}return a}())e.focus({preventScroll:!0});else{let t=function(e){let t=e.parentNode,r=[],n=document.scrollingElement||document.documentElement;for(;t instanceof HTMLElement&&t!==n;)(t.offsetHeighttypeof window&&window.document&&window.document.createElement,new WeakMap;l.default.useId;let P=null,k=new Set,L=new Map,N=!1,C=!1,I={Tab:!0,Escape:!0};function S(e,t){for(let r of k)r(e,t)}function A(e){N=!0,x.isOpening||e.metaKey||!b()&&e.altKey||e.ctrlKey||"Control"===e.key||"Shift"===e.key||"Meta"===e.key||(P="keyboard",S("keyboard",e))}function M(e){P="pointer","pointerType"in e&&e.pointerType,("mousedown"===e.type||"pointerdown"===e.type)&&(N=!0,S("pointer",e))}function R(e){x.isOpening||(""!==e.pointerType||!e.isTrusted)&&(T()&&e.pointerType?"click"!==e.type||1!==e.buttons:0!==e.detail||e.pointerType)||(N=!0,P="virtual")}function O(e){let t=n(s(e)),o=r(s(e));s(e)!==t&&s(e)!==o&&e.isTrusted&&(N||C||(P="virtual",S("virtual",e)),N=!1,C=!1)}function D(){N=!1,C=!0}function H(e){if("u"typeof PointerEvent&&(o.addEventListener("pointerdown",M,!0),o.addEventListener("pointermove",M,!0),o.addEventListener("pointerup",M,!0)),t.addEventListener("beforeunload",()=>{j(e)},{once:!0}),L.set(t,{focus:s})}let j=(e,t)=>{let o=n(e),s=r(e);t&&s.removeEventListener("DOMContentLoaded",t),L.has(o)&&(o.HTMLElement.prototype.focus=L.get(o).focus,s.removeEventListener("keydown",A,!0),s.removeEventListener("keyup",A,!0),s.removeEventListener("click",R,!0),o.removeEventListener("focus",O,!0),o.removeEventListener("blur",D,!1),"u">typeof PointerEvent&&(s.removeEventListener("pointerdown",M,!0),s.removeEventListener("pointermove",M,!0),s.removeEventListener("pointerup",M,!0)),L.delete(o))};function K(){return"pointer"!==P}"u">typeof document&&("loading"!==(t=r(void 0)).readyState?H(void 0):t.addEventListener("DOMContentLoaded",()=>{H(void 0)}));let W=new Set(["checkbox","radio","range","color","file","image","button","submit","reset"]);function B(){let e=(0,l.useRef)(new Map),t=(0,l.useCallback)((t,r,n,o)=>{let s=o?.once?(...t)=>{e.current.delete(n),n(...t)}:n;e.current.set(n,{type:r,eventTarget:t,fn:s,options:o}),t.addEventListener(r,s,o)},[]),r=(0,l.useCallback)((t,r,n,o)=>{let s=e.current.get(n)?.fn||n;t.removeEventListener(r,s,o),e.current.delete(n)},[]),n=(0,l.useCallback)(()=>{e.current.forEach((e,t)=>{r(e.eventTarget,e.type,t,e.options)})},[r]);return(0,l.useEffect)(()=>n,[n]),{addGlobalListener:t,removeGlobalListener:r,removeAllGlobalListeners:n}}e.s(["useFocusRing",0,function(e={}){var t;let{autoFocus:a=!1,isTextInput:i,within:u}=e,f=(0,l.useRef)({isFocused:!1,isFocusVisible:a||K()}),[p,m]=(0,l.useState)(!1),[b,v]=(0,l.useState)(()=>f.current.isFocused&&f.current.isFocusVisible),h=(0,l.useCallback)(()=>v(f.current.isFocused&&f.current.isFocusVisible),[]),g=(0,l.useCallback)(e=>{f.current.isFocused=e,f.current.isFocusVisible=K(),m(e),h()},[h]);t={enabled:p,isTextInput:i},H(),(0,l.useEffect)(()=>{if(t?.enabled===!1)return;let e=(e,o)=>{var a;let i,l,u,c,d,p,m,b;a=!!t?.isTextInput,l=r(i=o?s(o):void 0),c=void 0!==(u=n(i))?u.HTMLInputElement:HTMLInputElement,d=void 0!==u?u.HTMLTextAreaElement:HTMLTextAreaElement,p=void 0!==u?u.HTMLElement:HTMLElement,m=void 0!==u?u.KeyboardEvent:KeyboardEvent,b=((e=document)=>e.activeElement)(l),(a=a||b instanceof c&&!W.has(b.type)||b instanceof d||b instanceof p&&b.isContentEditable)&&"keyboard"===e&&o instanceof m&&!I[o.key]||(e=>{f.current.isFocusVisible=e,h()})(K())};return k.add(e),()=>{k.delete(e)}},[i,p]);let{focusProps:y}=function(e){let{isDisabled:t,onFocus:n,onBlur:o,onFocusChange:a}=e,i=(0,l.useCallback)(e=>{if(s(e)===e.currentTarget)return o&&o(e),a&&a(!1),!0},[o,a]),u=d(i),c=(0,l.useCallback)(e=>{let t=s(e),o=r(t),i=o?((e=document)=>e.activeElement)(o):((e=document)=>e.activeElement)();t===e.currentTarget&&t===i&&(n&&n(e),a&&a(!0),u(e))},[a,n,u]);return{focusProps:{onFocus:!t&&(n||a||o)?c:void 0,onBlur:!t&&(o||a)?i:void 0}}}({isDisabled:u,onFocusChange:g}),{focusWithinProps:E}=function(e){let{isDisabled:t,onBlurWithin:n,onFocusWithin:a,onFocusWithinChange:i}=e,u=(0,l.useRef)({isFocusWithin:!1}),{addGlobalListener:f,removeAllGlobalListeners:p}=B(),m=(0,l.useCallback)(e=>{o(e.currentTarget,s(e))&&u.current.isFocusWithin&&!o(e.currentTarget,e.relatedTarget)&&(u.current.isFocusWithin=!1,p(),n&&n(e),i&&i(!1))},[n,i,u,p]),b=d(m),v=(0,l.useCallback)(e=>{if(!o(e.currentTarget,s(e)))return;let t=s(e),n=r(t),l=((e=document)=>e.activeElement)(n);if(!u.current.isFocusWithin&&l===t){a&&a(e),i&&i(!0),u.current.isFocusWithin=!0,b(e);let t=e.currentTarget;f(n,"focus",e=>{let r=s(e);if(u.current.isFocusWithin&&!o(t,r)){let e=new n.defaultView.FocusEvent("blur",{relatedTarget:r});Object.defineProperty(e,"target",{value:t}),Object.defineProperty(e,"currentTarget",{value:t}),m(c(e))}},{capture:!0})}},[a,i,b,f,m]);return t?{focusWithinProps:{onFocus:void 0,onBlur:void 0}}:{focusWithinProps:{onFocus:v,onBlur:m}}}({isDisabled:!u,onFocusWithinChange:g});return{isFocused:p,isFocusVisible:b,focusProps:u?E:y}}],783222);let V=!1,_=0;function G(e){"touch"===e.pointerType&&(V=!0,setTimeout(()=>{V=!1},500))}function U(){let e=r(null);if(void 0!==e)return 0===_&&"u">typeof PointerEvent&&e.addEventListener("pointerup",G),_++,()=>{!(--_>0)&&"u">typeof PointerEvent&&e.removeEventListener("pointerup",G)}}e.s(["useHover",0,function(e){let{onHoverStart:t,onHoverChange:n,onHoverEnd:a,isDisabled:i}=e,[u,c]=(0,l.useState)(!1),d=(0,l.useRef)({isHovered:!1,ignoreEmulatedMouseEvents:!1,pointerType:"",target:null}).current;(0,l.useEffect)(U,[]);let{addGlobalListener:f,removeAllGlobalListeners:p}=B(),{hoverProps:m,triggerHoverEnd:b}=(0,l.useMemo)(()=>{let e=(e,t)=>{let r=d.target;d.pointerType="",d.target=null,"touch"!==t&&d.isHovered&&r&&(d.isHovered=!1,p(),a&&a({type:"hoverend",target:r,pointerType:t}),n&&n(!1),c(!1))},l={};return"u">typeof PointerEvent&&(l.onPointerEnter=a=>{V&&"mouse"===a.pointerType||((a,l)=>{if(d.pointerType=l,i||"touch"===l||d.isHovered||!o(a.currentTarget,s(a)))return;d.isHovered=!0;let u=a.currentTarget;d.target=u,f(r(s(a)),"pointerover",t=>{d.isHovered&&d.target&&!o(d.target,s(t))&&e(t,t.pointerType)},{capture:!0}),t&&t({type:"hoverstart",target:u,pointerType:l}),n&&n(!0),c(!0)})(a,a.pointerType)},l.onPointerLeave=t=>{!i&&o(t.currentTarget,s(t))&&e(t,t.pointerType)}),{hoverProps:l,triggerHoverEnd:e}},[t,n,a,i,d,f,p]);return(0,l.useEffect)(()=>{i&&b({currentTarget:d.target},d.pointerType)},[i]),{hoverProps:m,isHovered:u}}],433336);var $=Object.defineProperty,q=(e,t,r)=>{let n;return(n="symbol"!=typeof t?t+"":t)in e?$(e,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[n]=r,r};let X=new class{constructor(){q(this,"current",this.detect()),q(this,"handoffState","pending"),q(this,"currentId",0)}set(e){this.current!==e&&(this.handoffState="pending",this.currentId=0,this.current=e)}reset(){this.set(this.detect())}nextId(){return++this.currentId}get isServer(){return"server"===this.current}get isClient(){return"client"===this.current}detect(){return"u"setTimeout(()=>{throw e}))}function Z(){let e=[],t={addEventListener:(e,r,n,o)=>(e.addEventListener(r,n,o),t.add(()=>e.removeEventListener(r,n,o))),requestAnimationFrame(...e){let r=requestAnimationFrame(...e);return t.add(()=>cancelAnimationFrame(r))},nextFrame:(...e)=>t.requestAnimationFrame(()=>t.requestAnimationFrame(...e)),setTimeout(...e){let r=setTimeout(...e);return t.add(()=>clearTimeout(r))},microTask(...e){let r={current:!0};return z(()=>{r.current&&e[0]()}),t.add(()=>{r.current=!1})},style(e,t,r){let n=e.style.getPropertyValue(t);return Object.assign(e.style,{[t]:r}),this.add(()=>{Object.assign(e.style,{[t]:n})})},group(e){let t=Z();return e(t),this.add(()=>t.dispose())},add:t=>(e.includes(t)||e.push(t),()=>{let r=e.indexOf(t);if(r>=0)for(let t of e.splice(r,1))t()}),dispose(){for(let t of e.splice(0))t()}};return t}function J(){let[e]=(0,l.useState)(Z);return(0,l.useEffect)(()=>()=>e.dispose(),[e]),e}e.s(["env",0,X],80758),e.s(["getOwnerDocument",0,Y],402155),e.s(["microTask",0,z],368578),e.s(["disposables",0,Z],544508),e.s(["useDisposables",0,J],746725);let Q=(e,t)=>{X.isServer?(0,l.useEffect)(e,t):(0,l.useLayoutEffect)(e,t)};function ee(e){let t=(0,l.useRef)(e);return Q(()=>{t.current=e},[e]),t}e.s(["useIsoMorphicEffect",0,Q],835696),e.s(["useLatestValue",0,ee],941444);let et=function(e){let t=ee(e);return l.default.useCallback((...e)=>t.current(...e),[t])};e.s(["useEvent",0,et],914189),e.s(["useActivePress",0,function({disabled:e=!1}={}){let t=(0,l.useRef)(null),[r,n]=(0,l.useState)(!1),o=J(),s=et(()=>{t.current=null,n(!1),o.dispose()}),a=et(e=>{if(o.dispose(),null===t.current){t.current=e.currentTarget,n(!0);{let r=Y(e.currentTarget);o.addEventListener(r,"pointerup",s,!1),o.addEventListener(r,"pointermove",e=>{if(t.current){var r,o;let s,a;n((s=e.width/2,a=e.height/2,r={top:e.clientY-a,right:e.clientX+s,bottom:e.clientY+a,left:e.clientX-s},o=t.current.getBoundingClientRect(),!(!r||!o||r.righto.right||r.bottomo.bottom)))}},!1),o.addEventListener(r,"pointercancel",s,!1)}}});return{pressed:r,pressProps:e?{}:{onPointerDown:a,onPointerUp:s,onClick:s}}}],394487)},397701,e=>{"use strict";e.s(["match",0,function e(t,r,...n){if(t in r){let e=r[t];return"function"==typeof e?e(...n):e}let o=Error(`Tried to handle "${t}" but there is no handler defined. Only defined handlers are: ${Object.keys(r).map(e=>`"${e}"`).join(", ")}.`);throw Error.captureStackTrace&&Error.captureStackTrace(o,e),o}])},652265,e=>{"use strict";let t,r,n,o,s;e.i(544508);var a=e.i(397701),i=e.i(402155);let l=["[contentEditable=true]","[tabindex]","a[href]","area[href]","button:not([disabled])","iframe","input:not([disabled])","select:not([disabled])","textarea:not([disabled])"].map(e=>`${e}:not([tabindex='-1'])`).join(","),u=["[data-autofocus]"].map(e=>`${e}:not([tabindex='-1'])`).join(",");var c=((t=c||{})[t.First=1]="First",t[t.Previous=2]="Previous",t[t.Next=4]="Next",t[t.Last=8]="Last",t[t.WrapAround=16]="WrapAround",t[t.NoScroll=32]="NoScroll",t[t.AutoFocus=64]="AutoFocus",t),d=((r=d||{})[r.Error=0]="Error",r[r.Overflow=1]="Overflow",r[r.Success=2]="Success",r[r.Underflow=3]="Underflow",r),f=((n=f||{})[n.Previous=-1]="Previous",n[n.Next=1]="Next",n);function p(e=document.body){return null==e?[]:Array.from(e.querySelectorAll(l)).sort((e,t)=>Math.sign((e.tabIndex||Number.MAX_SAFE_INTEGER)-(t.tabIndex||Number.MAX_SAFE_INTEGER)))}var m=((o=m||{})[o.Strict=0]="Strict",o[o.Loose=1]="Loose",o),b=((s=b||{})[s.Keyboard=0]="Keyboard",s[s.Mouse=1]="Mouse",s);function v(e,t=e=>e){return e.slice().sort((e,r)=>{let n=t(e),o=t(r);if(null===n||null===o)return 0;let s=n.compareDocumentPosition(o);return s&Node.DOCUMENT_POSITION_FOLLOWING?-1:s&Node.DOCUMENT_POSITION_PRECEDING?1:0})}function h(e,t,{sorted:r=!0,relativeTo:n=null,skipElements:o=[]}={}){var s,a,i;let l=Array.isArray(e)?e.length>0?e[0].ownerDocument:document:e.ownerDocument,c=Array.isArray(e)?r?v(e):e:64&t?function(e=document.body){return null==e?[]:Array.from(e.querySelectorAll(u)).sort((e,t)=>Math.sign((e.tabIndex||Number.MAX_SAFE_INTEGER)-(t.tabIndex||Number.MAX_SAFE_INTEGER)))}(e):p(e);o.length>0&&c.length>1&&(c=c.filter(e=>!o.some(t=>null!=t&&"current"in t?(null==t?void 0:t.current)===e:t===e))),n=null!=n?n:l.activeElement;let d=(()=>{if(5&t)return 1;if(10&t)return -1;throw Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last")})(),f=(()=>{if(1&t)return 0;if(2&t)return Math.max(0,c.indexOf(n))-1;if(4&t)return Math.max(0,c.indexOf(n))+1;if(8&t)return c.length-1;throw Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last")})(),m=32&t?{preventScroll:!0}:{},b=0,g=c.length,y;do{if(b>=g||b+g<=0)return 0;let e=f+b;if(16&t)e=(e+g)%g;else{if(e<0)return 3;if(e>=g)return 1}null==(y=c[e])||y.focus(m),b+=d}while(y!==l.activeElement)return 6&t&&null!=(i=null==(a=null==(s=y)?void 0:s.matches)?void 0:a.call(s,"textarea,input"))&&i&&y.select(),2}"u">typeof window&&"u">typeof document&&(document.addEventListener("keydown",e=>{e.metaKey||e.altKey||e.ctrlKey||(document.documentElement.dataset.headlessuiFocusVisible="")},!0),document.addEventListener("click",e=>{1===e.detail?delete document.documentElement.dataset.headlessuiFocusVisible:0===e.detail&&(document.documentElement.dataset.headlessuiFocusVisible="")},!0)),e.s(["Focus",0,c,"FocusResult",0,d,"FocusableMode",0,m,"focusFrom",0,function(e,t){return h(p(),t,{relativeTo:e})},"focusIn",0,h,"getFocusableElements",0,p,"isFocusableElement",0,function(e,t=0){var r;return e!==(null==(r=(0,i.getOwnerDocument)(e))?void 0:r.body)&&(0,a.match)(t,{0:()=>e.matches(l),1(){let t=e;for(;null!==t;){if(t.matches(l))return!0;t=t.parentElement}return!1}})},"sortByDomNode",0,v])},144279,294316,e=>{"use strict";var t=e.i(271645);e.s(["useResolveButtonType",0,function(e,r){return(0,t.useMemo)(()=>{var t;if(e.type)return e.type;let n=null!=(t=e.as)?t:"button";if("string"==typeof n&&"button"===n.toLowerCase()||(null==r?void 0:r.tagName)==="BUTTON"&&!r.hasAttribute("type"))return"button"},[e.type,e.as,r])}],144279);var r=e.i(914189);let n=Symbol();e.s(["optionalRef",0,function(e,t=!0){return Object.assign(e,{[n]:t})},"useSyncRefs",0,function(...e){let o=(0,t.useRef)(e);(0,t.useEffect)(()=>{o.current=e},[e]);let s=(0,r.useEvent)(e=>{for(let t of o.current)null!=t&&("function"==typeof t?t(e):t.current=e)});return e.every(e=>null==e||(null==e?void 0:e[n]))?void 0:s}],294316)},732607,e=>{"use strict";e.s(["classNames",0,function(...e){return Array.from(new Set(e.flatMap(e=>"string"==typeof e?e.split(" "):[]))).filter(Boolean).join(" ")}])},700020,e=>{"use strict";let t,r;var n=e.i(271645),o=e.i(732607),s=e.i(397701),a=((t=a||{})[t.None=0]="None",t[t.RenderStrategy=1]="RenderStrategy",t[t.Static=2]="Static",t),i=((r=i||{})[r.Unmount=0]="Unmount",r[r.Hidden=1]="Hidden",r);function l(e,t={},r,s,a){let{as:i=r,children:u,refName:p="ref",...m}=f(e,["unmount","static"]),b=void 0!==e.ref?{[p]:e.ref}:{},v="function"==typeof u?u(t):u;"className"in m&&m.className&&"function"==typeof m.className&&(m.className=m.className(t)),m["aria-labelledby"]&&m["aria-labelledby"]===m.id&&(m["aria-labelledby"]=void 0);let h={};if(t){let e=!1,r=[];for(let[n,o]of Object.entries(t))"boolean"==typeof o&&(e=!0),!0===o&&r.push(n.replace(/([A-Z])/g,e=>`-${e.toLowerCase()}`));if(e)for(let e of(h["data-headlessui-state"]=r.join(" "),r))h[`data-${e}`]=""}if(i===n.Fragment&&(Object.keys(d(m)).length>0||Object.keys(d(h)).length>0))if(!(0,n.isValidElement)(v)||Array.isArray(v)&&v.length>1){if(Object.keys(d(m)).length>0)throw Error(['Passing props on "Fragment"!',"",`The current component <${s} /> is rendering a "Fragment".`,"However we need to passthrough the following props:",Object.keys(d(m)).concat(Object.keys(d(h))).map(e=>` - ${e}`).join(` +`),"","You can apply a few solutions:",['Add an `as="..."` prop, to ensure that we render an actual element instead of a "Fragment".',"Render a single element as the child so that we can forward the props onto that element."].map(e=>` - ${e}`).join(` +`)].join(` +`))}else{var g;let e=v.props,t=null==e?void 0:e.className,r="function"==typeof t?(...e)=>(0,o.classNames)(t(...e),m.className):(0,o.classNames)(t,m.className),s=c(v.props,d(f(m,["ref"])));for(let e in h)e in s&&delete h[e];return(0,n.cloneElement)(v,Object.assign({},s,h,b,{ref:a((g=v,n.default.version.split(".")[0]>="19"?g.props.ref:g.ref),b.ref)},r?{className:r}:{}))}return(0,n.createElement)(i,Object.assign({},f(m,["ref"]),i!==n.Fragment&&b,i!==n.Fragment&&h),v)}function u(...e){return e.every(e=>null==e)?void 0:t=>{for(let r of e)null!=r&&("function"==typeof r?r(t):r.current=t)}}function c(...e){if(0===e.length)return{};if(1===e.length)return e[0];let t={},r={};for(let n of e)for(let e in n)e.startsWith("on")&&"function"==typeof n[e]?(null!=r[e]||(r[e]=[]),r[e].push(n[e])):t[e]=n[e];if(t.disabled||t["aria-disabled"])for(let e in r)/^(on(?:Click|Pointer|Mouse|Key)(?:Down|Up|Press)?)$/.test(e)&&(r[e]=[e=>{var t;return null==(t=null==e?void 0:e.preventDefault)?void 0:t.call(e)}]);for(let e in r)Object.assign(t,{[e](t,...n){for(let o of r[e]){if((t instanceof Event||(null==t?void 0:t.nativeEvent)instanceof Event)&&t.defaultPrevented)return;o(t,...n)}}});return t}function d(e){let t=Object.assign({},e);for(let e in t)void 0===t[e]&&delete t[e];return t}function f(e,t=[]){let r=Object.assign({},e);for(let e of t)e in r&&delete r[e];return r}e.s(["RenderFeatures",0,a,"RenderStrategy",0,i,"compact",0,d,"forwardRefWithAs",0,function(e){var t;return Object.assign((0,n.forwardRef)(e),{displayName:null!=(t=e.displayName)?t:e.name})},"mergeProps",0,function(...e){if(0===e.length)return{};if(1===e.length)return e[0];let t={},r={};for(let n of e)for(let e in n)e.startsWith("on")&&"function"==typeof n[e]?(null!=r[e]||(r[e]=[]),r[e].push(n[e])):t[e]=n[e];for(let e in r)Object.assign(t,{[e](...t){for(let n of r[e])null==n||n(...t)}});return t},"useRender",0,function(){let e,t,r=(e=(0,n.useRef)([]),t=(0,n.useCallback)(t=>{for(let r of e.current)null!=r&&("function"==typeof r?r(t):r.current=t)},[]),(...r)=>{if(!r.every(e=>null==e))return e.current=r,t});return(0,n.useCallback)(e=>(function({ourProps:e,theirProps:t,slot:r,defaultTag:n,features:o,visible:a=!0,name:i,mergeRefs:d}){d=null!=d?d:u;let f=c(t,e);if(a)return l(f,r,n,i,d);let p=null!=o?o:0;if(2&p){let{static:e=!1,...t}=f;if(e)return l(t,r,n,i,d)}if(1&p){let{unmount:e=!0,...t}=f;return(0,s.match)(+!e,{0:()=>null,1:()=>l({...t,hidden:!0,style:{display:"none"}},r,n,i,d)})}return l(f,r,n,i,d)})({mergeRefs:r,...e}),[r])}])},2788,e=>{"use strict";let t;var r=e.i(700020),n=((t=n||{})[t.None=1]="None",t[t.Focusable=2]="Focusable",t[t.Hidden=4]="Hidden",t);let o=(0,r.forwardRefWithAs)(function(e,t){var n;let{features:o=1,...s}=e,a={ref:t,"aria-hidden":(2&o)==2||(null!=(n=s["aria-hidden"])?n:void 0),hidden:(4&o)==4||void 0,style:{position:"fixed",top:1,left:1,width:1,height:0,padding:0,margin:-1,overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",borderWidth:"0",...(4&o)==4&&(2&o)!=2&&{display:"none"}}};return(0,r.useRender)()({ourProps:a,theirProps:s,slot:{},defaultTag:"span",name:"Hidden"})});e.s(["Hidden",0,o,"HiddenFeatures",0,n])},998348,e=>{"use strict";let t;var r=((t=r||{}).Space=" ",t.Enter="Enter",t.Escape="Escape",t.Backspace="Backspace",t.Delete="Delete",t.ArrowLeft="ArrowLeft",t.ArrowUp="ArrowUp",t.ArrowRight="ArrowRight",t.ArrowDown="ArrowDown",t.Home="Home",t.End="End",t.PageUp="PageUp",t.PageDown="PageDown",t.Tab="Tab",t);e.s(["Keys",0,r])},553521,e=>{"use strict";var t=e.i(271645),r=e.i(835696);e.s(["useIsMounted",0,function(){let e=(0,t.useRef)(!1);return(0,r.useIsoMorphicEffect)(()=>(e.current=!0,()=>{e.current=!1}),[]),e}])},751734,e=>{"use strict";let t=(0,e.i(271645).createContext)(0);e.s(["default",0,t])},144582,e=>{"use strict";let t=(0,e.i(271645).createContext)({selectedValue:void 0,handleValueChange:void 0});e.s(["default",0,t])},404206,e=>{"use strict";var t=e.i(290571),r=e.i(751734),n=e.i(144582),o=e.i(444755),s=e.i(673706),a=e.i(271645);let i=(0,s.makeClassName)("TabPanel"),l=a.default.forwardRef((e,s)=>{let{children:l,className:u}=e,c=(0,t.__rest)(e,["children","className"]),{selectedValue:d}=(0,a.useContext)(n.default),f=d===(0,a.useContext)(r.default);return a.default.createElement("div",Object.assign({ref:s,className:(0,o.tremorTwMerge)(i("root"),"w-full mt-2",f?"":"hidden",u),"aria-selected":f?"true":"false"},c),l)});l.displayName="TabPanel",e.s(["TabPanel",0,l],404206)},640497,e=>{"use strict";var t=e.i(271645),r=e.i(553521),n=e.i(2788);e.s(["FocusSentinel",0,function({onFocus:e}){let[o,s]=(0,t.useState)(!0),a=(0,r.useIsMounted)();return o?t.default.createElement(n.Hidden,{as:"button",type:"button",features:n.HiddenFeatures.Focusable,onFocus:t=>{t.preventDefault();let r,n=50;r=requestAnimationFrame(function t(){if(n--<=0){r&&cancelAnimationFrame(r);return}if(e()){if(cancelAnimationFrame(r),!a.current)return;s(!1);return}r=requestAnimationFrame(t)})}}):null}])},963703,e=>{"use strict";var t=e.i(271645);let r=t.createContext(null);e.s(["StableCollection",0,function({children:e}){let n=t.useRef({groups:new Map,get(e,t){var r;let n=this.groups.get(e);n||(n=new Map,this.groups.set(e,n));let o=null!=(r=n.get(t))?r:0;return n.set(t,o+1),[Array.from(n.keys()).indexOf(t),function(){let e=n.get(t);e>1?n.set(t,e-1):n.delete(t)}]}});return t.createElement(r.Provider,{value:n},e)},"useStableCollectionIndex",0,function(e){let n=t.useContext(r);if(!n)throw Error("You must wrap your component in a ");let o=t.useId(),[s,a]=n.current.get(e,o);return t.useEffect(()=>a,[]),s}])},970554,e=>{"use strict";let t,r,n;var o=e.i(783222),s=e.i(433336),a=e.i(271645),i=e.i(394487),l=e.i(914189),u=e.i(835696),c=e.i(941444),d=e.i(144279),f=e.i(294316),p=e.i(640497),m=e.i(2788),b=e.i(652265),v=e.i(397701),h=e.i(368578),g=e.i(402155),y=e.i(700020),E=e.i(963703),T=e.i(998348),w=((t=w||{})[t.Forwards=0]="Forwards",t[t.Backwards=1]="Backwards",t),x=((r=x||{})[r.Less=-1]="Less",r[r.Equal=0]="Equal",r[r.Greater=1]="Greater",r),F=((n=F||{})[n.SetSelectedIndex=0]="SetSelectedIndex",n[n.RegisterTab=1]="RegisterTab",n[n.UnregisterTab=2]="UnregisterTab",n[n.RegisterPanel=3]="RegisterPanel",n[n.UnregisterPanel=4]="UnregisterPanel",n);let P={0(e,t){var r;let n=(0,b.sortByDomNode)(e.tabs,e=>e.current),o=(0,b.sortByDomNode)(e.panels,e=>e.current),s=n.filter(e=>{var t;return!(null!=(t=e.current)&&t.hasAttribute("disabled"))}),a={...e,tabs:n,panels:o};if(t.index<0||t.index>n.length-1){let r=(0,v.match)(Math.sign(t.index-e.selectedIndex),{[-1]:()=>1,0:()=>(0,v.match)(Math.sign(t.index),{[-1]:()=>0,0:()=>0,1:()=>1}),1:()=>0});if(0===s.length)return a;let o=(0,v.match)(r,{0:()=>n.indexOf(s[0]),1:()=>n.indexOf(s[s.length-1])});return{...a,selectedIndex:-1===o?e.selectedIndex:o}}let i=n.slice(0,t.index),l=[...n.slice(t.index),...i].find(e=>s.includes(e));if(!l)return a;let u=null!=(r=n.indexOf(l))?r:e.selectedIndex;return -1===u&&(u=e.selectedIndex),{...a,selectedIndex:u}},1(e,t){if(e.tabs.includes(t.tab))return e;let r=e.tabs[e.selectedIndex],n=(0,b.sortByDomNode)([...e.tabs,t.tab],e=>e.current),o=e.selectedIndex;return e.info.current.isControlled||-1===(o=n.indexOf(r))&&(o=e.selectedIndex),{...e,tabs:n,selectedIndex:o}},2:(e,t)=>({...e,tabs:e.tabs.filter(e=>e!==t.tab)}),3:(e,t)=>e.panels.includes(t.panel)?e:{...e,panels:(0,b.sortByDomNode)([...e.panels,t.panel],e=>e.current)},4:(e,t)=>({...e,panels:e.panels.filter(e=>e!==t.panel)})},k=(0,a.createContext)(null);function L(e){let t=(0,a.useContext)(k);if(null===t){let t=Error(`<${e} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,L),t}return t}k.displayName="TabsDataContext";let N=(0,a.createContext)(null);function C(e){let t=(0,a.useContext)(N);if(null===t){let t=Error(`<${e} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,C),t}return t}function I(e,t){return(0,v.match)(t.type,P,e,t)}N.displayName="TabsActionsContext";let S=y.RenderFeatures.RenderStrategy|y.RenderFeatures.Static,A=Object.assign((0,y.forwardRefWithAs)(function(e,t){var r,n;let c=(0,a.useId)(),{id:p=`headlessui-tabs-tab-${c}`,disabled:m=!1,autoFocus:w=!1,...x}=e,{orientation:F,activation:P,selectedIndex:k,tabs:N,panels:I}=L("Tab"),S=C("Tab"),A=L("Tab"),[M,R]=(0,a.useState)(null),O=(0,a.useRef)(null),D=(0,f.useSyncRefs)(O,t,R);(0,u.useIsoMorphicEffect)(()=>S.registerTab(O),[S,O]);let H=(0,E.useStableCollectionIndex)("tabs"),j=N.indexOf(O);-1===j&&(j=H);let K=j===k,W=(0,l.useEvent)(e=>{var t;let r=e();if(r===b.FocusResult.Success&&"auto"===P){let e=null==(t=(0,g.getOwnerDocument)(O))?void 0:t.activeElement,r=A.tabs.findIndex(t=>t.current===e);-1!==r&&S.change(r)}return r}),B=(0,l.useEvent)(e=>{let t=N.map(e=>e.current).filter(Boolean);if(e.key===T.Keys.Space||e.key===T.Keys.Enter){e.preventDefault(),e.stopPropagation(),S.change(j);return}switch(e.key){case T.Keys.Home:case T.Keys.PageUp:return e.preventDefault(),e.stopPropagation(),W(()=>(0,b.focusIn)(t,b.Focus.First));case T.Keys.End:case T.Keys.PageDown:return e.preventDefault(),e.stopPropagation(),W(()=>(0,b.focusIn)(t,b.Focus.Last))}if(W(()=>(0,v.match)(F,{vertical:()=>e.key===T.Keys.ArrowUp?(0,b.focusIn)(t,b.Focus.Previous|b.Focus.WrapAround):e.key===T.Keys.ArrowDown?(0,b.focusIn)(t,b.Focus.Next|b.Focus.WrapAround):b.FocusResult.Error,horizontal:()=>e.key===T.Keys.ArrowLeft?(0,b.focusIn)(t,b.Focus.Previous|b.Focus.WrapAround):e.key===T.Keys.ArrowRight?(0,b.focusIn)(t,b.Focus.Next|b.Focus.WrapAround):b.FocusResult.Error}))===b.FocusResult.Success)return e.preventDefault()}),V=(0,a.useRef)(!1),_=(0,l.useEvent)(()=>{var e;V.current||(V.current=!0,null==(e=O.current)||e.focus({preventScroll:!0}),S.change(j),(0,h.microTask)(()=>{V.current=!1}))}),G=(0,l.useEvent)(e=>{e.preventDefault()}),{isFocusVisible:U,focusProps:$}=(0,o.useFocusRing)({autoFocus:w}),{isHovered:q,hoverProps:X}=(0,s.useHover)({isDisabled:m}),{pressed:Y,pressProps:z}=(0,i.useActivePress)({disabled:m}),Z=(0,a.useMemo)(()=>({selected:K,hover:q,active:Y,focus:U,autofocus:w,disabled:m}),[K,q,U,Y,w,m]),J=(0,y.mergeProps)({ref:D,onKeyDown:B,onMouseDown:G,onClick:_,id:p,role:"tab",type:(0,d.useResolveButtonType)(e,M),"aria-controls":null==(n=null==(r=I[j])?void 0:r.current)?void 0:n.id,"aria-selected":K,tabIndex:K?0:-1,disabled:m||void 0,autoFocus:w},$,X,z);return(0,y.useRender)()({ourProps:J,theirProps:x,slot:Z,defaultTag:"button",name:"Tabs.Tab"})}),{Group:(0,y.forwardRefWithAs)(function(e,t){let{defaultIndex:r=0,vertical:n=!1,manual:o=!1,onChange:s,selectedIndex:i=null,...d}=e,m=n?"vertical":"horizontal",v=o?"manual":"auto",h=null!==i,g=(0,c.useLatestValue)({isControlled:h}),T=(0,f.useSyncRefs)(t),[w,x]=(0,a.useReducer)(I,{info:g,selectedIndex:null!=i?i:r,tabs:[],panels:[]}),F=(0,a.useMemo)(()=>({selectedIndex:w.selectedIndex}),[w.selectedIndex]),P=(0,c.useLatestValue)(s||(()=>{})),L=(0,c.useLatestValue)(w.tabs),C=(0,a.useMemo)(()=>({orientation:m,activation:v,...w}),[m,v,w]),S=(0,l.useEvent)(e=>(x({type:1,tab:e}),()=>x({type:2,tab:e}))),A=(0,l.useEvent)(e=>(x({type:3,panel:e}),()=>x({type:4,panel:e}))),M=(0,l.useEvent)(e=>{R.current!==e&&P.current(e),h||x({type:0,index:e})}),R=(0,c.useLatestValue)(h?e.selectedIndex:w.selectedIndex),O=(0,a.useMemo)(()=>({registerTab:S,registerPanel:A,change:M}),[]);(0,u.useIsoMorphicEffect)(()=>{x({type:0,index:null!=i?i:r})},[i]),(0,u.useIsoMorphicEffect)(()=>{if(void 0===R.current||w.tabs.length<=0)return;let e=(0,b.sortByDomNode)(w.tabs,e=>e.current);e.some((e,t)=>w.tabs[t]!==e)&&M(e.indexOf(w.tabs[R.current]))});let D=(0,y.useRender)();return a.default.createElement(E.StableCollection,null,a.default.createElement(N.Provider,{value:O},a.default.createElement(k.Provider,{value:C},C.tabs.length<=0&&a.default.createElement(p.FocusSentinel,{onFocus:()=>{var e,t;for(let r of L.current)if((null==(e=r.current)?void 0:e.tabIndex)===0)return null==(t=r.current)||t.focus(),!0;return!1}}),D({ourProps:{ref:T},theirProps:d,slot:F,defaultTag:"div",name:"Tabs"}))))}),List:(0,y.forwardRefWithAs)(function(e,t){let{orientation:r,selectedIndex:n}=L("Tab.List"),o=(0,f.useSyncRefs)(t),s=(0,a.useMemo)(()=>({selectedIndex:n}),[n]);return(0,y.useRender)()({ourProps:{ref:o,role:"tablist","aria-orientation":r},theirProps:e,slot:s,defaultTag:"div",name:"Tabs.List"})}),Panels:(0,y.forwardRefWithAs)(function(e,t){let{selectedIndex:r}=L("Tab.Panels"),n=(0,f.useSyncRefs)(t),o=(0,a.useMemo)(()=>({selectedIndex:r}),[r]);return(0,y.useRender)()({ourProps:{ref:n},theirProps:e,slot:o,defaultTag:"div",name:"Tabs.Panels"})}),Panel:(0,y.forwardRefWithAs)(function(e,t){var r,n,s,i;let l=(0,a.useId)(),{id:c=`headlessui-tabs-panel-${l}`,tabIndex:d=0,...p}=e,{selectedIndex:b,tabs:v,panels:h}=L("Tab.Panel"),g=C("Tab.Panel"),T=(0,a.useRef)(null),w=(0,f.useSyncRefs)(T,t);(0,u.useIsoMorphicEffect)(()=>g.registerPanel(T),[g,T]);let x=(0,E.useStableCollectionIndex)("panels"),F=h.indexOf(T);-1===F&&(F=x);let P=F===b,{isFocusVisible:k,focusProps:N}=(0,o.useFocusRing)(),I=(0,a.useMemo)(()=>({selected:P,focus:k}),[P,k]),A=(0,y.mergeProps)({ref:w,id:c,role:"tabpanel","aria-labelledby":null==(n=null==(r=v[F])?void 0:r.current)?void 0:n.id,tabIndex:P?d:-1},N),M=(0,y.useRender)();return P||null!=(s=p.unmount)&&!s||null!=(i=p.static)&&i?M({ourProps:A,theirProps:p,slot:I,defaultTag:"div",features:S,visible:P,name:"Tabs.Panel"}):a.default.createElement(m.Hidden,{"aria-hidden":"true",...A})})});e.s(["Tab",0,A])},723731,e=>{"use strict";var t=e.i(290571),r=e.i(970554),n=e.i(751734),o=e.i(144582),s=e.i(444755),a=e.i(673706),i=e.i(271645);let l=(0,a.makeClassName)("TabPanels"),u=i.default.forwardRef((e,a)=>{let{children:u,className:c}=e,d=(0,t.__rest)(e,["children","className"]);return i.default.createElement(r.Tab.Panels,Object.assign({as:"div",ref:a,className:(0,s.tremorTwMerge)(l("root"),"w-full",c)},d),({selectedIndex:e})=>i.default.createElement(o.default.Provider,{value:{selectedValue:e}},i.default.Children.map(u,(e,t)=>i.default.createElement(n.default.Provider,{value:t},e))))});u.displayName="TabPanels",e.s(["TabPanels",0,u],723731)},653824,e=>{"use strict";var t=e.i(290571),r=e.i(970554),n=e.i(444755),o=e.i(673706),s=e.i(271645);let a=(0,o.makeClassName)("TabGroup"),i=s.default.forwardRef((e,o)=>{let{defaultIndex:i,index:l,onIndexChange:u,children:c,className:d}=e,f=(0,t.__rest)(e,["defaultIndex","index","onIndexChange","children","className"]);return s.default.createElement(r.Tab.Group,Object.assign({as:"div",ref:o,defaultIndex:i,selectedIndex:l,onChange:u,className:(0,n.tremorTwMerge)(a("root"),"w-full",d)},f),c)});i.displayName="TabGroup",e.s(["TabGroup",0,i],653824)},405371,910342,e=>{"use strict";var t=e.i(290571),r=e.i(271645),n=e.i(480731);let o=(0,r.createContext)(n.BaseColors.Blue);e.s(["default",0,o],910342);var s=e.i(970554),a=e.i(444755);let i=(0,e.i(673706).makeClassName)("TabList"),l=(0,r.createContext)("line"),u={line:(0,a.tremorTwMerge)("flex border-b space-x-4","border-tremor-border","dark:border-dark-tremor-border"),solid:(0,a.tremorTwMerge)("inline-flex p-0.5 rounded-tremor-default space-x-1.5","bg-tremor-background-subtle","dark:bg-dark-tremor-background-subtle")},c=r.default.forwardRef((e,n)=>{let{color:c,variant:d="line",children:f,className:p}=e,m=(0,t.__rest)(e,["color","variant","children","className"]);return r.default.createElement(s.Tab.List,Object.assign({ref:n,className:(0,a.tremorTwMerge)(i("root"),"justify-start overflow-x-clip",u[d],p)},m),r.default.createElement(l.Provider,{value:d},r.default.createElement(o.Provider,{value:c},f)))});c.displayName="TabList",e.s(["TabVariantContext",0,l,"default",0,c],405371)},881073,e=>{"use strict";var t=e.i(405371);e.s(["TabList",()=>t.default])},197647,e=>{"use strict";var t=e.i(290571),r=e.i(970554),n=e.i(95779),o=e.i(444755),s=e.i(673706),a=e.i(271645),i=e.i(405371),l=e.i(910342);let u=(0,s.makeClassName)("Tab"),c=a.default.forwardRef((e,c)=>{let{icon:d,className:f,children:p}=e,m=(0,t.__rest)(e,["icon","className","children"]),b=(0,a.useContext)(i.TabVariantContext),v=(0,a.useContext)(l.default);return a.default.createElement(r.Tab,Object.assign({ref:c,className:(0,o.tremorTwMerge)(u("root"),"flex whitespace-nowrap truncate max-w-xs outline-none data-focus-visible:ring text-tremor-default transition duration-100",function(e,t){switch(e){case"line":return(0,o.tremorTwMerge)("data-[selected]:border-b-2 hover:border-b-2 border-transparent transition duration-100 -mb-px px-2 py-2","hover:border-tremor-content hover:text-tremor-content-emphasis text-tremor-content","[&:not([data-selected])]:dark:hover:border-dark-tremor-content-emphasis [&:not([data-selected])]:dark:hover:text-dark-tremor-content-emphasis [&:not([data-selected])]:dark:text-dark-tremor-content",t?(0,s.getColorClassNames)(t,n.colorPalette.border).selectBorderColor:["data-[selected]:border-tremor-brand data-[selected]:text-tremor-brand","data-[selected]:dark:border-dark-tremor-brand data-[selected]:dark:text-dark-tremor-brand"]);case"solid":return(0,o.tremorTwMerge)("border-transparent border rounded-tremor-small px-2.5 py-1","data-[selected]:border-tremor-border data-[selected]:bg-tremor-background data-[selected]:shadow-tremor-input [&:not([data-selected])]:hover:text-tremor-content-emphasis data-[selected]:text-tremor-brand [&:not([data-selected])]:text-tremor-content","dark:data-[selected]:border-dark-tremor-border dark:data-[selected]:bg-dark-tremor-background dark:data-[selected]:shadow-dark-tremor-input dark:[&:not([data-selected])]:hover:text-dark-tremor-content-emphasis dark:data-[selected]:text-dark-tremor-brand dark:[&:not([data-selected])]:text-dark-tremor-content",t?(0,s.getColorClassNames)(t,n.colorPalette.text).selectTextColor:"text-tremor-content dark:text-dark-tremor-content")}}(b,v),f,v&&(0,s.getColorClassNames)(v,n.colorPalette.text).selectTextColor)},m),d?a.default.createElement(d,{className:(0,o.tremorTwMerge)(u("icon"),"flex-none h-5 w-5",p?"mr-2":"")}):null,p?a.default.createElement("span",null,p):null)});c.displayName="Tab",e.s(["Tab",0,c],197647)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/022.sz94ycw4x.js b/litellm/proxy/_experimental/out/_next/static/chunks/022.sz94ycw4x.js new file mode 100644 index 00000000000..746b869a2c6 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/022.sz94ycw4x.js @@ -0,0 +1,4 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,751734,e=>{"use strict";let t=(0,e.i(271645).createContext)(0);e.s(["default",0,t])},144582,e=>{"use strict";let t=(0,e.i(271645).createContext)({selectedValue:void 0,handleValueChange:void 0});e.s(["default",0,t])},404206,e=>{"use strict";var t=e.i(290571),r=e.i(751734),n=e.i(144582),o=e.i(444755),s=e.i(673706),a=e.i(271645);let i=(0,s.makeClassName)("TabPanel"),l=a.default.forwardRef((e,s)=>{let{children:l,className:u}=e,c=(0,t.__rest)(e,["children","className"]),{selectedValue:d}=(0,a.useContext)(n.default),f=d===(0,a.useContext)(r.default);return a.default.createElement("div",Object.assign({ref:s,className:(0,o.tremorTwMerge)(i("root"),"w-full mt-2",f?"":"hidden",u),"aria-selected":f?"true":"false"},c),l)});l.displayName="TabPanel",e.s(["TabPanel",0,l],404206)},783222,433336,80758,402155,368578,544508,746725,835696,941444,914189,394487,e=>{"use strict";let t;e.i(247167);let r=e=>e?.ownerDocument??document,n=e=>e&&"window"in e&&e.window===e?e:r(e).defaultView||window;function o(e,t){return!!t&&!!e&&e.contains(t)}function s(e){return e.target}let a=null;"u">typeof Element&&Element.prototype;let i=["input:not([disabled]):not([type=hidden])","select:not([disabled])","textarea:not([disabled])","button:not([disabled])","a[href]","area[href]","summary","iframe","object","embed","audio[controls]","video[controls]",'[contenteditable]:not([contenteditable^="false"])',"permission"];i.join(":not([hidden]),"),i.push('[tabindex]:not([tabindex="-1"]):not([disabled])'),i.join(':not([hidden]):not([tabindex="-1"]),');var l=e.i(271645);let u="u">typeof document?l.default.useLayoutEffect:()=>{};function c(e){return e.nativeEvent=e,e.isDefaultPrevented=()=>e.defaultPrevented,e.isPropagationStopped=()=>e.cancelBubble,e.persist=()=>{},e}function d(e){let t=(0,l.useRef)({isFocused:!1,observer:null});return u(()=>{let e=t.current;return()=>{e.observer&&(e.observer.disconnect(),e.observer=null)}},[]),(0,l.useCallback)(r=>{let n=s(r);(n instanceof HTMLButtonElement||n instanceof HTMLInputElement||n instanceof HTMLTextAreaElement||n instanceof HTMLSelectElement)&&(t.current.isFocused=!0,n.addEventListener("focusout",r=>{if(t.current.isFocused=!1,n.disabled){let t=c(r);e?.(t)}t.current.observer&&(t.current.observer.disconnect(),t.current.observer=null)},{once:!0}),t.current.observer=new MutationObserver(()=>{if(t.current.isFocused&&n.disabled){t.current.observer?.disconnect();let e=n===((e=document)=>e.activeElement)()?null:((e=document)=>e.activeElement)();n.dispatchEvent(new FocusEvent("blur",{relatedTarget:e})),n.dispatchEvent(new FocusEvent("focusout",{bubbles:!0,relatedTarget:e}))}}),t.current.observer.observe(n,{attributes:!0,attributeFilter:["disabled"]}))},[e])}function f(e){if("u"e.test(t.brand))||e.test(window.navigator.userAgent)}function p(e){return"u">typeof window&&null!=window.navigator&&e.test(window.navigator.userAgentData?.platform||window.navigator.platform)}function m(e){let t=null;return()=>(null==t&&(t=e()),t)}let b=m(function(){return p(/^Mac/i)}),v=m(function(){return p(/^iPhone/i)}),h=m(function(){return p(/^iPad/i)||b()&&navigator.maxTouchPoints>1}),g=m(function(){return v()||h()});m(function(){return b()||g()});let y=m(function(){return f(/AppleWebKit/i)&&!E()}),E=m(function(){return f(/Chrome/i)}),T=m(function(){return f(/Android/i)}),w=m(function(){return f(/Firefox/i)});function x(e,t,r=!0){let{metaKey:n,ctrlKey:o,altKey:s,shiftKey:i}=t;w()&&window.event?.type?.startsWith("key")&&"_blank"===e.target&&(b()?n=!0:o=!0);let l=y()&&b()&&!h()&&1?new KeyboardEvent("keydown",{keyIdentifier:"Enter",metaKey:n,ctrlKey:o,altKey:s,shiftKey:i}):new MouseEvent("click",{metaKey:n,ctrlKey:o,altKey:s,shiftKey:i,detail:1,bubbles:!0,cancelable:!0});x.isOpening=r;if(function(){if(null==a){a=!1;try{document.createElement("div").focus({get preventScroll(){return a=!0,!0}})}catch{}}return a}())e.focus({preventScroll:!0});else{let t=function(e){let t=e.parentNode,r=[],n=document.scrollingElement||document.documentElement;for(;t instanceof HTMLElement&&t!==n;)(t.offsetHeighttypeof window&&window.document&&window.document.createElement,new WeakMap;l.default.useId;let P=null,k=new Set,L=new Map,N=!1,C=!1,I={Tab:!0,Escape:!0};function S(e,t){for(let r of k)r(e,t)}function A(e){N=!0,x.isOpening||e.metaKey||!b()&&e.altKey||e.ctrlKey||"Control"===e.key||"Shift"===e.key||"Meta"===e.key||(P="keyboard",S("keyboard",e))}function M(e){P="pointer","pointerType"in e&&e.pointerType,("mousedown"===e.type||"pointerdown"===e.type)&&(N=!0,S("pointer",e))}function R(e){x.isOpening||(""!==e.pointerType||!e.isTrusted)&&(T()&&e.pointerType?"click"!==e.type||1!==e.buttons:0!==e.detail||e.pointerType)||(N=!0,P="virtual")}function O(e){let t=n(s(e)),o=r(s(e));s(e)!==t&&s(e)!==o&&e.isTrusted&&(N||C||(P="virtual",S("virtual",e)),N=!1,C=!1)}function D(){N=!1,C=!0}function H(e){if("u"typeof PointerEvent&&(o.addEventListener("pointerdown",M,!0),o.addEventListener("pointermove",M,!0),o.addEventListener("pointerup",M,!0)),t.addEventListener("beforeunload",()=>{j(e)},{once:!0}),L.set(t,{focus:s})}let j=(e,t)=>{let o=n(e),s=r(e);t&&s.removeEventListener("DOMContentLoaded",t),L.has(o)&&(o.HTMLElement.prototype.focus=L.get(o).focus,s.removeEventListener("keydown",A,!0),s.removeEventListener("keyup",A,!0),s.removeEventListener("click",R,!0),o.removeEventListener("focus",O,!0),o.removeEventListener("blur",D,!1),"u">typeof PointerEvent&&(s.removeEventListener("pointerdown",M,!0),s.removeEventListener("pointermove",M,!0),s.removeEventListener("pointerup",M,!0)),L.delete(o))};function K(){return"pointer"!==P}"u">typeof document&&("loading"!==(t=r(void 0)).readyState?H(void 0):t.addEventListener("DOMContentLoaded",()=>{H(void 0)}));let W=new Set(["checkbox","radio","range","color","file","image","button","submit","reset"]);function B(){let e=(0,l.useRef)(new Map),t=(0,l.useCallback)((t,r,n,o)=>{let s=o?.once?(...t)=>{e.current.delete(n),n(...t)}:n;e.current.set(n,{type:r,eventTarget:t,fn:s,options:o}),t.addEventListener(r,s,o)},[]),r=(0,l.useCallback)((t,r,n,o)=>{let s=e.current.get(n)?.fn||n;t.removeEventListener(r,s,o),e.current.delete(n)},[]),n=(0,l.useCallback)(()=>{e.current.forEach((e,t)=>{r(e.eventTarget,e.type,t,e.options)})},[r]);return(0,l.useEffect)(()=>n,[n]),{addGlobalListener:t,removeGlobalListener:r,removeAllGlobalListeners:n}}e.s(["useFocusRing",0,function(e={}){var t;let{autoFocus:a=!1,isTextInput:i,within:u}=e,f=(0,l.useRef)({isFocused:!1,isFocusVisible:a||K()}),[p,m]=(0,l.useState)(!1),[b,v]=(0,l.useState)(()=>f.current.isFocused&&f.current.isFocusVisible),h=(0,l.useCallback)(()=>v(f.current.isFocused&&f.current.isFocusVisible),[]),g=(0,l.useCallback)(e=>{f.current.isFocused=e,f.current.isFocusVisible=K(),m(e),h()},[h]);t={enabled:p,isTextInput:i},H(),(0,l.useEffect)(()=>{if(t?.enabled===!1)return;let e=(e,o)=>{var a;let i,l,u,c,d,p,m,b;a=!!t?.isTextInput,l=r(i=o?s(o):void 0),c=void 0!==(u=n(i))?u.HTMLInputElement:HTMLInputElement,d=void 0!==u?u.HTMLTextAreaElement:HTMLTextAreaElement,p=void 0!==u?u.HTMLElement:HTMLElement,m=void 0!==u?u.KeyboardEvent:KeyboardEvent,b=((e=document)=>e.activeElement)(l),(a=a||b instanceof c&&!W.has(b.type)||b instanceof d||b instanceof p&&b.isContentEditable)&&"keyboard"===e&&o instanceof m&&!I[o.key]||(e=>{f.current.isFocusVisible=e,h()})(K())};return k.add(e),()=>{k.delete(e)}},[i,p]);let{focusProps:y}=function(e){let{isDisabled:t,onFocus:n,onBlur:o,onFocusChange:a}=e,i=(0,l.useCallback)(e=>{if(s(e)===e.currentTarget)return o&&o(e),a&&a(!1),!0},[o,a]),u=d(i),c=(0,l.useCallback)(e=>{let t=s(e),o=r(t),i=o?((e=document)=>e.activeElement)(o):((e=document)=>e.activeElement)();t===e.currentTarget&&t===i&&(n&&n(e),a&&a(!0),u(e))},[a,n,u]);return{focusProps:{onFocus:!t&&(n||a||o)?c:void 0,onBlur:!t&&(o||a)?i:void 0}}}({isDisabled:u,onFocusChange:g}),{focusWithinProps:E}=function(e){let{isDisabled:t,onBlurWithin:n,onFocusWithin:a,onFocusWithinChange:i}=e,u=(0,l.useRef)({isFocusWithin:!1}),{addGlobalListener:f,removeAllGlobalListeners:p}=B(),m=(0,l.useCallback)(e=>{o(e.currentTarget,s(e))&&u.current.isFocusWithin&&!o(e.currentTarget,e.relatedTarget)&&(u.current.isFocusWithin=!1,p(),n&&n(e),i&&i(!1))},[n,i,u,p]),b=d(m),v=(0,l.useCallback)(e=>{if(!o(e.currentTarget,s(e)))return;let t=s(e),n=r(t),l=((e=document)=>e.activeElement)(n);if(!u.current.isFocusWithin&&l===t){a&&a(e),i&&i(!0),u.current.isFocusWithin=!0,b(e);let t=e.currentTarget;f(n,"focus",e=>{let r=s(e);if(u.current.isFocusWithin&&!o(t,r)){let e=new n.defaultView.FocusEvent("blur",{relatedTarget:r});Object.defineProperty(e,"target",{value:t}),Object.defineProperty(e,"currentTarget",{value:t}),m(c(e))}},{capture:!0})}},[a,i,b,f,m]);return t?{focusWithinProps:{onFocus:void 0,onBlur:void 0}}:{focusWithinProps:{onFocus:v,onBlur:m}}}({isDisabled:!u,onFocusWithinChange:g});return{isFocused:p,isFocusVisible:b,focusProps:u?E:y}}],783222);let V=!1,_=0;function G(e){"touch"===e.pointerType&&(V=!0,setTimeout(()=>{V=!1},500))}function U(){let e=r(null);if(void 0!==e)return 0===_&&"u">typeof PointerEvent&&e.addEventListener("pointerup",G),_++,()=>{!(--_>0)&&"u">typeof PointerEvent&&e.removeEventListener("pointerup",G)}}e.s(["useHover",0,function(e){let{onHoverStart:t,onHoverChange:n,onHoverEnd:a,isDisabled:i}=e,[u,c]=(0,l.useState)(!1),d=(0,l.useRef)({isHovered:!1,ignoreEmulatedMouseEvents:!1,pointerType:"",target:null}).current;(0,l.useEffect)(U,[]);let{addGlobalListener:f,removeAllGlobalListeners:p}=B(),{hoverProps:m,triggerHoverEnd:b}=(0,l.useMemo)(()=>{let e=(e,t)=>{let r=d.target;d.pointerType="",d.target=null,"touch"!==t&&d.isHovered&&r&&(d.isHovered=!1,p(),a&&a({type:"hoverend",target:r,pointerType:t}),n&&n(!1),c(!1))},l={};return"u">typeof PointerEvent&&(l.onPointerEnter=a=>{V&&"mouse"===a.pointerType||((a,l)=>{if(d.pointerType=l,i||"touch"===l||d.isHovered||!o(a.currentTarget,s(a)))return;d.isHovered=!0;let u=a.currentTarget;d.target=u,f(r(s(a)),"pointerover",t=>{d.isHovered&&d.target&&!o(d.target,s(t))&&e(t,t.pointerType)},{capture:!0}),t&&t({type:"hoverstart",target:u,pointerType:l}),n&&n(!0),c(!0)})(a,a.pointerType)},l.onPointerLeave=t=>{!i&&o(t.currentTarget,s(t))&&e(t,t.pointerType)}),{hoverProps:l,triggerHoverEnd:e}},[t,n,a,i,d,f,p]);return(0,l.useEffect)(()=>{i&&b({currentTarget:d.target},d.pointerType)},[i]),{hoverProps:m,isHovered:u}}],433336);var $=Object.defineProperty,q=(e,t,r)=>{let n;return(n="symbol"!=typeof t?t+"":t)in e?$(e,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[n]=r,r};let X=new class{constructor(){q(this,"current",this.detect()),q(this,"handoffState","pending"),q(this,"currentId",0)}set(e){this.current!==e&&(this.handoffState="pending",this.currentId=0,this.current=e)}reset(){this.set(this.detect())}nextId(){return++this.currentId}get isServer(){return"server"===this.current}get isClient(){return"client"===this.current}detect(){return"u"setTimeout(()=>{throw e}))}function Z(){let e=[],t={addEventListener:(e,r,n,o)=>(e.addEventListener(r,n,o),t.add(()=>e.removeEventListener(r,n,o))),requestAnimationFrame(...e){let r=requestAnimationFrame(...e);return t.add(()=>cancelAnimationFrame(r))},nextFrame:(...e)=>t.requestAnimationFrame(()=>t.requestAnimationFrame(...e)),setTimeout(...e){let r=setTimeout(...e);return t.add(()=>clearTimeout(r))},microTask(...e){let r={current:!0};return z(()=>{r.current&&e[0]()}),t.add(()=>{r.current=!1})},style(e,t,r){let n=e.style.getPropertyValue(t);return Object.assign(e.style,{[t]:r}),this.add(()=>{Object.assign(e.style,{[t]:n})})},group(e){let t=Z();return e(t),this.add(()=>t.dispose())},add:t=>(e.includes(t)||e.push(t),()=>{let r=e.indexOf(t);if(r>=0)for(let t of e.splice(r,1))t()}),dispose(){for(let t of e.splice(0))t()}};return t}function J(){let[e]=(0,l.useState)(Z);return(0,l.useEffect)(()=>()=>e.dispose(),[e]),e}e.s(["env",0,X],80758),e.s(["getOwnerDocument",0,Y],402155),e.s(["microTask",0,z],368578),e.s(["disposables",0,Z],544508),e.s(["useDisposables",0,J],746725);let Q=(e,t)=>{X.isServer?(0,l.useEffect)(e,t):(0,l.useLayoutEffect)(e,t)};function ee(e){let t=(0,l.useRef)(e);return Q(()=>{t.current=e},[e]),t}e.s(["useIsoMorphicEffect",0,Q],835696),e.s(["useLatestValue",0,ee],941444);let et=function(e){let t=ee(e);return l.default.useCallback((...e)=>t.current(...e),[t])};e.s(["useEvent",0,et],914189),e.s(["useActivePress",0,function({disabled:e=!1}={}){let t=(0,l.useRef)(null),[r,n]=(0,l.useState)(!1),o=J(),s=et(()=>{t.current=null,n(!1),o.dispose()}),a=et(e=>{if(o.dispose(),null===t.current){t.current=e.currentTarget,n(!0);{let r=Y(e.currentTarget);o.addEventListener(r,"pointerup",s,!1),o.addEventListener(r,"pointermove",e=>{if(t.current){var r,o;let s,a;n((s=e.width/2,a=e.height/2,r={top:e.clientY-a,right:e.clientX+s,bottom:e.clientY+a,left:e.clientX-s},o=t.current.getBoundingClientRect(),!(!r||!o||r.righto.right||r.bottomo.bottom)))}},!1),o.addEventListener(r,"pointercancel",s,!1)}}});return{pressed:r,pressProps:e?{}:{onPointerDown:a,onPointerUp:s,onClick:s}}}],394487)},397701,e=>{"use strict";e.s(["match",0,function e(t,r,...n){if(t in r){let e=r[t];return"function"==typeof e?e(...n):e}let o=Error(`Tried to handle "${t}" but there is no handler defined. Only defined handlers are: ${Object.keys(r).map(e=>`"${e}"`).join(", ")}.`);throw Error.captureStackTrace&&Error.captureStackTrace(o,e),o}])},652265,e=>{"use strict";let t,r,n,o,s;e.i(544508);var a=e.i(397701),i=e.i(402155);let l=["[contentEditable=true]","[tabindex]","a[href]","area[href]","button:not([disabled])","iframe","input:not([disabled])","select:not([disabled])","textarea:not([disabled])"].map(e=>`${e}:not([tabindex='-1'])`).join(","),u=["[data-autofocus]"].map(e=>`${e}:not([tabindex='-1'])`).join(",");var c=((t=c||{})[t.First=1]="First",t[t.Previous=2]="Previous",t[t.Next=4]="Next",t[t.Last=8]="Last",t[t.WrapAround=16]="WrapAround",t[t.NoScroll=32]="NoScroll",t[t.AutoFocus=64]="AutoFocus",t),d=((r=d||{})[r.Error=0]="Error",r[r.Overflow=1]="Overflow",r[r.Success=2]="Success",r[r.Underflow=3]="Underflow",r),f=((n=f||{})[n.Previous=-1]="Previous",n[n.Next=1]="Next",n);function p(e=document.body){return null==e?[]:Array.from(e.querySelectorAll(l)).sort((e,t)=>Math.sign((e.tabIndex||Number.MAX_SAFE_INTEGER)-(t.tabIndex||Number.MAX_SAFE_INTEGER)))}var m=((o=m||{})[o.Strict=0]="Strict",o[o.Loose=1]="Loose",o),b=((s=b||{})[s.Keyboard=0]="Keyboard",s[s.Mouse=1]="Mouse",s);function v(e,t=e=>e){return e.slice().sort((e,r)=>{let n=t(e),o=t(r);if(null===n||null===o)return 0;let s=n.compareDocumentPosition(o);return s&Node.DOCUMENT_POSITION_FOLLOWING?-1:s&Node.DOCUMENT_POSITION_PRECEDING?1:0})}function h(e,t,{sorted:r=!0,relativeTo:n=null,skipElements:o=[]}={}){var s,a,i;let l=Array.isArray(e)?e.length>0?e[0].ownerDocument:document:e.ownerDocument,c=Array.isArray(e)?r?v(e):e:64&t?function(e=document.body){return null==e?[]:Array.from(e.querySelectorAll(u)).sort((e,t)=>Math.sign((e.tabIndex||Number.MAX_SAFE_INTEGER)-(t.tabIndex||Number.MAX_SAFE_INTEGER)))}(e):p(e);o.length>0&&c.length>1&&(c=c.filter(e=>!o.some(t=>null!=t&&"current"in t?(null==t?void 0:t.current)===e:t===e))),n=null!=n?n:l.activeElement;let d=(()=>{if(5&t)return 1;if(10&t)return -1;throw Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last")})(),f=(()=>{if(1&t)return 0;if(2&t)return Math.max(0,c.indexOf(n))-1;if(4&t)return Math.max(0,c.indexOf(n))+1;if(8&t)return c.length-1;throw Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last")})(),m=32&t?{preventScroll:!0}:{},b=0,g=c.length,y;do{if(b>=g||b+g<=0)return 0;let e=f+b;if(16&t)e=(e+g)%g;else{if(e<0)return 3;if(e>=g)return 1}null==(y=c[e])||y.focus(m),b+=d}while(y!==l.activeElement)return 6&t&&null!=(i=null==(a=null==(s=y)?void 0:s.matches)?void 0:a.call(s,"textarea,input"))&&i&&y.select(),2}"u">typeof window&&"u">typeof document&&(document.addEventListener("keydown",e=>{e.metaKey||e.altKey||e.ctrlKey||(document.documentElement.dataset.headlessuiFocusVisible="")},!0),document.addEventListener("click",e=>{1===e.detail?delete document.documentElement.dataset.headlessuiFocusVisible:0===e.detail&&(document.documentElement.dataset.headlessuiFocusVisible="")},!0)),e.s(["Focus",0,c,"FocusResult",0,d,"FocusableMode",0,m,"focusFrom",0,function(e,t){return h(p(),t,{relativeTo:e})},"focusIn",0,h,"getFocusableElements",0,p,"isFocusableElement",0,function(e,t=0){var r;return e!==(null==(r=(0,i.getOwnerDocument)(e))?void 0:r.body)&&(0,a.match)(t,{0:()=>e.matches(l),1(){let t=e;for(;null!==t;){if(t.matches(l))return!0;t=t.parentElement}return!1}})},"sortByDomNode",0,v])},144279,294316,e=>{"use strict";var t=e.i(271645);e.s(["useResolveButtonType",0,function(e,r){return(0,t.useMemo)(()=>{var t;if(e.type)return e.type;let n=null!=(t=e.as)?t:"button";if("string"==typeof n&&"button"===n.toLowerCase()||(null==r?void 0:r.tagName)==="BUTTON"&&!r.hasAttribute("type"))return"button"},[e.type,e.as,r])}],144279);var r=e.i(914189);let n=Symbol();e.s(["optionalRef",0,function(e,t=!0){return Object.assign(e,{[n]:t})},"useSyncRefs",0,function(...e){let o=(0,t.useRef)(e);(0,t.useEffect)(()=>{o.current=e},[e]);let s=(0,r.useEvent)(e=>{for(let t of o.current)null!=t&&("function"==typeof t?t(e):t.current=e)});return e.every(e=>null==e||(null==e?void 0:e[n]))?void 0:s}],294316)},732607,e=>{"use strict";e.s(["classNames",0,function(...e){return Array.from(new Set(e.flatMap(e=>"string"==typeof e?e.split(" "):[]))).filter(Boolean).join(" ")}])},700020,e=>{"use strict";let t,r;var n=e.i(271645),o=e.i(732607),s=e.i(397701),a=((t=a||{})[t.None=0]="None",t[t.RenderStrategy=1]="RenderStrategy",t[t.Static=2]="Static",t),i=((r=i||{})[r.Unmount=0]="Unmount",r[r.Hidden=1]="Hidden",r);function l(e,t={},r,s,a){let{as:i=r,children:u,refName:p="ref",...m}=f(e,["unmount","static"]),b=void 0!==e.ref?{[p]:e.ref}:{},v="function"==typeof u?u(t):u;"className"in m&&m.className&&"function"==typeof m.className&&(m.className=m.className(t)),m["aria-labelledby"]&&m["aria-labelledby"]===m.id&&(m["aria-labelledby"]=void 0);let h={};if(t){let e=!1,r=[];for(let[n,o]of Object.entries(t))"boolean"==typeof o&&(e=!0),!0===o&&r.push(n.replace(/([A-Z])/g,e=>`-${e.toLowerCase()}`));if(e)for(let e of(h["data-headlessui-state"]=r.join(" "),r))h[`data-${e}`]=""}if(i===n.Fragment&&(Object.keys(d(m)).length>0||Object.keys(d(h)).length>0))if(!(0,n.isValidElement)(v)||Array.isArray(v)&&v.length>1){if(Object.keys(d(m)).length>0)throw Error(['Passing props on "Fragment"!',"",`The current component <${s} /> is rendering a "Fragment".`,"However we need to passthrough the following props:",Object.keys(d(m)).concat(Object.keys(d(h))).map(e=>` - ${e}`).join(` +`),"","You can apply a few solutions:",['Add an `as="..."` prop, to ensure that we render an actual element instead of a "Fragment".',"Render a single element as the child so that we can forward the props onto that element."].map(e=>` - ${e}`).join(` +`)].join(` +`))}else{var g;let e=v.props,t=null==e?void 0:e.className,r="function"==typeof t?(...e)=>(0,o.classNames)(t(...e),m.className):(0,o.classNames)(t,m.className),s=c(v.props,d(f(m,["ref"])));for(let e in h)e in s&&delete h[e];return(0,n.cloneElement)(v,Object.assign({},s,h,b,{ref:a((g=v,n.default.version.split(".")[0]>="19"?g.props.ref:g.ref),b.ref)},r?{className:r}:{}))}return(0,n.createElement)(i,Object.assign({},f(m,["ref"]),i!==n.Fragment&&b,i!==n.Fragment&&h),v)}function u(...e){return e.every(e=>null==e)?void 0:t=>{for(let r of e)null!=r&&("function"==typeof r?r(t):r.current=t)}}function c(...e){if(0===e.length)return{};if(1===e.length)return e[0];let t={},r={};for(let n of e)for(let e in n)e.startsWith("on")&&"function"==typeof n[e]?(null!=r[e]||(r[e]=[]),r[e].push(n[e])):t[e]=n[e];if(t.disabled||t["aria-disabled"])for(let e in r)/^(on(?:Click|Pointer|Mouse|Key)(?:Down|Up|Press)?)$/.test(e)&&(r[e]=[e=>{var t;return null==(t=null==e?void 0:e.preventDefault)?void 0:t.call(e)}]);for(let e in r)Object.assign(t,{[e](t,...n){for(let o of r[e]){if((t instanceof Event||(null==t?void 0:t.nativeEvent)instanceof Event)&&t.defaultPrevented)return;o(t,...n)}}});return t}function d(e){let t=Object.assign({},e);for(let e in t)void 0===t[e]&&delete t[e];return t}function f(e,t=[]){let r=Object.assign({},e);for(let e of t)e in r&&delete r[e];return r}e.s(["RenderFeatures",0,a,"RenderStrategy",0,i,"compact",0,d,"forwardRefWithAs",0,function(e){var t;return Object.assign((0,n.forwardRef)(e),{displayName:null!=(t=e.displayName)?t:e.name})},"mergeProps",0,function(...e){if(0===e.length)return{};if(1===e.length)return e[0];let t={},r={};for(let n of e)for(let e in n)e.startsWith("on")&&"function"==typeof n[e]?(null!=r[e]||(r[e]=[]),r[e].push(n[e])):t[e]=n[e];for(let e in r)Object.assign(t,{[e](...t){for(let n of r[e])null==n||n(...t)}});return t},"useRender",0,function(){let e,t,r=(e=(0,n.useRef)([]),t=(0,n.useCallback)(t=>{for(let r of e.current)null!=r&&("function"==typeof r?r(t):r.current=t)},[]),(...r)=>{if(!r.every(e=>null==e))return e.current=r,t});return(0,n.useCallback)(e=>(function({ourProps:e,theirProps:t,slot:r,defaultTag:n,features:o,visible:a=!0,name:i,mergeRefs:d}){d=null!=d?d:u;let f=c(t,e);if(a)return l(f,r,n,i,d);let p=null!=o?o:0;if(2&p){let{static:e=!1,...t}=f;if(e)return l(t,r,n,i,d)}if(1&p){let{unmount:e=!0,...t}=f;return(0,s.match)(+!e,{0:()=>null,1:()=>l({...t,hidden:!0,style:{display:"none"}},r,n,i,d)})}return l(f,r,n,i,d)})({mergeRefs:r,...e}),[r])}])},2788,e=>{"use strict";let t;var r=e.i(700020),n=((t=n||{})[t.None=1]="None",t[t.Focusable=2]="Focusable",t[t.Hidden=4]="Hidden",t);let o=(0,r.forwardRefWithAs)(function(e,t){var n;let{features:o=1,...s}=e,a={ref:t,"aria-hidden":(2&o)==2||(null!=(n=s["aria-hidden"])?n:void 0),hidden:(4&o)==4||void 0,style:{position:"fixed",top:1,left:1,width:1,height:0,padding:0,margin:-1,overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",borderWidth:"0",...(4&o)==4&&(2&o)!=2&&{display:"none"}}};return(0,r.useRender)()({ourProps:a,theirProps:s,slot:{},defaultTag:"span",name:"Hidden"})});e.s(["Hidden",0,o,"HiddenFeatures",0,n])},998348,e=>{"use strict";let t;var r=((t=r||{}).Space=" ",t.Enter="Enter",t.Escape="Escape",t.Backspace="Backspace",t.Delete="Delete",t.ArrowLeft="ArrowLeft",t.ArrowUp="ArrowUp",t.ArrowRight="ArrowRight",t.ArrowDown="ArrowDown",t.Home="Home",t.End="End",t.PageUp="PageUp",t.PageDown="PageDown",t.Tab="Tab",t);e.s(["Keys",0,r])},553521,e=>{"use strict";var t=e.i(271645),r=e.i(835696);e.s(["useIsMounted",0,function(){let e=(0,t.useRef)(!1);return(0,r.useIsoMorphicEffect)(()=>(e.current=!0,()=>{e.current=!1}),[]),e}])},640497,e=>{"use strict";var t=e.i(271645),r=e.i(553521),n=e.i(2788);e.s(["FocusSentinel",0,function({onFocus:e}){let[o,s]=(0,t.useState)(!0),a=(0,r.useIsMounted)();return o?t.default.createElement(n.Hidden,{as:"button",type:"button",features:n.HiddenFeatures.Focusable,onFocus:t=>{t.preventDefault();let r,n=50;r=requestAnimationFrame(function t(){if(n--<=0){r&&cancelAnimationFrame(r);return}if(e()){if(cancelAnimationFrame(r),!a.current)return;s(!1);return}r=requestAnimationFrame(t)})}}):null}])},963703,e=>{"use strict";var t=e.i(271645);let r=t.createContext(null);e.s(["StableCollection",0,function({children:e}){let n=t.useRef({groups:new Map,get(e,t){var r;let n=this.groups.get(e);n||(n=new Map,this.groups.set(e,n));let o=null!=(r=n.get(t))?r:0;return n.set(t,o+1),[Array.from(n.keys()).indexOf(t),function(){let e=n.get(t);e>1?n.set(t,e-1):n.delete(t)}]}});return t.createElement(r.Provider,{value:n},e)},"useStableCollectionIndex",0,function(e){let n=t.useContext(r);if(!n)throw Error("You must wrap your component in a ");let o=t.useId(),[s,a]=n.current.get(e,o);return t.useEffect(()=>a,[]),s}])},970554,e=>{"use strict";let t,r,n;var o=e.i(783222),s=e.i(433336),a=e.i(271645),i=e.i(394487),l=e.i(914189),u=e.i(835696),c=e.i(941444),d=e.i(144279),f=e.i(294316),p=e.i(640497),m=e.i(2788),b=e.i(652265),v=e.i(397701),h=e.i(368578),g=e.i(402155),y=e.i(700020),E=e.i(963703),T=e.i(998348),w=((t=w||{})[t.Forwards=0]="Forwards",t[t.Backwards=1]="Backwards",t),x=((r=x||{})[r.Less=-1]="Less",r[r.Equal=0]="Equal",r[r.Greater=1]="Greater",r),F=((n=F||{})[n.SetSelectedIndex=0]="SetSelectedIndex",n[n.RegisterTab=1]="RegisterTab",n[n.UnregisterTab=2]="UnregisterTab",n[n.RegisterPanel=3]="RegisterPanel",n[n.UnregisterPanel=4]="UnregisterPanel",n);let P={0(e,t){var r;let n=(0,b.sortByDomNode)(e.tabs,e=>e.current),o=(0,b.sortByDomNode)(e.panels,e=>e.current),s=n.filter(e=>{var t;return!(null!=(t=e.current)&&t.hasAttribute("disabled"))}),a={...e,tabs:n,panels:o};if(t.index<0||t.index>n.length-1){let r=(0,v.match)(Math.sign(t.index-e.selectedIndex),{[-1]:()=>1,0:()=>(0,v.match)(Math.sign(t.index),{[-1]:()=>0,0:()=>0,1:()=>1}),1:()=>0});if(0===s.length)return a;let o=(0,v.match)(r,{0:()=>n.indexOf(s[0]),1:()=>n.indexOf(s[s.length-1])});return{...a,selectedIndex:-1===o?e.selectedIndex:o}}let i=n.slice(0,t.index),l=[...n.slice(t.index),...i].find(e=>s.includes(e));if(!l)return a;let u=null!=(r=n.indexOf(l))?r:e.selectedIndex;return -1===u&&(u=e.selectedIndex),{...a,selectedIndex:u}},1(e,t){if(e.tabs.includes(t.tab))return e;let r=e.tabs[e.selectedIndex],n=(0,b.sortByDomNode)([...e.tabs,t.tab],e=>e.current),o=e.selectedIndex;return e.info.current.isControlled||-1===(o=n.indexOf(r))&&(o=e.selectedIndex),{...e,tabs:n,selectedIndex:o}},2:(e,t)=>({...e,tabs:e.tabs.filter(e=>e!==t.tab)}),3:(e,t)=>e.panels.includes(t.panel)?e:{...e,panels:(0,b.sortByDomNode)([...e.panels,t.panel],e=>e.current)},4:(e,t)=>({...e,panels:e.panels.filter(e=>e!==t.panel)})},k=(0,a.createContext)(null);function L(e){let t=(0,a.useContext)(k);if(null===t){let t=Error(`<${e} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,L),t}return t}k.displayName="TabsDataContext";let N=(0,a.createContext)(null);function C(e){let t=(0,a.useContext)(N);if(null===t){let t=Error(`<${e} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,C),t}return t}function I(e,t){return(0,v.match)(t.type,P,e,t)}N.displayName="TabsActionsContext";let S=y.RenderFeatures.RenderStrategy|y.RenderFeatures.Static,A=Object.assign((0,y.forwardRefWithAs)(function(e,t){var r,n;let c=(0,a.useId)(),{id:p=`headlessui-tabs-tab-${c}`,disabled:m=!1,autoFocus:w=!1,...x}=e,{orientation:F,activation:P,selectedIndex:k,tabs:N,panels:I}=L("Tab"),S=C("Tab"),A=L("Tab"),[M,R]=(0,a.useState)(null),O=(0,a.useRef)(null),D=(0,f.useSyncRefs)(O,t,R);(0,u.useIsoMorphicEffect)(()=>S.registerTab(O),[S,O]);let H=(0,E.useStableCollectionIndex)("tabs"),j=N.indexOf(O);-1===j&&(j=H);let K=j===k,W=(0,l.useEvent)(e=>{var t;let r=e();if(r===b.FocusResult.Success&&"auto"===P){let e=null==(t=(0,g.getOwnerDocument)(O))?void 0:t.activeElement,r=A.tabs.findIndex(t=>t.current===e);-1!==r&&S.change(r)}return r}),B=(0,l.useEvent)(e=>{let t=N.map(e=>e.current).filter(Boolean);if(e.key===T.Keys.Space||e.key===T.Keys.Enter){e.preventDefault(),e.stopPropagation(),S.change(j);return}switch(e.key){case T.Keys.Home:case T.Keys.PageUp:return e.preventDefault(),e.stopPropagation(),W(()=>(0,b.focusIn)(t,b.Focus.First));case T.Keys.End:case T.Keys.PageDown:return e.preventDefault(),e.stopPropagation(),W(()=>(0,b.focusIn)(t,b.Focus.Last))}if(W(()=>(0,v.match)(F,{vertical:()=>e.key===T.Keys.ArrowUp?(0,b.focusIn)(t,b.Focus.Previous|b.Focus.WrapAround):e.key===T.Keys.ArrowDown?(0,b.focusIn)(t,b.Focus.Next|b.Focus.WrapAround):b.FocusResult.Error,horizontal:()=>e.key===T.Keys.ArrowLeft?(0,b.focusIn)(t,b.Focus.Previous|b.Focus.WrapAround):e.key===T.Keys.ArrowRight?(0,b.focusIn)(t,b.Focus.Next|b.Focus.WrapAround):b.FocusResult.Error}))===b.FocusResult.Success)return e.preventDefault()}),V=(0,a.useRef)(!1),_=(0,l.useEvent)(()=>{var e;V.current||(V.current=!0,null==(e=O.current)||e.focus({preventScroll:!0}),S.change(j),(0,h.microTask)(()=>{V.current=!1}))}),G=(0,l.useEvent)(e=>{e.preventDefault()}),{isFocusVisible:U,focusProps:$}=(0,o.useFocusRing)({autoFocus:w}),{isHovered:q,hoverProps:X}=(0,s.useHover)({isDisabled:m}),{pressed:Y,pressProps:z}=(0,i.useActivePress)({disabled:m}),Z=(0,a.useMemo)(()=>({selected:K,hover:q,active:Y,focus:U,autofocus:w,disabled:m}),[K,q,U,Y,w,m]),J=(0,y.mergeProps)({ref:D,onKeyDown:B,onMouseDown:G,onClick:_,id:p,role:"tab",type:(0,d.useResolveButtonType)(e,M),"aria-controls":null==(n=null==(r=I[j])?void 0:r.current)?void 0:n.id,"aria-selected":K,tabIndex:K?0:-1,disabled:m||void 0,autoFocus:w},$,X,z);return(0,y.useRender)()({ourProps:J,theirProps:x,slot:Z,defaultTag:"button",name:"Tabs.Tab"})}),{Group:(0,y.forwardRefWithAs)(function(e,t){let{defaultIndex:r=0,vertical:n=!1,manual:o=!1,onChange:s,selectedIndex:i=null,...d}=e,m=n?"vertical":"horizontal",v=o?"manual":"auto",h=null!==i,g=(0,c.useLatestValue)({isControlled:h}),T=(0,f.useSyncRefs)(t),[w,x]=(0,a.useReducer)(I,{info:g,selectedIndex:null!=i?i:r,tabs:[],panels:[]}),F=(0,a.useMemo)(()=>({selectedIndex:w.selectedIndex}),[w.selectedIndex]),P=(0,c.useLatestValue)(s||(()=>{})),L=(0,c.useLatestValue)(w.tabs),C=(0,a.useMemo)(()=>({orientation:m,activation:v,...w}),[m,v,w]),S=(0,l.useEvent)(e=>(x({type:1,tab:e}),()=>x({type:2,tab:e}))),A=(0,l.useEvent)(e=>(x({type:3,panel:e}),()=>x({type:4,panel:e}))),M=(0,l.useEvent)(e=>{R.current!==e&&P.current(e),h||x({type:0,index:e})}),R=(0,c.useLatestValue)(h?e.selectedIndex:w.selectedIndex),O=(0,a.useMemo)(()=>({registerTab:S,registerPanel:A,change:M}),[]);(0,u.useIsoMorphicEffect)(()=>{x({type:0,index:null!=i?i:r})},[i]),(0,u.useIsoMorphicEffect)(()=>{if(void 0===R.current||w.tabs.length<=0)return;let e=(0,b.sortByDomNode)(w.tabs,e=>e.current);e.some((e,t)=>w.tabs[t]!==e)&&M(e.indexOf(w.tabs[R.current]))});let D=(0,y.useRender)();return a.default.createElement(E.StableCollection,null,a.default.createElement(N.Provider,{value:O},a.default.createElement(k.Provider,{value:C},C.tabs.length<=0&&a.default.createElement(p.FocusSentinel,{onFocus:()=>{var e,t;for(let r of L.current)if((null==(e=r.current)?void 0:e.tabIndex)===0)return null==(t=r.current)||t.focus(),!0;return!1}}),D({ourProps:{ref:T},theirProps:d,slot:F,defaultTag:"div",name:"Tabs"}))))}),List:(0,y.forwardRefWithAs)(function(e,t){let{orientation:r,selectedIndex:n}=L("Tab.List"),o=(0,f.useSyncRefs)(t),s=(0,a.useMemo)(()=>({selectedIndex:n}),[n]);return(0,y.useRender)()({ourProps:{ref:o,role:"tablist","aria-orientation":r},theirProps:e,slot:s,defaultTag:"div",name:"Tabs.List"})}),Panels:(0,y.forwardRefWithAs)(function(e,t){let{selectedIndex:r}=L("Tab.Panels"),n=(0,f.useSyncRefs)(t),o=(0,a.useMemo)(()=>({selectedIndex:r}),[r]);return(0,y.useRender)()({ourProps:{ref:n},theirProps:e,slot:o,defaultTag:"div",name:"Tabs.Panels"})}),Panel:(0,y.forwardRefWithAs)(function(e,t){var r,n,s,i;let l=(0,a.useId)(),{id:c=`headlessui-tabs-panel-${l}`,tabIndex:d=0,...p}=e,{selectedIndex:b,tabs:v,panels:h}=L("Tab.Panel"),g=C("Tab.Panel"),T=(0,a.useRef)(null),w=(0,f.useSyncRefs)(T,t);(0,u.useIsoMorphicEffect)(()=>g.registerPanel(T),[g,T]);let x=(0,E.useStableCollectionIndex)("panels"),F=h.indexOf(T);-1===F&&(F=x);let P=F===b,{isFocusVisible:k,focusProps:N}=(0,o.useFocusRing)(),I=(0,a.useMemo)(()=>({selected:P,focus:k}),[P,k]),A=(0,y.mergeProps)({ref:w,id:c,role:"tabpanel","aria-labelledby":null==(n=null==(r=v[F])?void 0:r.current)?void 0:n.id,tabIndex:P?d:-1},N),M=(0,y.useRender)();return P||null!=(s=p.unmount)&&!s||null!=(i=p.static)&&i?M({ourProps:A,theirProps:p,slot:I,defaultTag:"div",features:S,visible:P,name:"Tabs.Panel"}):a.default.createElement(m.Hidden,{"aria-hidden":"true",...A})})});e.s(["Tab",0,A])},405371,910342,e=>{"use strict";var t=e.i(290571),r=e.i(271645),n=e.i(480731);let o=(0,r.createContext)(n.BaseColors.Blue);e.s(["default",0,o],910342);var s=e.i(970554),a=e.i(444755);let i=(0,e.i(673706).makeClassName)("TabList"),l=(0,r.createContext)("line"),u={line:(0,a.tremorTwMerge)("flex border-b space-x-4","border-tremor-border","dark:border-dark-tremor-border"),solid:(0,a.tremorTwMerge)("inline-flex p-0.5 rounded-tremor-default space-x-1.5","bg-tremor-background-subtle","dark:bg-dark-tremor-background-subtle")},c=r.default.forwardRef((e,n)=>{let{color:c,variant:d="line",children:f,className:p}=e,m=(0,t.__rest)(e,["color","variant","children","className"]);return r.default.createElement(s.Tab.List,Object.assign({ref:n,className:(0,a.tremorTwMerge)(i("root"),"justify-start overflow-x-clip",u[d],p)},m),r.default.createElement(l.Provider,{value:d},r.default.createElement(o.Provider,{value:c},f)))});c.displayName="TabList",e.s(["TabVariantContext",0,l,"default",0,c],405371)},197647,e=>{"use strict";var t=e.i(290571),r=e.i(970554),n=e.i(95779),o=e.i(444755),s=e.i(673706),a=e.i(271645),i=e.i(405371),l=e.i(910342);let u=(0,s.makeClassName)("Tab"),c=a.default.forwardRef((e,c)=>{let{icon:d,className:f,children:p}=e,m=(0,t.__rest)(e,["icon","className","children"]),b=(0,a.useContext)(i.TabVariantContext),v=(0,a.useContext)(l.default);return a.default.createElement(r.Tab,Object.assign({ref:c,className:(0,o.tremorTwMerge)(u("root"),"flex whitespace-nowrap truncate max-w-xs outline-none data-focus-visible:ring text-tremor-default transition duration-100",function(e,t){switch(e){case"line":return(0,o.tremorTwMerge)("data-[selected]:border-b-2 hover:border-b-2 border-transparent transition duration-100 -mb-px px-2 py-2","hover:border-tremor-content hover:text-tremor-content-emphasis text-tremor-content","[&:not([data-selected])]:dark:hover:border-dark-tremor-content-emphasis [&:not([data-selected])]:dark:hover:text-dark-tremor-content-emphasis [&:not([data-selected])]:dark:text-dark-tremor-content",t?(0,s.getColorClassNames)(t,n.colorPalette.border).selectBorderColor:["data-[selected]:border-tremor-brand data-[selected]:text-tremor-brand","data-[selected]:dark:border-dark-tremor-brand data-[selected]:dark:text-dark-tremor-brand"]);case"solid":return(0,o.tremorTwMerge)("border-transparent border rounded-tremor-small px-2.5 py-1","data-[selected]:border-tremor-border data-[selected]:bg-tremor-background data-[selected]:shadow-tremor-input [&:not([data-selected])]:hover:text-tremor-content-emphasis data-[selected]:text-tremor-brand [&:not([data-selected])]:text-tremor-content","dark:data-[selected]:border-dark-tremor-border dark:data-[selected]:bg-dark-tremor-background dark:data-[selected]:shadow-dark-tremor-input dark:[&:not([data-selected])]:hover:text-dark-tremor-content-emphasis dark:data-[selected]:text-dark-tremor-brand dark:[&:not([data-selected])]:text-dark-tremor-content",t?(0,s.getColorClassNames)(t,n.colorPalette.text).selectTextColor:"text-tremor-content dark:text-dark-tremor-content")}}(b,v),f,v&&(0,s.getColorClassNames)(v,n.colorPalette.text).selectTextColor)},m),d?a.default.createElement(d,{className:(0,o.tremorTwMerge)(u("icon"),"flex-none h-5 w-5",p?"mr-2":"")}):null,p?a.default.createElement("span",null,p):null)});c.displayName="Tab",e.s(["Tab",0,c],197647)},653824,e=>{"use strict";var t=e.i(290571),r=e.i(970554),n=e.i(444755),o=e.i(673706),s=e.i(271645);let a=(0,o.makeClassName)("TabGroup"),i=s.default.forwardRef((e,o)=>{let{defaultIndex:i,index:l,onIndexChange:u,children:c,className:d}=e,f=(0,t.__rest)(e,["defaultIndex","index","onIndexChange","children","className"]);return s.default.createElement(r.Tab.Group,Object.assign({as:"div",ref:o,defaultIndex:i,selectedIndex:l,onChange:u,className:(0,n.tremorTwMerge)(a("root"),"w-full",d)},f),c)});i.displayName="TabGroup",e.s(["TabGroup",0,i],653824)},881073,e=>{"use strict";var t=e.i(405371);e.s(["TabList",()=>t.default])},723731,e=>{"use strict";var t=e.i(290571),r=e.i(970554),n=e.i(751734),o=e.i(144582),s=e.i(444755),a=e.i(673706),i=e.i(271645);let l=(0,a.makeClassName)("TabPanels"),u=i.default.forwardRef((e,a)=>{let{children:u,className:c}=e,d=(0,t.__rest)(e,["children","className"]);return i.default.createElement(r.Tab.Panels,Object.assign({as:"div",ref:a,className:(0,s.tremorTwMerge)(l("root"),"w-full",c)},d),({selectedIndex:e})=>i.default.createElement(o.default.Provider,{value:{selectedValue:e}},i.default.Children.map(u,(e,t)=>i.default.createElement(n.default.Provider,{value:t},e))))});u.displayName="TabPanels",e.s(["TabPanels",0,u],723731)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/024dtgrf2jszs.js b/litellm/proxy/_experimental/out/_next/static/chunks/024dtgrf2jszs.js new file mode 100644 index 00000000000..b1a91138cd5 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/024dtgrf2jszs.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,510674,e=>{"use strict";var t=e.i(266027),s=e.i(243652),l=e.i(602869),a=e.i(431703),r=e.i(135214),i=e.i(708347);let n=(0,s.createQueryKeys)("projects"),o=[...i.all_admin_roles,...i.internalUserRoles],d=async e=>{let t=(0,l.getProxyBaseUrl)(),s=`${t}/project/list`,r=await fetch(s,{method:"GET",headers:{[(0,l.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!r.ok){let e=await r.json(),t=(0,a.deriveErrorMessage)(e);throw(0,l.handleError)(t),Error(t)}return r.json()};e.s(["projectKeys",0,n,"useProjects",0,()=>{let{accessToken:e,userRole:s}=(0,r.default)();return(0,t.useQuery)({queryKey:n.list({}),queryFn:async()=>d(e),enabled:!!e&&o.includes(s)})}])},207082,e=>{"use strict";var t=e.i(619273),s=e.i(266027),l=e.i(243652),a=e.i(602869),r=e.i(431703),i=e.i(135214);let n=(0,l.createQueryKeys)("keys"),o=async(e,t,s,l={})=>{try{let i=(0,a.getProxyBaseUrl)(),n=new URLSearchParams(Object.entries({team_id:l.teamID,project_id:l.projectID,agent_id:l.agentID,organization_id:l.organizationID,key_alias:l.selectedKeyAlias,key_hash:l.keyHash,user_id:l.userID,page:t,size:s,sort_by:l.sortBy,sort_order:l.sortOrder,expand:l.expand,status:l.status,return_full_object:"true",include_team_keys:"true",include_created_by_keys:"true",substring_matching:"true"}).filter(([,e])=>null!=e).map(([e,t])=>[e,String(t)])),o=`${i?`${i}/key/list`:"/key/list"}?${n}`,d=await fetch(o,{method:"GET",headers:{[(0,a.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!d.ok){let e=await d.json(),t=(0,r.deriveErrorMessage)(e);throw(0,a.handleError)(t),Error(t)}return await d.json()}catch(e){throw console.error("Failed to list keys:",e),e}},d=(0,l.createQueryKeys)("deletedKeys");e.s(["keyKeys",0,n,"useDeletedKeys",0,(e,l,a={})=>{let{accessToken:r}=(0,i.default)();return(0,s.useQuery)({queryKey:d.list({page:e,limit:l,...a}),queryFn:async()=>await o(r,e,l,{...a,status:"deleted"}),enabled:!!r,staleTime:3e4,placeholderData:t.keepPreviousData})},"useKeys",0,(e,l,a={})=>{let{accessToken:r}=(0,i.default)();return(0,s.useQuery)({queryKey:n.list({page:e,limit:l,...a}),queryFn:async()=>await o(r,e,l,a),enabled:!!r,staleTime:3e4,placeholderData:t.keepPreviousData})}])},109034,e=>{"use strict";var t=e.i(266027),s=e.i(243652),l=e.i(602869),a=e.i(135214);let r=(0,s.createQueryKeys)("tags");e.s(["useTags",0,()=>{let{accessToken:e,userId:s,userRole:i}=(0,a.default)();return(0,t.useQuery)({queryKey:r.list({}),queryFn:async()=>await (0,l.tagListCall)(e),enabled:!!(e&&s&&i)})}])},552130,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(199133),a=e.i(602869);e.s(["default",0,({onChange:e,value:r,className:i,accessToken:n,placeholder:o="Select agents",disabled:d=!1})=>{let[c,u]=(0,s.useState)([]),[m,p]=(0,s.useState)([]),[g,h]=(0,s.useState)(!1);(0,s.useEffect)(()=>{(async()=>{if(n){h(!0);try{let e=await (0,a.getAgentsList)(n),t=e?.agents||[];u(t);let s=new Set;t.forEach(e=>{let t=e.agent_access_groups;t&&Array.isArray(t)&&t.forEach(e=>s.add(e))}),p(Array.from(s))}catch(e){console.error("Error fetching agents:",e)}finally{h(!1)}}})()},[n]);let x=[...m.map(e=>({label:e,value:`group:${e}`,isAccessGroup:!0,searchText:`${e} Access Group`})),...c.map(e=>({label:`${e.agent_name||e.agent_id}`,value:e.agent_id,isAccessGroup:!1,searchText:`${e.agent_name||e.agent_id} ${e.agent_id} Agent`}))],y=[...r?.agents||[],...(r?.accessGroups||[]).map(e=>`group:${e}`)];return(0,t.jsx)("div",{children:(0,t.jsx)(l.Select,{mode:"multiple",placeholder:o,onChange:t=>{e({agents:t.filter(e=>!e.startsWith("group:")),accessGroups:t.filter(e=>e.startsWith("group:")).map(e=>e.replace("group:",""))})},value:y,loading:g,className:i,allowClear:!0,showSearch:!0,style:{width:"100%"},disabled:d,filterOption:(e,t)=>(x.find(e=>e.value===t?.value)?.searchText||"").toLowerCase().includes(e.toLowerCase()),children:x.map(e=>(0,t.jsx)(l.Select.Option,{value:e.value,label:e.label,children:(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[(0,t.jsx)("span",{style:{display:"inline-block",width:8,height:8,borderRadius:"50%",background:e.isAccessGroup?"#52c41a":"#722ed1",flexShrink:0}}),(0,t.jsx)("span",{style:{flex:1},children:e.label}),(0,t.jsx)("span",{style:{color:e.isAccessGroup?"#52c41a":"#722ed1",fontSize:"12px",fontWeight:500,opacity:.8},children:e.isAccessGroup?"Access Group":"Agent"})]})},e.value))})})}])},557662,e=>{"use strict";let t="/ui/assets/logos/",s=[{id:"arize",displayName:"Arize",logo:`${t}arize.png`,supports_key_team_logging:!0,dynamic_params:{arize_api_key:"password",arize_space_id:"password"},description:"Arize Logging Integration"},{id:"braintrust",displayName:"Braintrust",logo:`${t}braintrust.png`,supports_key_team_logging:!1,dynamic_params:{braintrust_api_key:"password",braintrust_project_name:"text"},description:"Braintrust Logging Integration"},{id:"custom_callback_api",displayName:"Custom Callback API",logo:`${t}custom.svg`,supports_key_team_logging:!0,dynamic_params:{custom_callback_api_url:"text",custom_callback_api_headers:"text"},description:"Custom Callback API Logging Integration"},{id:"galileo",displayName:"Galileo",logo:`${t}galileo.ico`,supports_key_team_logging:!1,dynamic_params:{GALILEO_API_KEY:"password",GALILEO_PROJECT_ID:"text",GALILEO_LOG_STREAM_ID:"text",GALILEO_BASE_URL:"text",GALILEO_USERNAME:"text",GALILEO_PASSWORD:"password"},description:"Galileo AI Observability Integration"},{id:"datadog",displayName:"Datadog",logo:`${t}datadog.png`,supports_key_team_logging:!1,dynamic_params:{dd_api_key:"password",dd_site:"text"},description:"Datadog Logging Integration"},{id:"lago",displayName:"Lago",logo:`${t}lago.svg`,supports_key_team_logging:!1,dynamic_params:{lago_api_url:"text",lago_api_key:"password"},description:"Lago Billing Logging Integration"},{id:"langfuse",displayName:"Langfuse",logo:`${t}langfuse.png`,supports_key_team_logging:!0,dynamic_params:{langfuse_public_key:"text",langfuse_secret_key:"password",langfuse_host:"text"},description:"Langfuse v2 Logging Integration"},{id:"langfuse_otel",displayName:"Langfuse OTEL",logo:`${t}langfuse.png`,supports_key_team_logging:!0,dynamic_params:{langfuse_public_key:"text",langfuse_secret_key:"password",langfuse_host:"text"},description:"Langfuse v3 OTEL Logging Integration"},{id:"langsmith",displayName:"LangSmith",logo:`${t}langsmith.png`,supports_key_team_logging:!0,dynamic_params:{langsmith_api_key:"password",langsmith_project:"text",langsmith_base_url:"text",langsmith_sampling_rate:"number"},description:"Langsmith Logging Integration"},{id:"openmeter",displayName:"OpenMeter",logo:`${t}openmeter.png`,supports_key_team_logging:!1,dynamic_params:{openmeter_api_key:"password",openmeter_base_url:"text"},description:"OpenMeter Logging Integration"},{id:"otel",displayName:"Open Telemetry",logo:`${t}otel.png`,supports_key_team_logging:!1,dynamic_params:{otel_endpoint:"text",otel_headers:"text"},description:"OpenTelemetry Logging Integration"},{id:"s3",displayName:"S3",logo:`${t}aws.svg`,supports_key_team_logging:!1,dynamic_params:{s3_bucket_name:"text",aws_access_key_id:"password",aws_secret_access_key:"password",aws_region:"text"},description:"S3 Bucket (AWS) Logging Integration"},{id:"SQS",displayName:"SQS",logo:`${t}aws.svg`,supports_key_team_logging:!1,dynamic_params:{sqs_queue_url:"text",aws_access_key_id:"password",aws_secret_access_key:"password",aws_region:"text"},description:"SQS Queue (AWS) Logging Integration"}],l=s.reduce((e,t)=>(e[t.displayName]=t,e),{}),a=s.reduce((e,t)=>(e[t.displayName]=t.id,e),{}),r=s.reduce((e,t)=>(e[t.id]=t.displayName,e),{});e.s(["callbackInfo",0,l,"callback_map",0,a,"mapDisplayToInternalNames",0,e=>e.map(e=>a[e]||e),"mapInternalToDisplayNames",0,e=>e.map(e=>r[e]||e),"reverse_callback_map",0,r])},9314,e=>{"use strict";var t=e.i(843476),s=e.i(199133),l=e.i(981339),a=e.i(645526),r=e.i(599724),i=e.i(263147);e.s(["default",0,({value:e,onChange:n,placeholder:o="Select access groups",disabled:d=!1,style:c,className:u,showLabel:m=!1,labelText:p="Access Group",allowClear:g=!0})=>{let{data:h,isLoading:x,isError:y}=(0,i.useAccessGroups)();if(x)return(0,t.jsxs)("div",{children:[m&&(0,t.jsxs)(r.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,t.jsx)(a.TeamOutlined,{className:"mr-2"})," ",p]}),(0,t.jsx)(l.Skeleton.Input,{active:!0,block:!0,style:{height:32,...c}})]});let f=(h??[]).map(e=>({label:(0,t.jsxs)("span",{children:[(0,t.jsx)("span",{className:"font-medium",children:e.access_group_name})," ",(0,t.jsxs)("span",{className:"text-gray-400 text-xs",children:["(",e.access_group_id,")"]})]}),value:e.access_group_id,selectedLabel:e.access_group_name,searchText:`${e.access_group_name} ${e.access_group_id}`}));return(0,t.jsxs)("div",{children:[m&&(0,t.jsxs)(r.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,t.jsx)(a.TeamOutlined,{className:"mr-2"})," ",p]}),(0,t.jsx)(s.Select,{mode:"multiple",value:e,placeholder:o,onChange:n,disabled:d,allowClear:g,showSearch:!0,style:{width:"100%",...c},className:`rounded-md ${u??""}`,notFoundContent:y?(0,t.jsx)("span",{className:"text-red-500",children:"Failed to load access groups"}):"No access groups found",filterOption:(e,t)=>(f.find(e=>e.value===t?.value)?.searchText??"").toLowerCase().includes(e.toLowerCase()),optionLabelProp:"selectedLabel",options:f.map(e=>({label:e.label,value:e.value,selectedLabel:e.selectedLabel}))})]})}])},392110,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(199133),a=e.i(592968),r=e.i(312361),i=e.i(790848),n=e.i(536916),o=e.i(827252),d=e.i(779241);let{Option:c}=l.Select;e.s(["default",0,({form:e,autoRotationEnabled:u,onAutoRotationChange:m,rotationInterval:p,onRotationIntervalChange:g,isCreateMode:h=!1,neverExpire:x=!1,onNeverExpireChange:y})=>{let f=p&&!["7d","30d","90d","180d","365d"].includes(p),[b,_]=(0,s.useState)(f),[j,v]=(0,s.useState)(f?p:""),[w,N]=(0,s.useState)(e?.getFieldValue?.("duration")||"");return(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Key Expiry Settings"}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,t.jsx)("span",{children:"Expire Key"}),(0,t.jsx)(a.Tooltip,{title:"Set when this key should expire. Format: 30s (seconds), 30m (minutes), 30h (hours), 30d (days). Leave empty to keep the current expiry unchanged.",children:(0,t.jsx)(o.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})}),!h&&y&&(0,t.jsx)(n.Checkbox,{checked:x,onChange:t=>{let s=t.target.checked;y(s),s&&(N(""),e&&"function"==typeof e.setFieldValue?e.setFieldValue("duration",""):e&&"function"==typeof e.setFieldsValue&&e.setFieldsValue({duration:""}))},className:"ml-2 text-sm font-normal text-gray-600",children:"Never Expire"})]}),(0,t.jsx)(d.TextInput,{name:"duration",placeholder:h?"e.g., 30d or leave empty to never expire":"e.g., 30d",className:"w-full",value:w,onValueChange:t=>{N(t),e&&"function"==typeof e.setFieldValue?e.setFieldValue("duration",t):e&&"function"==typeof e.setFieldsValue&&e.setFieldsValue({duration:t})},disabled:!h&&x})]})]}),(0,t.jsx)(r.Divider,{}),(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Auto-Rotation Settings"}),(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,t.jsx)("span",{children:"Enable Auto-Rotation"}),(0,t.jsx)(a.Tooltip,{title:"Key will automatically regenerate at the specified interval for enhanced security.",children:(0,t.jsx)(o.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})})]}),(0,t.jsx)(i.Switch,{checked:u,onChange:m,size:"default",className:u?"":"bg-gray-400"})]}),u&&(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,t.jsx)("span",{children:"Rotation Interval"}),(0,t.jsx)(a.Tooltip,{title:"How often the key should be automatically rotated. Choose the interval that best fits your security requirements.",children:(0,t.jsx)(o.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)(l.Select,{value:b?"custom":p,onChange:e=>{"custom"===e?_(!0):(_(!1),v(""),g(e))},className:"w-full",placeholder:"Select interval",children:[(0,t.jsx)(c,{value:"7d",children:"7 days"}),(0,t.jsx)(c,{value:"30d",children:"30 days"}),(0,t.jsx)(c,{value:"90d",children:"90 days"}),(0,t.jsx)(c,{value:"180d",children:"180 days"}),(0,t.jsx)(c,{value:"365d",children:"365 days"}),(0,t.jsx)(c,{value:"custom",children:"Custom interval"})]}),b&&(0,t.jsxs)("div",{className:"space-y-1",children:[(0,t.jsx)(d.TextInput,{value:j,onChange:e=>{let t=e.target.value;v(t),g(t)},placeholder:"e.g., 1s, 5m, 2h, 14d"}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Supported formats: seconds (s), minutes (m), hours (h), days (d)"})]})]})]})]}),u&&(0,t.jsx)("div",{className:"bg-blue-50 p-3 rounded-md text-sm text-blue-700",children:"When rotation occurs, you'll receive a notification with the new key. The old key will be deactivated after a brief grace period."})]})]})}])},533882,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(250980),a=e.i(797672),r=e.i(68155),i=e.i(304967),n=e.i(629569),o=e.i(599724),d=e.i(269200),c=e.i(427612),u=e.i(64848),m=e.i(942232),p=e.i(496020),g=e.i(977572),h=e.i(992619),x=e.i(727749);e.s(["default",0,({accessToken:e,initialModelAliases:y={},onAliasUpdate:f,showExampleConfig:b=!0})=>{let[_,j]=(0,s.useState)([]),[v,w]=(0,s.useState)({aliasName:"",targetModel:""}),[N,k]=(0,s.useState)(null);(0,s.useEffect)(()=>{j(Object.entries(y).map(([e,t],s)=>({id:`${s}-${e}`,aliasName:e,targetModel:t})))},[y]);let S=()=>{if(!N)return;if(!N.aliasName||!N.targetModel)return void x.default.fromBackend("Please provide both alias name and target model");if(_.some(e=>e.id!==N.id&&e.aliasName===N.aliasName))return void x.default.fromBackend("An alias with this name already exists");let e=_.map(e=>e.id===N.id?N:e);j(e),k(null);let t={};e.forEach(e=>{t[e.aliasName]=e.targetModel}),f&&f(t),x.default.success("Alias updated successfully")},C=()=>{k(null)},T=_.reduce((e,t)=>(e[t.aliasName]=t.targetModel,e),{});return(0,t.jsxs)("div",{className:"mt-4",children:[(0,t.jsxs)("div",{className:"mb-6",children:[(0,t.jsx)(o.Text,{className:"text-sm font-medium text-gray-700 mb-2",children:"Add New Alias"}),(0,t.jsxs)("div",{className:"grid grid-cols-3 gap-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Alias Name"}),(0,t.jsx)("input",{type:"text",value:v.aliasName,onChange:e=>w({...v,aliasName:e.target.value}),placeholder:"e.g., gpt-4o",className:"w-full px-3 py-2 border border-gray-300 rounded-md text-sm"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Target Model"}),(0,t.jsx)(h.default,{accessToken:e,value:v.targetModel,placeholder:"Select target model",onChange:e=>w({...v,targetModel:e}),showLabel:!1})]}),(0,t.jsx)("div",{className:"flex items-end",children:(0,t.jsxs)("button",{onClick:()=>{if(!v.aliasName||!v.targetModel)return void x.default.fromBackend("Please provide both alias name and target model");if(_.some(e=>e.aliasName===v.aliasName))return void x.default.fromBackend("An alias with this name already exists");let e=[..._,{id:`${Date.now()}-${v.aliasName}`,aliasName:v.aliasName,targetModel:v.targetModel}];j(e),w({aliasName:"",targetModel:""});let t={};e.forEach(e=>{t[e.aliasName]=e.targetModel}),f&&f(t),x.default.success("Alias added successfully")},disabled:!v.aliasName||!v.targetModel,className:`flex items-center px-4 py-2 rounded-md text-sm ${!v.aliasName||!v.targetModel?"bg-gray-300 text-gray-500 cursor-not-allowed":"bg-green-600 text-white hover:bg-green-700"}`,children:[(0,t.jsx)(l.PlusCircleIcon,{className:"w-4 h-4 mr-1"}),"Add Alias"]})})]})]}),(0,t.jsx)(o.Text,{className:"text-sm font-medium text-gray-700 mb-2",children:"Manage Existing Aliases"}),(0,t.jsx)("div",{className:"rounded-lg custom-border relative mb-6",children:(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsxs)(d.Table,{className:"[&_td]:py-0.5 [&_th]:py-1",children:[(0,t.jsx)(c.TableHead,{children:(0,t.jsxs)(p.TableRow,{children:[(0,t.jsx)(u.TableHeaderCell,{className:"py-1 h-8",children:"Alias Name"}),(0,t.jsx)(u.TableHeaderCell,{className:"py-1 h-8",children:"Target Model"}),(0,t.jsx)(u.TableHeaderCell,{className:"py-1 h-8",children:"Actions"})]})}),(0,t.jsxs)(m.TableBody,{children:[_.map(s=>(0,t.jsx)(p.TableRow,{className:"h-8",children:N&&N.id===s.id?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(g.TableCell,{className:"py-0.5",children:(0,t.jsx)("input",{type:"text",value:N.aliasName,onChange:e=>k({...N,aliasName:e.target.value}),className:"w-full px-2 py-1 border border-gray-300 rounded-md text-sm"})}),(0,t.jsx)(g.TableCell,{className:"py-0.5",children:(0,t.jsx)(h.default,{accessToken:e,value:N.targetModel,onChange:e=>k({...N,targetModel:e}),showLabel:!1,style:{height:"32px"}})}),(0,t.jsx)(g.TableCell,{className:"py-0.5 whitespace-nowrap",children:(0,t.jsxs)("div",{className:"flex space-x-2",children:[(0,t.jsx)("button",{onClick:S,className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded-sm hover:bg-blue-100",children:"Save"}),(0,t.jsx)("button",{onClick:C,className:"text-xs bg-gray-50 text-gray-600 px-2 py-1 rounded-sm hover:bg-gray-100",children:"Cancel"})]})})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(g.TableCell,{className:"py-0.5 text-sm text-gray-900",children:s.aliasName}),(0,t.jsx)(g.TableCell,{className:"py-0.5 text-sm text-gray-500",children:s.targetModel}),(0,t.jsx)(g.TableCell,{className:"py-0.5 whitespace-nowrap",children:(0,t.jsxs)("div",{className:"flex space-x-2",children:[(0,t.jsx)("button",{onClick:()=>{k({...s})},className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded-sm hover:bg-blue-100",children:(0,t.jsx)(a.PencilIcon,{className:"w-3 h-3"})}),(0,t.jsx)("button",{onClick:()=>{var e;let t,l;return e=s.id,j(t=_.filter(t=>t.id!==e)),l={},void(t.forEach(e=>{l[e.aliasName]=e.targetModel}),f&&f(l),x.default.success("Alias deleted successfully"))},className:"text-xs bg-red-50 text-red-600 px-2 py-1 rounded-sm hover:bg-red-100",children:(0,t.jsx)(r.TrashIcon,{className:"w-3 h-3"})})]})})]})},s.id)),0===_.length&&(0,t.jsx)(p.TableRow,{children:(0,t.jsx)(g.TableCell,{colSpan:3,className:"py-0.5 text-sm text-gray-500 text-center",children:"No aliases added yet. Add a new alias above."})})]})]})})}),b&&(0,t.jsxs)(i.Card,{children:[(0,t.jsx)(n.Title,{className:"mb-4",children:"Configuration Example"}),(0,t.jsx)(o.Text,{className:"text-gray-600 mb-4",children:"Here's how your current aliases would look in the config:"}),(0,t.jsx)("div",{className:"bg-gray-100 rounded-lg p-4 font-mono text-sm",children:(0,t.jsxs)("div",{className:"text-gray-700",children:["model_aliases:",0===Object.keys(T).length?(0,t.jsxs)("span",{className:"text-gray-500",children:[(0,t.jsx)("br",{}),"  # No aliases configured yet"]}):Object.entries(T).map(([e,s])=>(0,t.jsxs)("span",{children:[(0,t.jsx)("br",{}),'  "',e,'": "',s,'"']},e))]})})]})]})}])},844565,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(199133),a=e.i(602869);e.s(["default",0,({onChange:e,value:r,className:i,accessToken:n,placeholder:o="Select pass through routes",disabled:d=!1,teamId:c})=>{let[u,m]=(0,s.useState)([]),[p,g]=(0,s.useState)(!1);return(0,s.useEffect)(()=>{(async()=>{if(n){g(!0);try{let e=await (0,a.getPassThroughEndpointsCall)(n,c);if(e.endpoints){let t=e.endpoints.flatMap(e=>{let t=e.path,s=e.methods;return s&&s.length>0?s.map(e=>({label:`${e} ${t}`,value:t})):[{label:t,value:t}]});m(t)}}catch(e){console.error("Error fetching pass through routes:",e)}finally{g(!1)}}})()},[n,c]),(0,t.jsx)(l.Select,{mode:"tags",placeholder:o,onChange:e,value:r,loading:p,className:i,allowClear:!0,options:u,optionFilterProp:"label",showSearch:!0,style:{width:"100%"},disabled:d})}])},810757,477386,e=>{"use strict";var t=e.i(271645);let s=t.forwardRef(function(e,s){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:s},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"}),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"}))});e.s(["CogIcon",0,s],810757);let l=t.forwardRef(function(e,s){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:s},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"}))});e.s(["BanIcon",0,l],477386)},266484,e=>{"use strict";var t=e.i(843476),s=e.i(199133),l=e.i(592968),a=e.i(312361),r=e.i(827252),i=e.i(994388),n=e.i(304967),o=e.i(779241),d=e.i(988297),c=e.i(68155),u=e.i(810757),m=e.i(477386),p=e.i(557662),g=e.i(555987),h=e.i(435451);let{Option:x}=s.Select;e.s(["default",0,({value:e=[],onChange:y,disabledCallbacks:f=[],onDisabledCallbacksChange:b})=>{let _=Object.entries(p.callbackInfo).filter(([e,t])=>t.supports_key_team_logging).map(([e,t])=>e),j=Object.keys(p.callbackInfo),v=e=>{y?.(e)},w=(t,s,l)=>{let a=[...e];if("callback_name"===s){let e=p.callback_map[l]||l;a[t]={...a[t],[s]:e,callback_vars:{}}}else a[t]={...a[t],[s]:l};v(a)},N=(t,s,l)=>{let a=[...e];a[t]={...a[t],callback_vars:{...a[t].callback_vars,[s]:l}},v(a)};return(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)(m.BanIcon,{className:"w-5 h-5 text-red-500"}),(0,t.jsx)("span",{className:"text-base font-semibold text-gray-800",children:"Disabled Callbacks"}),(0,t.jsx)(l.Tooltip,{title:"Select callbacks to disable for this key. Disabled callbacks will not receive any logging data.",children:(0,t.jsx)(r.InfoCircleOutlined,{className:"text-gray-400 cursor-help"})})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Disabled Callbacks"}),(0,t.jsx)(s.Select,{mode:"multiple",placeholder:"Select callbacks to disable",value:f,onChange:e=>{let t=(0,p.mapDisplayToInternalNames)(e);b?.(t)},style:{width:"100%"},optionLabelProp:"label",children:j.map(e=>{let s=(0,g.resolveLogoSrc)(p.callbackInfo[e]?.logo),a=p.callbackInfo[e]?.description;return(0,t.jsx)(x,{value:e,label:e,children:(0,t.jsx)(l.Tooltip,{title:a,placement:"right",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[s&&(0,t.jsx)("img",{src:s,alt:e,className:"w-4 h-4 object-contain",onError:t=>{let s=t.target,l=s.parentElement;if(l){let t=document.createElement("div");t.className="w-4 h-4 rounded-full bg-gray-200 flex items-center justify-center text-xs",t.textContent=e.charAt(0),l.replaceChild(t,s)}}}),(0,t.jsx)("span",{children:e})]})})},e)})}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Select callbacks that should be disabled for this key. These callbacks will not receive any logging data."})]})]}),(0,t.jsx)(a.Divider,{}),(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)(u.CogIcon,{className:"w-5 h-5 text-blue-500"}),(0,t.jsx)("span",{className:"text-base font-semibold text-gray-800",children:"Logging Integrations"}),(0,t.jsx)(l.Tooltip,{title:"Configure callback logging integrations for this team.",children:(0,t.jsx)(r.InfoCircleOutlined,{className:"text-gray-400 cursor-help"})})]}),(0,t.jsx)(i.Button,{variant:"secondary",onClick:()=>{v([...e,{callback_name:"",callback_type:"success",callback_vars:{}}])},icon:d.PlusIcon,size:"sm",className:"hover:border-blue-400 hover:text-blue-500",type:"button",children:"Add Integration"})]}),(0,t.jsx)("div",{className:"space-y-4",children:e.map((a,d)=>{let u=a.callback_name?Object.entries(p.callback_map).find(([e,t])=>t===a.callback_name)?.[0]:void 0,m=u?(0,g.resolveLogoSrc)(p.callbackInfo[u]?.logo):null;return(0,t.jsxs)(n.Card,{className:"border border-gray-200 shadow-xs hover:shadow-md transition-shadow duration-200",decoration:"top",decorationColor:"blue",children:[(0,t.jsxs)("div",{className:"flex justify-between items-start mb-4",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[m&&(0,t.jsx)("img",{src:m,alt:u,className:"w-5 h-5 object-contain"}),(0,t.jsxs)("span",{className:"text-sm font-medium",children:[u||"New Integration"," Configuration"]})]}),(0,t.jsx)(i.Button,{variant:"light",onClick:()=>{v(e.filter((e,t)=>t!==d))},icon:c.TrashIcon,size:"xs",color:"red",className:"hover:bg-red-50",type:"button",children:"Remove"})]}),(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Integration Type"}),(0,t.jsx)(s.Select,{value:u,placeholder:"Select integration",onChange:e=>w(d,"callback_name",e),className:"w-full",optionLabelProp:"label",children:_.map(e=>{let s=(0,g.resolveLogoSrc)(p.callbackInfo[e]?.logo),a=p.callbackInfo[e]?.description;return(0,t.jsx)(x,{value:e,label:e,children:(0,t.jsx)(l.Tooltip,{title:a,placement:"right",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[s&&(0,t.jsx)("img",{src:s,alt:e,className:"w-4 h-4 object-contain",onError:t=>{let s=t.target,l=s.parentElement;if(l){let t=document.createElement("div");t.className="w-4 h-4 rounded-full bg-gray-200 flex items-center justify-center text-xs",t.textContent=e.charAt(0),l.replaceChild(t,s)}}}),(0,t.jsx)("span",{children:e})]})})},e)})})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Event Type"}),(0,t.jsxs)(s.Select,{value:a.callback_type,onChange:e=>w(d,"callback_type",e),className:"w-full",children:[(0,t.jsx)(x,{value:"success",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("div",{className:"w-2 h-2 bg-green-500 rounded-full"}),(0,t.jsx)("span",{children:"Success Only"})]})}),(0,t.jsx)(x,{value:"failure",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("div",{className:"w-2 h-2 bg-red-500 rounded-full"}),(0,t.jsx)("span",{children:"Failure Only"})]})}),(0,t.jsx)(x,{value:"success_and_failure",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("div",{className:"w-2 h-2 bg-blue-500 rounded-full"}),(0,t.jsx)("span",{children:"Success & Failure"})]})})]})]})]}),((e,s)=>{if(!e.callback_name)return null;let a=Object.entries(p.callback_map).find(([t,s])=>s===e.callback_name)?.[0];if(!a)return null;let i=p.callbackInfo[a]?.dynamic_params||{};return 0===Object.keys(i).length?null:(0,t.jsxs)("div",{className:"mt-6 pt-4 border-t border-gray-100",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2 mb-4",children:[(0,t.jsx)("div",{className:"w-3 h-3 bg-blue-100 rounded-full flex items-center justify-center",children:(0,t.jsx)("div",{className:"w-1.5 h-1.5 bg-blue-500 rounded-full"})}),(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Integration Parameters"})]}),(0,t.jsx)("div",{className:"grid grid-cols-1 gap-4",children:Object.entries(i).map(([a,i])=>(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 capitalize flex items-center space-x-1",children:[(0,t.jsx)("span",{children:a.replace(/_/g," ")}),(0,t.jsx)(l.Tooltip,{title:`Environment variable reference recommended: os.environ/${a.toUpperCase()}`,children:(0,t.jsx)(r.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})}),"password"===i&&(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-medium bg-yellow-100 text-yellow-800",children:"Sensitive"}),"number"===i&&(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-medium bg-yellow-100 text-yellow-800",children:"Number"})]}),"number"===i&&(0,t.jsx)("span",{className:"text-xs text-gray-500",children:"Value must be between 0 and 1"}),"number"===i?(0,t.jsx)(h.default,{step:.01,width:400,placeholder:`os.environ/${a.toUpperCase()}`,value:e.callback_vars[a]||"",onChange:e=>N(s,a,e.target.value)}):(0,t.jsx)(o.TextInput,{type:"password"===i?"password":"text",placeholder:`os.environ/${a.toUpperCase()}`,value:e.callback_vars[a]||"",onChange:e=>N(s,a,e.target.value)})]},a))})]})})(a,d)]})]},d)})}),0===e.length&&(0,t.jsxs)("div",{className:"text-center py-12 text-gray-500 border-2 border-dashed border-gray-200 rounded-lg bg-gray-50/50",children:[(0,t.jsx)(u.CogIcon,{className:"w-12 h-12 text-gray-300 mb-3 mx-auto"}),(0,t.jsx)("div",{className:"text-base font-medium mb-1",children:"No logging integrations configured"}),(0,t.jsx)("div",{className:"text-sm text-gray-400",children:'Click "Add Integration" to configure logging for this team'})]})]})}])},651904,e=>{"use strict";var t=e.i(843476),s=e.i(599724),l=e.i(266484);e.s(["default",0,function({value:e,onChange:a,premiumUser:r=!1,disabledCallbacks:i=[],onDisabledCallbacksChange:n}){return r?(0,t.jsx)(l.default,{value:e,onChange:a,disabledCallbacks:i,onDisabledCallbacksChange:n}):(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex flex-wrap gap-2 mb-3",children:[(0,t.jsx)("div",{className:"inline-flex items-center px-3 py-1.5 rounded-lg bg-green-50 border border-green-200 text-green-800 text-sm font-medium opacity-50",children:"✨ langfuse-logging"}),(0,t.jsx)("div",{className:"inline-flex items-center px-3 py-1.5 rounded-lg bg-green-50 border border-green-200 text-green-800 text-sm font-medium opacity-50",children:"✨ datadog-logging"})]}),(0,t.jsx)("div",{className:"p-3 bg-yellow-50 border border-yellow-200 rounded-lg",children:(0,t.jsxs)(s.Text,{className:"text-sm text-yellow-800",children:["Setting Key/Team logging settings is a LiteLLM Enterprise feature. Global Logging Settings are available for all free users. Get a trial key"," ",(0,t.jsx)("a",{href:"https://www.litellm.ai/#pricing",target:"_blank",rel:"noopener noreferrer",className:"underline",children:"here"}),"."]})})]})}])},939510,e=>{"use strict";var t=e.i(843476),s=e.i(808613),l=e.i(199133),a=e.i(592968),r=e.i(827252);let{Option:i}=l.Select;e.s(["default",0,({type:e,name:n,showDetailedDescriptions:o=!0,className:d="",initialValue:c=null,form:u,onChange:m})=>{let p=e.toUpperCase(),g=e.toLowerCase(),h=`Select 'guaranteed_throughput' to prevent overallocating ${p} limit when the key belongs to a Team with specific ${p} limits.`;return(0,t.jsx)(s.Form.Item,{label:(0,t.jsxs)("span",{children:[p," Rate Limit Type"," ",(0,t.jsx)(a.Tooltip,{title:h,children:(0,t.jsx)(r.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:n,initialValue:c,className:d,children:(0,t.jsx)(l.Select,{defaultValue:o?"default":void 0,placeholder:"Select rate limit type",style:{width:"100%"},optionLabelProp:o?"label":void 0,onChange:e=>{u&&u.setFieldValue(n,e),m&&m(e)},children:o?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i,{value:"best_effort_throughput",label:"Default",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)("div",{style:{fontWeight:500},children:"Default"}),(0,t.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["Best effort throughput - no error if we're overallocating ",g," (Team/Key Limits checked at runtime)."]})]})}),(0,t.jsx)(i,{value:"guaranteed_throughput",label:"Guaranteed throughput",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)("div",{style:{fontWeight:500},children:"Guaranteed throughput"}),(0,t.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["Guaranteed throughput - raise an error if we're overallocating ",g," (also checks model-specific limits)"]})]})}),(0,t.jsx)(i,{value:"dynamic",label:"Dynamic",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)("div",{style:{fontWeight:500},children:"Dynamic"}),(0,t.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["If the key has a set ",p," (e.g. 2 ",p,") and there are no 429 errors, it can dynamically exceed the limit when the model being called is not erroring."]})]})})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i,{value:"best_effort_throughput",children:"Best effort throughput"}),(0,t.jsx)(i,{value:"guaranteed_throughput",children:"Guaranteed throughput"}),(0,t.jsx)(i,{value:"dynamic",children:"Dynamic"})]})})})}])},460285,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(404206),a=e.i(723731),r=e.i(653824),i=e.i(881073),n=e.i(197647),o=e.i(602869),d=e.i(158392),c=e.i(419470),u=e.i(695411);let m=(0,s.forwardRef)(({accessToken:e,value:m,onChange:p,modelData:g},h)=>{let[x,y]=(0,s.useState)({routerSettings:{},selectedStrategy:null,enableTagFiltering:!1}),[f,b]=(0,s.useState)([]),[_,j]=(0,s.useState)([]),[v,w]=(0,s.useState)([]),[N,k]=(0,s.useState)([]),[S,C]=(0,s.useState)({}),[T,I]=(0,s.useState)({}),A=(0,s.useRef)(!1),L=(0,s.useRef)(null);(0,s.useEffect)(()=>{let e=m?.router_settings?JSON.stringify({routing_strategy:m.router_settings.routing_strategy,fallbacks:m.router_settings.fallbacks,enable_tag_filtering:m.router_settings.enable_tag_filtering}):null;if(A.current&&e===L.current){A.current=!1;return}if(A.current&&e!==L.current&&(A.current=!1),e!==L.current)if(L.current=e,m?.router_settings){let e=m.router_settings,{fallbacks:t,...s}=e;y({routerSettings:s,selectedStrategy:e.routing_strategy||null,enableTagFiltering:e.enable_tag_filtering??!1});let l=e.fallbacks||[];b(l),j(l&&0!==l.length?l.map((e,t)=>{let[s,l]=Object.entries(e)[0];return{id:(t+1).toString(),primaryModel:s||null,fallbackModels:l||[]}}):[{id:"1",primaryModel:null,fallbackModels:[]}])}else y({routerSettings:{},selectedStrategy:null,enableTagFiltering:!1}),b([]),j([{id:"1",primaryModel:null,fallbackModels:[]}])},[m]),(0,s.useEffect)(()=>{e&&(0,o.getRouterSettingsCall)(e).then(e=>{if(e.fields){let t={};e.fields.forEach(e=>{t[e.field_name]={ui_field_name:e.ui_field_name,field_description:e.field_description,options:e.options,link:e.link}}),C(t);let s=e.fields.find(e=>"routing_strategy"===e.field_name);s?.options&&k(s.options),e.routing_strategy_descriptions&&I(e.routing_strategy_descriptions)}})},[e]),(0,s.useEffect)(()=>{e&&(async()=>{try{let t=await (0,u.fetchAvailableModels)(e);w(t)}catch(e){console.error("Error fetching model info for fallbacks:",e)}})()},[e]);let F=()=>{let e=new Set(["allowed_fails","cooldown_time","num_retries","timeout","retry_after"]),t=new Set(["model_group_alias","retry_policy"]),s=Object.fromEntries(Object.entries({...x.routerSettings,enable_tag_filtering:x.enableTagFiltering,routing_strategy:x.selectedStrategy,fallbacks:f.length>0?f:null}).map(([s,l])=>{if("routing_strategy_args"!==s&&"routing_strategy"!==s&&"enable_tag_filtering"!==s&&"fallbacks"!==s){let a=document.querySelector(`input[name="${s}"]`);if(a){if(void 0!==a.value&&""!==a.value){let r=((s,l,a)=>{if(null==l)return a;let r=String(l).trim();if(""===r||"null"===r.toLowerCase())return null;if(e.has(s)){let e=Number(r);return Number.isNaN(e)?a:e}if(t.has(s)){if(""===r)return null;try{return JSON.parse(r)}catch{return a}}return"true"===r.toLowerCase()||"false"!==r.toLowerCase()&&r})(s,a.value,l);return[s,r]}return[s,null]}}else if("routing_strategy"===s)return[s,x.selectedStrategy];else if("enable_tag_filtering"===s)return[s,x.enableTagFiltering];else if("fallbacks"===s)return[s,f.length>0?f:null];else if("routing_strategy_args"===s&&"latency-based-routing"===x.selectedStrategy){let e=document.querySelector('input[name="lowest_latency_buffer"]'),t=document.querySelector('input[name="ttl"]'),s={};return e?.value&&(s.lowest_latency_buffer=Number(e.value)),t?.value&&(s.ttl=Number(t.value)),["routing_strategy_args",Object.keys(s).length>0?s:null]}return[s,l]}).filter(e=>null!=e)),l=(e,t=!1)=>null==e||"object"==typeof e&&!Array.isArray(e)&&0===Object.keys(e).length||t&&("number"!=typeof e||Number.isNaN(e))?null:e;return{routing_strategy:l(s.routing_strategy),allowed_fails:l(s.allowed_fails,!0),cooldown_time:l(s.cooldown_time,!0),num_retries:l(s.num_retries,!0),timeout:l(s.timeout,!0),retry_after:l(s.retry_after,!0),fallbacks:f.length>0?f:null,context_window_fallbacks:l(s.context_window_fallbacks),retry_policy:l(s.retry_policy),model_group_alias:l(s.model_group_alias),enable_tag_filtering:x.enableTagFiltering,routing_strategy_args:l(s.routing_strategy_args)}};(0,s.useEffect)(()=>{if(!p)return;let e=setTimeout(()=>{A.current=!0,p({router_settings:F()})},100);return()=>clearTimeout(e)},[x,f]);let M=Array.from(new Set(v.map(e=>e.model_group))).sort();return((0,s.useImperativeHandle)(h,()=>({getValue:()=>({router_settings:F()})})),e)?(0,t.jsx)("div",{className:"w-full",children:(0,t.jsxs)(r.TabGroup,{className:"w-full",children:[(0,t.jsxs)(i.TabList,{variant:"line",defaultValue:"1",className:"px-8 pt-4",children:[(0,t.jsx)(n.Tab,{value:"1",children:"Loadbalancing"}),(0,t.jsx)(n.Tab,{value:"2",children:"Fallbacks"})]}),(0,t.jsxs)(a.TabPanels,{className:"px-8 py-6",children:[(0,t.jsx)(l.TabPanel,{children:(0,t.jsx)(d.default,{value:x,onChange:y,routerFieldsMetadata:S,availableRoutingStrategies:N,routingStrategyDescriptions:T})}),(0,t.jsx)(l.TabPanel,{children:(0,t.jsx)(c.FallbackSelectionForm,{groups:_,onGroupsChange:e=>{j(e),b(e.filter(e=>e.primaryModel&&e.fallbackModels.length>0).map(e=>({[e.primaryModel]:e.fallbackModels})))},availableModels:M,maxGroups:5})})]})]})}):null});m.displayName="RouterSettingsAccordion",e.s(["default",0,m])},363256,e=>{"use strict";var t=e.i(843476),s=e.i(199133);let{Text:l}=e.i(898586).Typography;e.s(["default",0,({organizations:e,value:a,onChange:r,disabled:i,loading:n,style:o})=>(0,t.jsx)(s.Select,{showSearch:!0,placeholder:"All Organizations",value:a,onChange:r,disabled:i,loading:n,allowClear:!0,style:{minWidth:280,...o},filterOption:(t,s)=>{if(!s)return!1;let l=e?.find(e=>e.organization_id===s.key);if(!l)return!1;let a=t.toLowerCase().trim(),r=(l.organization_alias||"").toLowerCase(),i=(l.organization_id||"").toLowerCase();return r.includes(a)||i.includes(a)},children:e?.map(e=>(0,t.jsxs)(s.Select.Option,{value:e.organization_id,children:[(0,t.jsx)("span",{className:"font-medium",children:e.organization_alias})," ",(0,t.jsxs)(l,{type:"secondary",children:["(",e.organization_id,")"]})]},e.organization_id))})])},575260,e=>{"use strict";var t=e.i(843476),s=e.i(199133),l=e.i(482725),a=e.i(56456);e.s(["default",0,({projects:e,value:r,onChange:i,disabled:n,loading:o,teamId:d})=>{let c=d?e?.filter(e=>e.team_id===d):e;return(0,t.jsx)(s.Select,{showSearch:!0,placeholder:"Search or select a project",value:r,onChange:i,disabled:n,loading:o,allowClear:!0,notFoundContent:o?(0,t.jsx)(l.Spin,{indicator:(0,t.jsx)(a.LoadingOutlined,{spin:!0}),size:"small"}):void 0,filterOption:(e,t)=>{if(!t)return!1;let s=c?.find(e=>e.project_id===t.key);if(!s)return!1;let l=e.toLowerCase().trim(),a=(s.project_alias||"").toLowerCase(),r=(s.project_id||"").toLowerCase();return a.includes(l)||r.includes(l)},optionFilterProp:"children",children:!o&&c?.map(e=>(0,t.jsxs)(s.Select.Option,{value:e.project_id,children:[(0,t.jsx)("span",{className:"font-medium",children:e.project_alias||e.project_id})," ",(0,t.jsxs)("span",{className:"text-gray-500",children:["(",e.project_id,")"]})]},e.project_id))})}])},128233,319312,e=>{"use strict";var t=e.i(843476),s=e.i(464571),l=e.i(199133),a=e.i(592968),r=e.i(425063),i=e.i(107233),n=e.i(37727),o=e.i(271645);e.s(["BudgetFallbacksEditor",0,function({value:e,onChange:d,availableModels:c}){let[u,m]=(0,o.useState)(()=>{let t;return 0===(t=Object.keys(e)).length?[]:t.map((t,s)=>({id:String(s+1),primaryModel:t,fallbackModels:e[t]}))}),p=e=>{m(e),d(Object.fromEntries(e.filter(e=>null!==e.primaryModel&&e.fallbackModels.length>0).map(e=>[e.primaryModel,e.fallbackModels])))},g=()=>{p([...u,{id:Date.now().toString(),primaryModel:null,fallbackModels:[]}])},h=(e,t)=>{p(u.map(s=>s.id===e?{...s,...t}:s))},x=new Set(u.map(e=>e.primaryModel).filter(Boolean));return 0===u.length?(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-xs text-gray-500 mb-2",children:"When a model exceeds its per-model budget, requests automatically reroute to fallback models"}),(0,t.jsx)(s.Button,{size:"small",onClick:g,icon:(0,t.jsx)(i.Plus,{className:"w-3 h-3"}),children:"Add Budget Fallback"})]}):(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"When a model exceeds its per-model budget, requests automatically reroute to fallback models"}),u.map(e=>{let s=c.filter(t=>t===e.primaryModel||!x.has(t)),i=c.filter(t=>t!==e.primaryModel);return(0,t.jsxs)("div",{className:"relative rounded-lg border border-gray-200 bg-gray-50 p-4",children:[(0,t.jsx)("button",{type:"button",onClick:()=>{var t;return t=e.id,void p(u.filter(e=>e.id!==t))},className:"absolute top-2 right-2 text-gray-400 hover:text-red-500 transition-colors p-1",children:(0,t.jsx)(n.X,{className:"w-4 h-4"})}),(0,t.jsxs)("div",{className:"mb-3",children:[(0,t.jsx)("label",{className:"block text-xs font-medium text-gray-600 mb-1",children:"Primary Model"}),(0,t.jsx)(l.Select,{className:"w-full",placeholder:"Select model",value:e.primaryModel,onChange:t=>{let s=e.fallbackModels.filter(e=>e!==t);h(e.id,{primaryModel:t,fallbackModels:s})},showSearch:!0,filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase()),options:s.map(e=>({label:e,value:e})),getPopupContainer:e=>e.parentElement||document.body})]}),(0,t.jsx)("div",{className:"flex items-center justify-center -my-1 mb-2",children:(0,t.jsxs)("div",{className:"bg-amber-50 text-amber-600 px-3 py-0.5 rounded-full text-[10px] font-bold border border-amber-100 flex items-center gap-1",children:[(0,t.jsx)(r.ArrowDown,{className:"w-3 h-3"}),"IF BUDGET EXCEEDED, TRY"]})}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs font-medium text-gray-600 mb-1",children:"Fallback Models"}),(0,t.jsx)(l.Select,{mode:"multiple",className:"w-full",placeholder:e.primaryModel?"Select fallback models":"Select a primary model first",value:e.fallbackModels,onChange:t=>h(e.id,{fallbackModels:t}),disabled:!e.primaryModel,showSearch:!0,filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase()),options:i.map(e=>({label:e,value:e})),getPopupContainer:e=>e.parentElement||document.body,maxTagCount:"responsive",maxTagPlaceholder:e=>(0,t.jsx)(a.Tooltip,{styles:{root:{pointerEvents:"none"}},title:e.map(({value:e})=>e).join(", "),children:(0,t.jsxs)("span",{children:["+",e.length," more"]})})}),e.fallbackModels.length>1&&(0,t.jsx)("div",{className:"text-[10px] text-gray-400 mt-1 ml-1",children:"Tried in order; first model still within its own budget is used"})]})]},e.id)}),(0,t.jsx)(s.Button,{size:"small",onClick:g,icon:(0,t.jsx)(i.Plus,{className:"w-3 h-3"}),children:"Add Budget Fallback"})]})}],128233);var d=e.i(28651);let c=[{value:"1h",label:"Hourly",resetHint:"Resets every hour"},{value:"24h",label:"Daily",resetHint:"Resets daily at midnight UTC"},{value:"7d",label:"Weekly",resetHint:"Resets every Sunday at midnight UTC"},{value:"30d",label:"Monthly",resetHint:"Resets on the 1st of every month at midnight UTC"}];e.s(["BudgetWindowsEditor",0,function({value:e,onChange:a}){let r=(t,s,l)=>{a(e.map((e,a)=>a===t?{...e,[s]:l}:e))};return(0,t.jsxs)("div",{children:[e.map((i,n)=>{let o=c.find(e=>e.value===i.budget_duration)?.resetHint;return(0,t.jsxs)("div",{style:{marginBottom:12},children:[(0,t.jsxs)("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[(0,t.jsx)(l.Select,{value:i.budget_duration,onChange:e=>r(n,"budget_duration",e),style:{width:130},options:c.map(e=>({value:e.value,label:e.label}))}),(0,t.jsx)(d.InputNumber,{step:.01,min:0,precision:2,value:i.max_budget??void 0,onChange:e=>r(n,"max_budget",e??null),placeholder:"Max spend ($)",style:{width:160},prefix:"$"}),(0,t.jsx)(s.Button,{type:"text",danger:!0,size:"small",onClick:()=>{a(e.filter((e,t)=>t!==n))},style:{padding:"0 4px"},children:"✕"})]}),o&&(0,t.jsxs)("div",{style:{fontSize:11,color:"#888",marginTop:3,marginLeft:2},children:["↻ ",o]})]},n)}),(0,t.jsx)(s.Button,{size:"small",onClick:t=>{t.preventDefault(),a([...e,{budget_duration:"24h",max_budget:null}])},children:"+ Add Budget Window"})]})}],319312)},390605,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(602869),a=e.i(599724),r=e.i(482725),i=e.i(91739),n=e.i(500727),o=e.i(531516),d=e.i(696609);e.s(["default",0,({accessToken:e,selectedServers:c,toolPermissions:u,onChange:m,disabled:p=!1})=>{let{data:g=[]}=(0,n.useMCPServers)(),[h,x]=(0,s.useState)({}),[y,f]=(0,s.useState)({}),[b,_]=(0,s.useState)({}),[j,v]=(0,s.useState)({}),w=(0,s.useRef)(u);(0,s.useEffect)(()=>{w.current=u},[u]);let N=(0,s.useMemo)(()=>0===c.length?[]:g.filter(e=>c.includes(e.server_id)),[g,c]),k=async(e,t)=>{f(t=>({...t,[e]:!0})),_(t=>({...t,[e]:""}));try{let s=await (0,l.listMCPTools)(t,e);if(s.error)_(t=>({...t,[e]:s.message||"Failed to fetch tools"})),x(t=>({...t,[e]:[]}));else{let t=s.tools||[];x(s=>({...s,[e]:t}));let l=w.current;if(!l[e]&&t.length>0){let s=t.filter(e=>"delete"!==(0,d.classifyToolOp)(e.name,e.description||"")).map(e=>e.name);m({...l,[e]:s})}}}catch(t){console.error(`Error fetching tools for server ${e}:`,t),_(t=>({...t,[e]:"Failed to fetch tools"})),x(t=>({...t,[e]:[]}))}finally{f(t=>({...t,[e]:!1}))}};(0,s.useEffect)(()=>{N.forEach(t=>{h[t.server_id]||y[t.server_id]||k(t.server_id,e)})},[N,e]);let S=(e,t)=>{m({...u,[e]:t})};return 0===c.length?null:(0,t.jsx)("div",{className:"space-y-4",children:N.map(e=>{let s=e.server_name||e.alias||e.server_id,l=h[e.server_id]||[],n=u[e.server_id]||[],d=y[e.server_id],c=b[e.server_id],g=j[e.server_id]??"crud";return(0,t.jsxs)("div",{className:"border rounded-lg bg-gray-50",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between p-4 border-b bg-white rounded-t-lg",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(a.Text,{className:"font-semibold text-gray-900",children:s}),e.description&&(0,t.jsx)(a.Text,{className:"text-sm text-gray-500",children:e.description})]}),(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[!p&&l.length>0&&(0,t.jsx)(i.Radio.Group,{value:g,onChange:t=>v(s=>({...s,[e.server_id]:t.target.value})),size:"small",optionType:"button",buttonStyle:"solid",options:[{label:"Risk Groups",value:"crud"},{label:"Flat List",value:"flat"}]}),!p&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("button",{type:"button",className:"text-sm text-blue-600 hover:text-blue-700 font-medium",onClick:()=>{var t;let s;return s=h[t=e.server_id]||[],void m({...u,[t]:s.map(e=>e.name)})},disabled:d,children:"Select All"}),(0,t.jsx)("button",{type:"button",className:"text-sm text-blue-600 hover:text-blue-700 font-medium",onClick:()=>{var t;return t=e.server_id,void m({...u,[t]:[]})},disabled:d,children:"Deselect All"})]})]})]}),(0,t.jsxs)("div",{className:"p-4",children:[d&&(0,t.jsxs)("div",{className:"flex items-center justify-center py-8",children:[(0,t.jsx)(r.Spin,{size:"large"}),(0,t.jsx)(a.Text,{className:"ml-3 text-gray-500",children:"Loading tools..."})]}),c&&!d&&(0,t.jsxs)("div",{className:"p-4 bg-red-50 border border-red-200 rounded-lg text-center",children:[(0,t.jsx)(a.Text,{className:"text-red-600 font-medium",children:"Unable to load tools"}),(0,t.jsx)(a.Text,{className:"text-sm text-red-500 mt-1",children:c})]}),!d&&!c&&l.length>0&&"crud"===g&&(0,t.jsx)(o.default,{tools:l,value:u[e.server_id]?n:void 0,onChange:t=>S(e.server_id,t),readOnly:p}),!d&&!c&&l.length>0&&"flat"===g&&(0,t.jsx)("div",{className:"space-y-2",children:l.map(s=>{let l=n.includes(s.name);return(0,t.jsxs)("div",{className:"flex items-start gap-2",children:[(0,t.jsx)("input",{type:"checkbox",checked:l,onChange:()=>{if(p)return;let t=l?n.filter(e=>e!==s.name):[...n,s.name];S(e.server_id,t)},disabled:p,className:"mt-0.5"}),(0,t.jsx)("div",{className:"flex-1 min-w-0",children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(a.Text,{className:"font-medium text-gray-900",children:s.name}),(0,t.jsxs)(a.Text,{className:"text-sm text-gray-500",children:["- ",s.description||"No description"]})]})})]},s.name)})}),!d&&!c&&0===l.length&&(0,t.jsx)("div",{className:"text-center py-6",children:(0,t.jsx)(a.Text,{className:"text-gray-500",children:"No tools available"})})]})]},e.server_id)})})}])},364769,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(237016),a=e.i(464571),r=e.i(888259);e.s(["default",0,({apiKey:e})=>{let[i,n]=(0,s.useState)(!1);return(0,t.jsxs)("div",{children:[(0,t.jsxs)("p",{className:"mb-2",children:["Please save this secret key somewhere safe and accessible. For security reasons,"," ",(0,t.jsx)("b",{children:"you will not be able to view it again"})," through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]}),(0,t.jsx)("p",{className:"text-sm text-gray-600 mt-3 mb-1",children:"Virtual Key:"}),(0,t.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,t.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal",margin:0},children:e})}),(0,t.jsx)(l.CopyToClipboard,{text:e,onCopy:()=>{n(!0),r.default.success("Key copied to clipboard"),setTimeout(()=>n(!1),2e3)},children:(0,t.jsx)(a.Button,{type:"primary",style:{marginTop:12},children:i?"Copied!":"Copy Virtual Key"})})]})}])},702597,e=>{"use strict";var t=e.i(843476),s=e.i(207082),l=e.i(109799),a=e.i(510674),r=e.i(109034),i=e.i(292639),n=e.i(135214),o=e.i(500330),d=e.i(827252),c=e.i(912598),u=e.i(677667),m=e.i(130643),p=e.i(898667),g=e.i(994388),h=e.i(309426),x=e.i(350967),y=e.i(599724),f=e.i(779241),b=e.i(629569),_=e.i(464571),j=e.i(808613),v=e.i(311451),w=e.i(212931),N=e.i(91739),k=e.i(199133),S=e.i(790848),C=e.i(262218),T=e.i(592968),I=e.i(898586),A=e.i(374009),L=e.i(271645),F=e.i(708347),M=e.i(552130),O=e.i(557662),E=e.i(9314),P=e.i(860585),B=e.i(82946),$=e.i(392110),R=e.i(533882),D=e.i(844565),V=e.i(651904),z=e.i(939510),U=e.i(460285),G=e.i(663435),K=e.i(363256),q=e.i(575260),W=e.i(371455),H=e.i(128233),Q=e.i(319312),J=e.i(355619),Y=e.i(75921),X=e.i(234713),Z=e.i(390605),ee=e.i(727749),et=e.i(602869),es=e.i(364769),el=e.i(435451),ea=e.i(916940);let{Option:er}=k.Select,ei=async(e,t,s,l)=>{try{if(null===e||null===t)return[];if(null!==s)return(await (0,et.modelAvailableCall)(s,e,t,!0,l,!0)).data.map(e=>e.id);return[]}catch(e){return console.error("Error fetching user models:",e),[]}},en=async(e,t,s,l)=>{try{if(null===e||null===t)return;if(null!==s){let a=(await (0,et.modelAvailableCall)(s,e,t)).data.map(e=>e.id);l(a)}}catch(e){console.error("Error fetching user models:",e)}};e.s(["default",0,({team:e,teams:eo,data:ed,addKey:ec,autoOpenCreate:eu,prefillData:em})=>{let{accessToken:ep,userId:eg,userRole:eh,premiumUser:ex}=(0,n.default)(),ey=ex||null!=eh&&F.rolesWithWriteAccess.includes(eh),{data:ef,isLoading:eb}=(0,l.useOrganizations)(),{data:e_,isLoading:ej}=(0,a.useProjects)(),{data:ev}=(0,i.useUISettings)(),{data:ew}=(0,r.useTags)(),eN=!!ev?.values?.enable_projects_ui,ek=!!ev?.values?.disable_custom_api_keys,eS=ew?Object.values(ew).map(e=>({value:e.name,label:e.name})):[],eC=(0,c.useQueryClient)(),[eT]=j.Form.useForm(),[eI,eA]=(0,L.useState)(!1),[eL,eF]=(0,L.useState)(null),[eM,eO]=(0,L.useState)(null),[eE,eP]=(0,L.useState)([]),[eB,e$]=(0,L.useState)([]),[eR,eD]=(0,L.useState)("you"),[eV,ez]=(0,L.useState)(!1),[eU,eG]=(0,L.useState)(null),[eK,eq]=(0,L.useState)([]),[eW,eH]=(0,L.useState)([]),[eQ,eJ]=(0,L.useState)([]),[eY,eX]=(0,L.useState)([]),[eZ,e0]=(0,L.useState)(e),[e1,e2]=(0,L.useState)(null),[e4,e3]=(0,L.useState)(null),[e5,e6]=(0,L.useState)(!1),[e7,e9]=(0,L.useState)(null),[e8,te]=(0,L.useState)({}),[tt,ts]=(0,L.useState)([]),[tl,ta]=(0,L.useState)(!1),[tr,ti]=(0,L.useState)([]),[tn,to]=(0,L.useState)([]),[td,tc]=(0,L.useState)("llm_api"),[tu,tm]=(0,L.useState)({}),[tp,tg]=(0,L.useState)(!1),[th,tx]=(0,L.useState)("30d"),[ty,tf]=(0,L.useState)(null),[tb,t_]=(0,L.useState)([]),[tj,tv]=(0,L.useState)({}),[tw,tN]=(0,L.useState)(0),[tk,tS]=(0,L.useState)(0),[tC,tT]=(0,L.useState)([]),[tI,tA]=(0,L.useState)(null),tL=()=>{eA(!1),eT.resetFields(),eX([]),to([]),tc("llm_api"),tm({}),tg(!1),tx("30d"),tf(null),tS(e=>e+1),tA(null),e2(null),e3(null),t_([]),tv({}),tN(e=>e+1)},tF=()=>{eA(!1),eF(null),e0(null),eT.resetFields(),eX([]),to([]),tc("llm_api"),tm({}),tg(!1),tx("30d"),tf(null),tS(e=>e+1),tA(null),e2(null),e3(null),t_([]),tv({}),tN(e=>e+1)};(0,L.useEffect)(()=>{eg&&eh&&ep&&en(eg,eh,ep,eP)},[ep,eg,eh]),(0,L.useEffect)(()=>{ep&&(0,et.getAgentsList)(ep).then(e=>tT(e?.agents||[])).catch(()=>tT([]))},[ep]),(0,L.useEffect)(()=>{let e=async()=>{try{let e=(await (0,et.getPoliciesList)(ep)).policies.map(e=>e.policy_name);eH(e)}catch(e){console.error("Failed to fetch policies:",e)}},t=async()=>{try{let e=await (0,et.getPromptsList)(ep);eJ(e.prompts.map(e=>e.prompt_id))}catch(e){console.error("Failed to fetch prompts:",e)}};(async()=>{try{let e=(await (0,et.getGuardrailsList)(ep)).guardrails.map(e=>e.guardrail_name);eq(e)}catch(e){console.error("Failed to fetch guardrails:",e)}})(),e(),t()},[ep]),(0,L.useEffect)(()=>{(async()=>{try{if(ep){let e=sessionStorage.getItem("possibleUserRoles");if(e)te(JSON.parse(e));else{let e=await (0,et.getPossibleUserRoles)(ep);sessionStorage.setItem("possibleUserRoles",JSON.stringify(e)),te(e)}}}catch(e){console.error("Error fetching possible user roles:",e)}})()},[ep]),(0,L.useEffect)(()=>{if(eu&&!eV&&eo&&eh&&F.rolesWithWriteAccess.includes(eh)&&(eA(!0),ez(!0),em)){if(em.owned_by&&("another_user"===em.owned_by&&"Admin"!==eh?eD("you"):eD(em.owned_by)),em.team_id){let e=eo?.find(e=>e.team_id===em.team_id)||null;e&&(e0(e),eT.setFieldsValue({team_id:em.team_id}))}em.key_alias&&eT.setFieldsValue({key_alias:em.key_alias}),em.models&&em.models.length>0&&eG(em.models),em.key_type&&(tc(em.key_type),eT.setFieldsValue({key_type:em.key_type}))}},[eu,em,eo,eV,eT,eh]);let tM=eB.includes("no-default-models")&&!eZ,tO=async e=>{try{let t,l=e?.key_alias??"",a=e?.team_id??null;if((ed?.filter(e=>e.team_id===a).map(e=>e.key_alias)??[]).includes(l))throw Error(`Key alias ${l} already exists for team with ID ${a}, please provide another key alias`);if(ee.default.info("Making API Call"),eA(!0),"you"===eR)e.user_id=eg;else if("agent"===eR){if(!tI)return void ee.default.fromBackend("Please select an agent");e.agent_id=tI}let r={};try{r=JSON.parse(e.metadata||"{}")}catch(e){console.error("Error parsing metadata:",e)}if("service_account"===eR&&(r.service_account_id=e.key_alias),eY.length>0&&(r={...r,logging:eY.filter(e=>e.callback_name)}),tn.length>0){let e=(0,O.mapDisplayToInternalNames)(tn);r={...r,litellm_disabled_callbacks:e}}if(tp&&(e.auto_rotate=!0,e.rotation_interval=th),e.duration&&""!==e.duration.trim()||(e.duration=null),e.metadata=JSON.stringify(r),e.disable_global_guardrails||delete e.disable_global_guardrails,e.allowed_vector_store_ids&&e.allowed_vector_store_ids.length>0&&(e.object_permission={vector_stores:e.allowed_vector_store_ids},delete e.allowed_vector_store_ids),e.allowed_mcp_servers_and_groups&&(e.allowed_mcp_servers_and_groups.servers?.length>0||e.allowed_mcp_servers_and_groups.accessGroups?.length>0)){e.object_permission||(e.object_permission={});let{servers:t,accessGroups:s}=e.allowed_mcp_servers_and_groups;t&&t.length>0&&(e.object_permission.mcp_servers=t),s&&s.length>0&&(e.object_permission.mcp_access_groups=s),delete e.allowed_mcp_servers_and_groups}let i=e.mcp_tool_permissions||{};if(Object.keys(i).length>0&&(e.object_permission||(e.object_permission={}),e.object_permission.mcp_tool_permissions=i),delete e.mcp_tool_permissions,e.allowed_mcp_access_groups&&e.allowed_mcp_access_groups.length>0&&(e.object_permission||(e.object_permission={}),e.object_permission.mcp_access_groups=e.allowed_mcp_access_groups,delete e.allowed_mcp_access_groups),e.allowed_agents_and_groups&&(e.allowed_agents_and_groups.agents?.length>0||e.allowed_agents_and_groups.accessGroups?.length>0)){e.object_permission||(e.object_permission={});let{agents:t,accessGroups:s}=e.allowed_agents_and_groups;t&&t.length>0&&(e.object_permission.agents=t),s&&s.length>0&&(e.object_permission.agent_access_groups=s),delete e.allowed_agents_and_groups}Object.keys(tu).length>0&&(e.aliases=JSON.stringify(tu)),ty?.router_settings&&Object.values(ty.router_settings).some(e=>null!=e&&""!==e)&&(e.router_settings=ty.router_settings);let n=tb.filter(e=>e.budget_duration&&null!==e.max_budget&&void 0!==e.max_budget);n.length>0&&(e.budget_limits=n),Object.keys(tj).length>0&&(e.budget_fallbacks=tj),t="service_account"===eR?await (0,et.keyCreateServiceAccountCall)(ep,e):await (0,et.keyCreateCall)(ep,eg,e),ec(t),eC.invalidateQueries({queryKey:s.keyKeys.lists()}),eF(t.key),eO(t.soft_budget),ee.default.success("Virtual Key Created"),eT.resetFields(),t_([]),tv({}),tN(e=>e+1),localStorage.removeItem("userData"+eg)}catch(t){let e=(e=>{let t;if(!(t=!e||"object"!=typeof e||e instanceof Error?String(e):JSON.stringify(e)).includes("/key/generate")&&!t.includes("KeyManagementRoutes.KEY_GENERATE"))return`Error creating the key: ${e}`;let s=t;try{if(!e||"object"!=typeof e||e instanceof Error){let e=t.match(/\{[\s\S]*\}/);if(e){let t=JSON.parse(e[0]),l=t?.error||t;l?.message&&(s=l.message)}}else{let t=e?.error||e;t?.message&&(s=t.message)}}catch(e){}return t.includes("team_member_permission_error")||s.includes("Team member does not have permissions")?"Team member does not have permission to generate key for this team. Ask your proxy admin to configure the team member permission settings.":`Error creating the key: ${e}`})(t);ee.default.fromBackend(e)}};(0,L.useEffect)(()=>{if(e4){let e=e_?.find(e=>e.project_id===e4);e$(e?.models??[]),eT.setFieldValue("models",[]);return}eg&&eh&&ep&&ei(eg,eh,ep,eZ?.team_id??null).then(e=>{e$(Array.from(new Set([...eZ?.models??[],...e])))}),eU||eT.setFieldValue("models",[]),eT.setFieldValue("allowed_mcp_servers_and_groups",{servers:[],accessGroups:[]})},[eZ,e4,ep,eg,eh,eT]),(0,L.useEffect)(()=>{if(!eU||0===eU.length||!eB||0===eB.length)return;let e=eU.filter(e=>eB.includes(e));e.length>0&&eT.setFieldsValue({models:e}),eG(null)},[eU,eB,eT]),(0,L.useEffect)(()=>{if(!e4||!eo)return;let e=e_?.find(e=>e.project_id===e4);if(!e?.team_id||eZ?.team_id===e.team_id)return;let t=eo.find(t=>t.team_id===e.team_id)||null;t&&(e0(t),eT.setFieldValue("team_id",t.team_id))},[eo,e4,e_]);let tE=async e=>{if(!e)return void ts([]);ta(!0);try{let t=new URLSearchParams;if(t.append("user_email",e),null==ep)return;let s=(await (0,et.userFilterUICall)(ep,t)).map(e=>({label:`${e.user_email} (${e.user_id})`,value:e.user_id,user:e}));ts(s)}catch(e){console.error("Error fetching users:",e),ee.default.fromBackend("Failed to search for users")}finally{ta(!1)}},tP=(0,L.useCallback)((0,A.default)(e=>tE(e),300),[ep]);return(0,t.jsxs)("div",{children:[eh&&F.rolesWithWriteAccess.includes(eh)&&(0,t.jsx)(g.Button,{className:"mx-auto",onClick:()=>eA(!0),"data-testid":"create-key-button",children:"+ Create New Key"}),(0,t.jsx)(w.Modal,{open:eI,width:1e3,footer:null,onOk:tL,onCancel:tF,children:(0,t.jsxs)(j.Form,{form:eT,onFinish:tO,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,t.jsxs)("div",{className:"mb-8",children:[(0,t.jsx)(b.Title,{className:"mb-4",children:"Key Ownership"}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Owned By"," ",(0,t.jsx)(T.Tooltip,{title:"Select who will own this Virtual Key",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),className:"mb-4",children:(0,t.jsxs)(N.Radio.Group,{onChange:e=>eD(e.target.value),value:eR,children:[(0,t.jsx)(N.Radio,{value:"you",children:"You"}),(0,t.jsx)(N.Radio,{value:"service_account",children:"Service Account"}),"Admin"===eh&&(0,t.jsx)(N.Radio,{value:"another_user",children:"Another User"}),(0,t.jsxs)(N.Radio,{value:"agent",children:["Agent ",(0,t.jsx)(C.Tag,{color:"purple",children:"New"})]})]})}),"another_user"===eR&&(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["User ID"," ",(0,t.jsx)(T.Tooltip,{title:"The user who will own this key and be responsible for its usage",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"user_id",className:"mt-4",rules:[{required:"another_user"===eR,message:"Please input the user ID of the user you are assigning the key to"}],children:(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{style:{display:"flex",marginBottom:"8px"},children:[(0,t.jsx)(k.Select,{showSearch:!0,placeholder:"Type email to search for users",filterOption:!1,onSearch:e=>{tP(e)},onSelect:(e,t)=>{let s;return s=t.user,void eT.setFieldsValue({user_id:s.user_id})},options:tt,loading:tl,allowClear:!0,style:{width:"100%"},notFoundContent:tl?"Searching...":"No users found"}),(0,t.jsx)(_.Button,{onClick:()=>e6(!0),style:{marginLeft:"8px"},children:"Create User"})]}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Search by email to find users"})]})}),"agent"===eR&&(0,t.jsxs)("div",{className:"mt-4 p-4 bg-purple-50 border border-purple-200 rounded-md",children:[(0,t.jsx)("div",{className:"mb-3",children:(0,t.jsxs)("span",{className:"text-sm font-medium text-gray-700",children:["Select Agent ",(0,t.jsx)("span",{className:"text-red-500",children:"*"})]})}),(0,t.jsx)(k.Select,{showSearch:!0,placeholder:"Select an agent",style:{width:"100%"},value:tI,onChange:e=>tA(e),filterOption:(e,t)=>t?.label?.toLowerCase().includes(e.toLowerCase()),options:tC.map(e=>({label:e.agent_name||e.agent_id,value:e.agent_id}))}),(0,t.jsx)("div",{className:"text-xs text-gray-500 mt-2",children:"This key will be used by the selected agent to make requests to LiteLLM"})]}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Organization"," ",(0,t.jsx)(T.Tooltip,{title:"The organization this key belongs to. Selecting an organization filters the available teams.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"organization_id",className:"mt-4",children:(0,t.jsx)(K.default,{organizations:ef,loading:eb,disabled:"Admin"!==eh,onChange:e=>{e2(e||null),e0(null),e3(null),eT.setFieldValue("team_id",void 0),eT.setFieldValue("project_id",void 0)}})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Team"," ",(0,t.jsx)(T.Tooltip,{title:"The team this key belongs to, which determines available models and budget limits",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"team_id",initialValue:e?e.team_id:null,className:"mt-4",rules:[{required:"service_account"===eR,message:"Please select a team for the service account"}],help:"service_account"===eR?"required":"",children:(0,t.jsx)(G.default,{disabled:null!==e4,organizationId:e1,onTeamSelect:e=>{e0(e),e3(null),eT.setFieldValue("project_id",void 0),e?.organization_id?(e2(e.organization_id),eT.setFieldValue("organization_id",e.organization_id)):e||(e2(null),eT.setFieldValue("organization_id",void 0))}})}),eN&&(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Project"," ",(0,t.jsx)(T.Tooltip,{title:"Assign this key to a project. Selecting a project will lock the team to the project's team.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"project_id",className:"mt-4",children:(0,t.jsx)(q.default,{projects:e_,teamId:eZ?.team_id,loading:ej||!eo,onChange:e=>{if(!e){e3(null),e0(null),eT.setFieldValue("team_id",void 0);return}e3(e)}})})]}),tM&&(0,t.jsx)("div",{className:"mb-8 p-4 bg-blue-50 border border-blue-200 rounded-md",children:(0,t.jsx)(y.Text,{className:"text-blue-800 text-sm",children:"Please select a team to continue configuring your Virtual Key. If you do not see any teams, please contact your Proxy Admin to either provide you with access to models or to add you to a team."})}),!tM&&(0,t.jsxs)("div",{className:"mb-8",children:[(0,t.jsx)(b.Title,{className:"mb-4",children:"Key Details"}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["you"===eR||"another_user"===eR?"Key Name":"Service Account ID"," ",(0,t.jsx)(T.Tooltip,{title:"you"===eR||"another_user"===eR?"A descriptive name to identify this key":"Unique identifier for this service account",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"key_alias",rules:[{required:!0,message:`Please input a ${"you"===eR?"key name":"service account ID"}`}],help:"required",children:(0,t.jsx)(f.TextInput,{placeholder:""})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Models"," ",(0,t.jsx)(T.Tooltip,{title:"Select which models this key can access. Choose 'All Team Models' to grant access to all models available to the team. Leave empty to allow access to all models.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"models",rules:[],help:"management"===td||"read_only"===td?"Models field is disabled for this key type":"optional - leave empty to allow access to all models",className:"mt-4",children:(0,t.jsxs)(k.Select,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},disabled:"management"===td||"read_only"===td,onChange:e=>{e.includes("all-team-models")&&eT.setFieldsValue({models:["all-team-models"]})},children:[!e4&&(0,t.jsx)(er,{value:"all-team-models",children:"All Team Models"},"all-team-models"),eB.map(e=>(0,t.jsx)(er,{value:e,children:(0,J.getModelDisplayName)(e)},e))]})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Key Type"," ",(0,t.jsx)(T.Tooltip,{title:"Select the type of key to determine what routes and operations this key can access",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"key_type",initialValue:"llm_api",className:"mt-4",children:(0,t.jsxs)(k.Select,{defaultValue:"llm_api",placeholder:"Select key type",style:{width:"100%"},optionLabelProp:"label",onChange:e=>{tc(e),("management"===e||"read_only"===e)&&eT.setFieldsValue({models:[]})},children:[(0,t.jsx)(er,{value:"llm_api",label:"AI APIs",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)(I.Typography.Text,{strong:!0,children:"AI APIs"}),(0,t.jsx)(I.Typography.Paragraph,{type:"secondary",style:{fontSize:11,margin:"2px 0 0"},children:"Can call only AI API routes (chat/completions, embeddings, etc.)"})]})}),(0,t.jsx)(er,{value:"management",label:"Management",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)(I.Typography.Text,{strong:!0,children:"Management"}),(0,t.jsx)(I.Typography.Paragraph,{type:"secondary",style:{fontSize:11,margin:"2px 0 0"},children:"Can call only management routes (user/team/key management)"})]})}),(0,t.jsx)(er,{value:"default",label:"Full Access",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)(I.Typography.Text,{strong:!0,children:"Full Access"}),(0,t.jsx)(I.Typography.Paragraph,{type:"secondary",style:{fontSize:11,margin:"2px 0 0"},children:"Can call all routes (AI APIs, Management, and read-only)"})]})})]})})]}),!tM&&(0,t.jsx)("div",{className:"mb-8",children:(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)(b.Title,{className:"m-0",children:"Optional Settings"})}),(0,t.jsxs)(m.AccordionBody,{children:[(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Max Budget (USD)"," ",(0,t.jsx)(T.Tooltip,{title:"Maximum amount in USD this key can spend. When reached, the key will be blocked from making further requests",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"max_budget",help:`Budget cannot exceed team max budget: $${e?.max_budget!==null&&e?.max_budget!==void 0?e?.max_budget:"unlimited"}`,rules:[{validator:async(t,s)=>{if(s&&e&&null!==e.max_budget&&s>e.max_budget)throw Error(`Budget cannot exceed team max budget: $${(0,o.formatNumberWithCommas)(e.max_budget,4)}`)}}],children:(0,t.jsx)(el.default,{step:.01,precision:2,width:200})}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Reset Budget"," ",(0,t.jsx)(T.Tooltip,{title:"How often the budget should reset. For example, setting 'daily' will reset the budget every 24 hours",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"budget_duration",help:`Team Reset Budget: ${e?.budget_duration!==null&&e?.budget_duration!==void 0?e?.budget_duration:"None"}`,children:(0,t.jsx)(P.default,{onChange:e=>eT.setFieldValue("budget_duration",e)})}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Budget Windows"," ",(0,t.jsx)(T.Tooltip,{title:"Set multiple independent budget windows (e.g., hourly $10 AND monthly $200). Each window tracks spend separately and resets on its own schedule.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),children:(0,t.jsx)(Q.BudgetWindowsEditor,{value:tb,onChange:t_})}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Budget Fallbacks"," ",(0,t.jsx)(T.Tooltip,{title:"When a model exceeds its per-model budget (model_max_budget), requests automatically reroute to fallback models instead of failing. Configure per-model budgets in Advanced Settings.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),children:(0,t.jsx)(H.BudgetFallbacksEditor,{value:tj,onChange:tv,availableModels:eB},tw)}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Tokens per minute Limit (TPM)"," ",(0,t.jsx)(T.Tooltip,{title:"Maximum number of tokens this key can process per minute. Helps control usage and costs",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"tpm_limit",help:`TPM cannot exceed team TPM limit: ${e?.tpm_limit!==null&&e?.tpm_limit!==void 0?e?.tpm_limit:"unlimited"}`,rules:[{validator:async(t,s)=>{if(s&&e&&null!==e.tpm_limit&&s>e.tpm_limit)throw Error(`TPM limit cannot exceed team TPM limit: ${e.tpm_limit}`)}}],children:(0,t.jsx)(el.default,{step:1,width:400})}),(0,t.jsx)(z.default,{type:"tpm",name:"tpm_limit_type",className:"mt-4",initialValue:null,form:eT,showDetailedDescriptions:!0}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Requests per minute Limit (RPM)"," ",(0,t.jsx)(T.Tooltip,{title:"Maximum number of API requests this key can make per minute. Helps prevent abuse and manage load",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"rpm_limit",help:`RPM cannot exceed team RPM limit: ${e?.rpm_limit!==null&&e?.rpm_limit!==void 0?e?.rpm_limit:"unlimited"}`,rules:[{validator:async(t,s)=>{if(s&&e&&null!==e.rpm_limit&&s>e.rpm_limit)throw Error(`RPM limit cannot exceed team RPM limit: ${e.rpm_limit}`)}}],children:(0,t.jsx)(el.default,{step:1,width:400})}),(0,t.jsx)(z.default,{type:"rpm",name:"rpm_limit_type",className:"mt-4",initialValue:null,form:eT,showDetailedDescriptions:!0}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Guardrails"," ",(0,t.jsx)(T.Tooltip,{title:"Apply safety guardrails to this key to filter content or enforce policies",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"guardrails",className:"mt-4",help:ey?"Select existing guardrails or enter new ones":"Premium feature - Upgrade to set guardrails by key",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},disabled:!ey,placeholder:ey?"Select or enter guardrails":"Premium feature - Upgrade to set guardrails by key",options:eK.map(e=>({value:e,label:e}))})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Disable Global Guardrails"," ",(0,t.jsx)(T.Tooltip,{title:"When enabled, this key will bypass any guardrails configured to run on every request (global guardrails)",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"disable_global_guardrails",className:"mt-4",valuePropName:"checked",help:ey?"Bypass global guardrails for this key":"Premium feature - Upgrade to disable global guardrails by key",children:(0,t.jsx)(S.Switch,{disabled:!ey,checkedChildren:"Yes",unCheckedChildren:"No"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Policies"," ",(0,t.jsx)(T.Tooltip,{title:"Apply policies to this key to control guardrails and other settings",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/guardrail_policies",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"policies",className:"mt-4",help:ex?"Select existing policies or enter new ones":"Premium feature - Upgrade to set policies by key",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},disabled:!ex,placeholder:ex?"Select or enter policies":"Premium feature - Upgrade to set policies by key",options:eW.map(e=>({value:e,label:e}))})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Prompts"," ",(0,t.jsx)(T.Tooltip,{title:"Allow this key to use specific prompt templates",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/prompt_management",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"prompts",className:"mt-4",help:ex?"Select existing prompts or enter new ones":"Premium feature - Upgrade to set prompts by key",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},disabled:!ex,placeholder:ex?"Select or enter prompts":"Premium feature - Upgrade to set prompts by key",options:eQ.map(e=>({value:e,label:e}))})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Access Groups"," ",(0,t.jsx)(T.Tooltip,{title:"Assign access groups to this key. Access groups control which models, MCP servers, and agents this key can use",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"access_group_ids",className:"mt-4",help:"Select access groups to assign to this key",children:(0,t.jsx)(E.default,{placeholder:"Select access groups (optional)"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Pass Through Routes"," ",(0,t.jsx)(T.Tooltip,{title:"Allow this key to use specific pass through routes",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/pass_through",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"allowed_passthrough_routes",className:"mt-4",help:ex?"Select existing pass through routes or enter new ones":"Premium feature - Upgrade to set pass through routes by key",children:(0,t.jsx)(D.default,{onChange:e=>eT.setFieldValue("allowed_passthrough_routes",e),value:eT.getFieldValue("allowed_passthrough_routes"),accessToken:ep,placeholder:ex?"Select or enter pass through routes":"Premium feature - Upgrade to set pass through routes by key",disabled:!ex,teamId:eZ?eZ.team_id:null})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Vector Stores"," ",(0,t.jsx)(T.Tooltip,{title:"Select which vector stores this key can access. If none selected, the key will have access to all available vector stores",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"allowed_vector_store_ids",className:"mt-4",help:"Select vector stores this key can access. Leave empty for access to all vector stores",children:(0,t.jsx)(ea.default,{onChange:e=>eT.setFieldValue("allowed_vector_store_ids",e),value:eT.getFieldValue("allowed_vector_store_ids"),accessToken:ep,placeholder:"Select vector stores (optional)"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Metadata"," ",(0,t.jsx)(T.Tooltip,{title:"JSON object with additional information about this key. Used for tracking or custom logic",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"metadata",className:"mt-4",children:(0,t.jsx)(v.Input.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Tags"," ",(0,t.jsx)(T.Tooltip,{title:"Tags for tracking spend and/or doing tag-based routing. Used for analytics and filtering",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"tags",className:"mt-4",help:"Tags for tracking spend and/or doing tag-based routing.",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},placeholder:"Select or enter tags",tokenSeparators:[","],options:eS})}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"MCP Settings"})}),(0,t.jsxs)(m.AccordionBody,{children:[(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed MCP Servers"," ",(0,t.jsx)(T.Tooltip,{title:"Select which MCP servers or access groups this key can access",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"allowed_mcp_servers_and_groups",help:"Select MCP servers or access groups this key can access",children:(0,t.jsx)(Y.default,{onChange:e=>eT.setFieldValue("allowed_mcp_servers_and_groups",e),value:eT.getFieldValue("allowed_mcp_servers_and_groups"),accessToken:ep,teamId:eZ?.team_id??null,placeholder:"Select MCP servers or access groups (optional)",allowNoMcpServers:!0})}),(0,t.jsx)(j.Form.Item,{name:"mcp_tool_permissions",initialValue:{},hidden:!0,children:(0,t.jsx)(v.Input,{type:"hidden"})}),(0,t.jsx)(j.Form.Item,{noStyle:!0,shouldUpdate:(e,t)=>e.allowed_mcp_servers_and_groups!==t.allowed_mcp_servers_and_groups||e.mcp_tool_permissions!==t.mcp_tool_permissions,children:()=>(0,t.jsx)("div",{className:"mt-6",children:(0,t.jsx)(Z.default,{accessToken:ep,selectedServers:(eT.getFieldValue("allowed_mcp_servers_and_groups")?.servers||[]).filter(e=>e!==X.NO_MCP_SERVERS_SENTINEL),toolPermissions:eT.getFieldValue("mcp_tool_permissions")||{},onChange:e=>eT.setFieldsValue({mcp_tool_permissions:e})})})})]})]}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Agent Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Agents"," ",(0,t.jsx)(T.Tooltip,{title:"Select which agents or access groups this key can access",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"allowed_agents_and_groups",help:"Select agents or access groups this key can access",children:(0,t.jsx)(M.default,{onChange:e=>eT.setFieldValue("allowed_agents_and_groups",e),value:eT.getFieldValue("allowed_agents_and_groups"),accessToken:ep,placeholder:"Select agents or access groups (optional)"})})})]}),ex?(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Logging Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(V.default,{value:eY,onChange:eX,premiumUser:!0,disabledCallbacks:tn,onDisabledCallbacksChange:to})})})]}):(0,t.jsx)(T.Tooltip,{title:(0,t.jsxs)("span",{children:["Key-level logging settings is an enterprise feature, get in touch -",(0,t.jsx)("a",{href:"https://www.litellm.ai/enterprise",target:"_blank",children:"https://www.litellm.ai/enterprise"})]}),placement:"top",children:(0,t.jsxs)("div",{style:{position:"relative"},children:[(0,t.jsx)("div",{style:{opacity:.5},children:(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Logging Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(V.default,{value:eY,onChange:eX,premiumUser:!1,disabledCallbacks:tn,onDisabledCallbacksChange:to})})})]})}),(0,t.jsx)("div",{style:{position:"absolute",inset:0,cursor:"not-allowed"}})]})}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Router Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4 w-full",children:(0,t.jsx)(U.default,{accessToken:ep||"",value:ty||void 0,onChange:tf,modelData:eE.length>0?{data:eE.map(e=>({model_name:e}))}:void 0},tk)})})]},`router-settings-accordion-${tk}`),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Model Aliases"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsxs)("div",{className:"mt-4",children:[(0,t.jsx)(y.Text,{className:"text-sm text-gray-600 mb-4",children:"Create custom aliases for models that can be used in API calls. This allows you to create shortcuts for specific models."}),(0,t.jsx)(R.default,{accessToken:ep,initialModelAliases:tu,onAliasUpdate:tm,showExampleConfig:!1})]})})]}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Key Lifecycle"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)($.default,{form:eT,autoRotationEnabled:tp,onAutoRotationChange:tg,rotationInterval:th,onRotationIntervalChange:tx,isCreateMode:!0})})}),(0,t.jsx)(j.Form.Item,{name:"duration",hidden:!0,initialValue:null,children:(0,t.jsx)(v.Input,{})})]}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("b",{children:"Advanced Settings"}),(0,t.jsx)(T.Tooltip,{title:(0,t.jsxs)("span",{children:["Learn more about advanced settings in our"," ",(0,t.jsx)("a",{href:et.proxyBaseUrl?`${et.proxyBaseUrl}/#/key%20management/generate_key_fn_key_generate_post`:"/#/key%20management/generate_key_fn_key_generate_post",target:"_blank",rel:"noopener noreferrer",className:"text-blue-400 hover:text-blue-300",children:"documentation"})]}),children:(0,t.jsx)(d.InfoCircleOutlined,{className:"text-gray-400 hover:text-gray-300 cursor-help"})})]})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)(B.default,{schemaComponent:"GenerateKeyRequest",form:eT,excludedFields:["key_alias","team_id","organization_id","models","duration","metadata","tags","guardrails","max_budget","budget_duration","tpm_limit","rpm_limit",...ek?["key"]:[]]})})]})]})]})}),(0,t.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,t.jsx)(_.Button,{htmlType:"submit",disabled:tM,style:{opacity:tM?.5:1},children:"Create Key"})})]})}),e5&&(0,t.jsx)(w.Modal,{title:"Create New User",open:e5,onCancel:()=>e6(!1),footer:null,width:800,children:(0,t.jsx)(W.CreateUserButton,{userID:eg,accessToken:ep,teams:eo,possibleUIRoles:e8,onUserCreated:e=>{e9(e),eT.setFieldsValue({user_id:e}),e6(!1)},isEmbedded:!0})}),eL&&(0,t.jsx)(w.Modal,{open:eI,onOk:tL,onCancel:tF,footer:null,children:(0,t.jsxs)(x.Grid,{numItems:1,className:"gap-2 w-full",children:[(0,t.jsx)(b.Title,{children:"Save your Key"}),(0,t.jsx)(h.Col,{numColSpan:1,children:null!=eL?(0,t.jsx)(es.default,{apiKey:eL}):(0,t.jsx)(y.Text,{children:"Key being created, this might take 30s"})})]})})]})},"fetchTeamModels",0,ei,"fetchUserModels",0,en],702597)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/025gva_b59p-5.js b/litellm/proxy/_experimental/out/_next/static/chunks/025gva_b59p-5.js new file mode 100644 index 00000000000..c0fe3dcc751 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/025gva_b59p-5.js @@ -0,0 +1,68 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,599724,936325,e=>{"use strict";var o=e.i(95779),r=e.i(444755),l=e.i(673706),n=e.i(271645);let t=n.default.forwardRef((e,t)=>{let{color:a,className:s,children:i}=e;return n.default.createElement("p",{ref:t,className:(0,r.tremorTwMerge)("text-tremor-default",a?(0,l.getColorClassNames)(a,o.colorPalette.text).textColor:(0,r.tremorTwMerge)("text-tremor-content","dark:text-dark-tremor-content"),s)},i)});t.displayName="Text",e.s(["default",0,t],936325),e.s(["Text",0,t],599724)},350967,46757,e=>{"use strict";var o=e.i(290571),r=e.i(444755),l=e.i(673706),n=e.i(271645);let t={0:"grid-cols-none",1:"grid-cols-1",2:"grid-cols-2",3:"grid-cols-3",4:"grid-cols-4",5:"grid-cols-5",6:"grid-cols-6",7:"grid-cols-7",8:"grid-cols-8",9:"grid-cols-9",10:"grid-cols-10",11:"grid-cols-11",12:"grid-cols-12"},a={0:"sm:grid-cols-none",1:"sm:grid-cols-1",2:"sm:grid-cols-2",3:"sm:grid-cols-3",4:"sm:grid-cols-4",5:"sm:grid-cols-5",6:"sm:grid-cols-6",7:"sm:grid-cols-7",8:"sm:grid-cols-8",9:"sm:grid-cols-9",10:"sm:grid-cols-10",11:"sm:grid-cols-11",12:"sm:grid-cols-12"},s={0:"md:grid-cols-none",1:"md:grid-cols-1",2:"md:grid-cols-2",3:"md:grid-cols-3",4:"md:grid-cols-4",5:"md:grid-cols-5",6:"md:grid-cols-6",7:"md:grid-cols-7",8:"md:grid-cols-8",9:"md:grid-cols-9",10:"md:grid-cols-10",11:"md:grid-cols-11",12:"md:grid-cols-12"},i={0:"lg:grid-cols-none",1:"lg:grid-cols-1",2:"lg:grid-cols-2",3:"lg:grid-cols-3",4:"lg:grid-cols-4",5:"lg:grid-cols-5",6:"lg:grid-cols-6",7:"lg:grid-cols-7",8:"lg:grid-cols-8",9:"lg:grid-cols-9",10:"lg:grid-cols-10",11:"lg:grid-cols-11",12:"lg:grid-cols-12"};e.s(["colSpan",0,{1:"col-span-1",2:"col-span-2",3:"col-span-3",4:"col-span-4",5:"col-span-5",6:"col-span-6",7:"col-span-7",8:"col-span-8",9:"col-span-9",10:"col-span-10",11:"col-span-11",12:"col-span-12",13:"col-span-13"},"colSpanLg",0,{1:"lg:col-span-1",2:"lg:col-span-2",3:"lg:col-span-3",4:"lg:col-span-4",5:"lg:col-span-5",6:"lg:col-span-6",7:"lg:col-span-7",8:"lg:col-span-8",9:"lg:col-span-9",10:"lg:col-span-10",11:"lg:col-span-11",12:"lg:col-span-12",13:"lg:col-span-13"},"colSpanMd",0,{1:"md:col-span-1",2:"md:col-span-2",3:"md:col-span-3",4:"md:col-span-4",5:"md:col-span-5",6:"md:col-span-6",7:"md:col-span-7",8:"md:col-span-8",9:"md:col-span-9",10:"md:col-span-10",11:"md:col-span-11",12:"md:col-span-12",13:"md:col-span-13"},"colSpanSm",0,{1:"sm:col-span-1",2:"sm:col-span-2",3:"sm:col-span-3",4:"sm:col-span-4",5:"sm:col-span-5",6:"sm:col-span-6",7:"sm:col-span-7",8:"sm:col-span-8",9:"sm:col-span-9",10:"sm:col-span-10",11:"sm:col-span-11",12:"sm:col-span-12",13:"sm:col-span-13"},"gridCols",0,t,"gridColsLg",0,i,"gridColsMd",0,s,"gridColsSm",0,a],46757);let c=(0,l.makeClassName)("Grid"),d=(e,o)=>e&&Object.keys(o).includes(String(e))?o[e]:"",g=n.default.forwardRef((e,l)=>{let{numItems:g=1,numItemsSm:p,numItemsMd:m,numItemsLg:h,children:u,className:b}=e,k=(0,o.__rest)(e,["numItems","numItemsSm","numItemsMd","numItemsLg","children","className"]),f=d(g,t),x=d(p,a),v=d(m,s),w=d(h,i),y=(0,r.tremorTwMerge)(f,x,v,w);return n.default.createElement("div",Object.assign({ref:l,className:(0,r.tremorTwMerge)(c("root"),"grid",y,b)},k),u)});g.displayName="Grid",e.s(["Grid",0,g],350967)},678745,e=>{"use strict";let o=(0,e.i(475254).default)("check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]]);e.s(["default",0,o])},678784,e=>{"use strict";var o=e.i(678745);e.s(["CheckIcon",()=>o.default])},546467,e=>{"use strict";let o=(0,e.i(475254).default)("external-link",[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]]);e.s(["default",0,o])},673709,e=>{"use strict";var o=e.i(843476),r=e.i(271645),l=e.i(678784);let n=(0,e.i(475254).default)("clipboard",[["rect",{width:"8",height:"4",x:"8",y:"2",rx:"1",ry:"1",key:"tgr4d6"}],["path",{d:"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2",key:"116196"}]]);var t=e.i(650056);let a={'code[class*="language-"]':{background:"hsl(230, 1%, 98%)",color:"hsl(230, 8%, 24%)",fontFamily:'"Fira Code", "Fira Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace',direction:"ltr",textAlign:"left",whiteSpace:"pre",wordSpacing:"normal",wordBreak:"normal",lineHeight:"1.5",MozTabSize:"2",OTabSize:"2",tabSize:"2",WebkitHyphens:"none",MozHyphens:"none",msHyphens:"none",hyphens:"none"},'pre[class*="language-"]':{background:"hsl(230, 1%, 98%)",color:"hsl(230, 8%, 24%)",fontFamily:'"Fira Code", "Fira Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace',direction:"ltr",textAlign:"left",whiteSpace:"pre",wordSpacing:"normal",wordBreak:"normal",lineHeight:"1.5",MozTabSize:"2",OTabSize:"2",tabSize:"2",WebkitHyphens:"none",MozHyphens:"none",msHyphens:"none",hyphens:"none",padding:"1em",margin:"0.5em 0",overflow:"auto",borderRadius:"0.3em"},'code[class*="language-"]::-moz-selection':{background:"hsl(230, 1%, 90%)",color:"inherit"},'code[class*="language-"] *::-moz-selection':{background:"hsl(230, 1%, 90%)",color:"inherit"},'pre[class*="language-"] *::-moz-selection':{background:"hsl(230, 1%, 90%)",color:"inherit"},'code[class*="language-"]::selection':{background:"hsl(230, 1%, 90%)",color:"inherit"},'code[class*="language-"] *::selection':{background:"hsl(230, 1%, 90%)",color:"inherit"},'pre[class*="language-"] *::selection':{background:"hsl(230, 1%, 90%)",color:"inherit"},':not(pre) > code[class*="language-"]':{padding:"0.2em 0.3em",borderRadius:"0.3em",whiteSpace:"normal"},comment:{color:"hsl(230, 4%, 64%)",fontStyle:"italic"},prolog:{color:"hsl(230, 4%, 64%)"},cdata:{color:"hsl(230, 4%, 64%)"},doctype:{color:"hsl(230, 8%, 24%)"},punctuation:{color:"hsl(230, 8%, 24%)"},entity:{color:"hsl(230, 8%, 24%)",cursor:"help"},"attr-name":{color:"hsl(35, 99%, 36%)"},"class-name":{color:"hsl(35, 99%, 36%)"},boolean:{color:"hsl(35, 99%, 36%)"},constant:{color:"hsl(35, 99%, 36%)"},number:{color:"hsl(35, 99%, 36%)"},atrule:{color:"hsl(35, 99%, 36%)"},keyword:{color:"hsl(301, 63%, 40%)"},property:{color:"hsl(5, 74%, 59%)"},tag:{color:"hsl(5, 74%, 59%)"},symbol:{color:"hsl(5, 74%, 59%)"},deleted:{color:"hsl(5, 74%, 59%)"},important:{color:"hsl(5, 74%, 59%)"},selector:{color:"hsl(119, 34%, 47%)"},string:{color:"hsl(119, 34%, 47%)"},char:{color:"hsl(119, 34%, 47%)"},builtin:{color:"hsl(119, 34%, 47%)"},inserted:{color:"hsl(119, 34%, 47%)"},regex:{color:"hsl(119, 34%, 47%)"},"attr-value":{color:"hsl(119, 34%, 47%)"},"attr-value > .token.punctuation":{color:"hsl(119, 34%, 47%)"},variable:{color:"hsl(221, 87%, 60%)"},operator:{color:"hsl(221, 87%, 60%)"},function:{color:"hsl(221, 87%, 60%)"},url:{color:"hsl(198, 99%, 37%)"},"attr-value > .token.punctuation.attr-equals":{color:"hsl(230, 8%, 24%)"},"special-attr > .token.attr-value > .token.value.css":{color:"hsl(230, 8%, 24%)"},".language-css .token.selector":{color:"hsl(5, 74%, 59%)"},".language-css .token.property":{color:"hsl(230, 8%, 24%)"},".language-css .token.function":{color:"hsl(198, 99%, 37%)"},".language-css .token.url > .token.function":{color:"hsl(198, 99%, 37%)"},".language-css .token.url > .token.string.url":{color:"hsl(119, 34%, 47%)"},".language-css .token.important":{color:"hsl(301, 63%, 40%)"},".language-css .token.atrule .token.rule":{color:"hsl(301, 63%, 40%)"},".language-javascript .token.operator":{color:"hsl(301, 63%, 40%)"},".language-javascript .token.template-string > .token.interpolation > .token.interpolation-punctuation.punctuation":{color:"hsl(344, 84%, 43%)"},".language-json .token.operator":{color:"hsl(230, 8%, 24%)"},".language-json .token.null.keyword":{color:"hsl(35, 99%, 36%)"},".language-markdown .token.url":{color:"hsl(230, 8%, 24%)"},".language-markdown .token.url > .token.operator":{color:"hsl(230, 8%, 24%)"},".language-markdown .token.url-reference.url > .token.string":{color:"hsl(230, 8%, 24%)"},".language-markdown .token.url > .token.content":{color:"hsl(221, 87%, 60%)"},".language-markdown .token.url > .token.url":{color:"hsl(198, 99%, 37%)"},".language-markdown .token.url-reference.url":{color:"hsl(198, 99%, 37%)"},".language-markdown .token.blockquote.punctuation":{color:"hsl(230, 4%, 64%)",fontStyle:"italic"},".language-markdown .token.hr.punctuation":{color:"hsl(230, 4%, 64%)",fontStyle:"italic"},".language-markdown .token.code-snippet":{color:"hsl(119, 34%, 47%)"},".language-markdown .token.bold .token.content":{color:"hsl(35, 99%, 36%)"},".language-markdown .token.italic .token.content":{color:"hsl(301, 63%, 40%)"},".language-markdown .token.strike .token.content":{color:"hsl(5, 74%, 59%)"},".language-markdown .token.strike .token.punctuation":{color:"hsl(5, 74%, 59%)"},".language-markdown .token.list.punctuation":{color:"hsl(5, 74%, 59%)"},".language-markdown .token.title.important > .token.punctuation":{color:"hsl(5, 74%, 59%)"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"},namespace:{Opacity:"0.8"},"token.tab:not(:empty):before":{color:"hsla(230, 8%, 24%, 0.2)"},"token.cr:before":{color:"hsla(230, 8%, 24%, 0.2)"},"token.lf:before":{color:"hsla(230, 8%, 24%, 0.2)"},"token.space:before":{color:"hsla(230, 8%, 24%, 0.2)"},"div.code-toolbar > .toolbar.toolbar > .toolbar-item":{marginRight:"0.4em"},"div.code-toolbar > .toolbar.toolbar > .toolbar-item > button":{background:"hsl(230, 1%, 90%)",color:"hsl(230, 6%, 44%)",padding:"0.1em 0.4em",borderRadius:"0.3em"},"div.code-toolbar > .toolbar.toolbar > .toolbar-item > a":{background:"hsl(230, 1%, 90%)",color:"hsl(230, 6%, 44%)",padding:"0.1em 0.4em",borderRadius:"0.3em"},"div.code-toolbar > .toolbar.toolbar > .toolbar-item > span":{background:"hsl(230, 1%, 90%)",color:"hsl(230, 6%, 44%)",padding:"0.1em 0.4em",borderRadius:"0.3em"},"div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:hover":{background:"hsl(230, 1%, 78%)",color:"hsl(230, 8%, 24%)"},"div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:focus":{background:"hsl(230, 1%, 78%)",color:"hsl(230, 8%, 24%)"},"div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:hover":{background:"hsl(230, 1%, 78%)",color:"hsl(230, 8%, 24%)"},"div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:focus":{background:"hsl(230, 1%, 78%)",color:"hsl(230, 8%, 24%)"},"div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:hover":{background:"hsl(230, 1%, 78%)",color:"hsl(230, 8%, 24%)"},"div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:focus":{background:"hsl(230, 1%, 78%)",color:"hsl(230, 8%, 24%)"},".line-highlight.line-highlight":{background:"hsla(230, 8%, 24%, 0.05)"},".line-highlight.line-highlight:before":{background:"hsl(230, 1%, 90%)",color:"hsl(230, 8%, 24%)",padding:"0.1em 0.6em",borderRadius:"0.3em",boxShadow:"0 2px 0 0 rgba(0, 0, 0, 0.2)"},".line-highlight.line-highlight[data-end]:after":{background:"hsl(230, 1%, 90%)",color:"hsl(230, 8%, 24%)",padding:"0.1em 0.6em",borderRadius:"0.3em",boxShadow:"0 2px 0 0 rgba(0, 0, 0, 0.2)"},"pre[id].linkable-line-numbers.linkable-line-numbers span.line-numbers-rows > span:hover:before":{backgroundColor:"hsla(230, 8%, 24%, 0.05)"},".line-numbers.line-numbers .line-numbers-rows":{borderRightColor:"hsla(230, 8%, 24%, 0.2)"},".command-line .command-line-prompt":{borderRightColor:"hsla(230, 8%, 24%, 0.2)"},".line-numbers .line-numbers-rows > span:before":{color:"hsl(230, 1%, 62%)"},".command-line .command-line-prompt > span:before":{color:"hsl(230, 1%, 62%)"},".rainbow-braces .token.token.punctuation.brace-level-1":{color:"hsl(5, 74%, 59%)"},".rainbow-braces .token.token.punctuation.brace-level-5":{color:"hsl(5, 74%, 59%)"},".rainbow-braces .token.token.punctuation.brace-level-9":{color:"hsl(5, 74%, 59%)"},".rainbow-braces .token.token.punctuation.brace-level-2":{color:"hsl(119, 34%, 47%)"},".rainbow-braces .token.token.punctuation.brace-level-6":{color:"hsl(119, 34%, 47%)"},".rainbow-braces .token.token.punctuation.brace-level-10":{color:"hsl(119, 34%, 47%)"},".rainbow-braces .token.token.punctuation.brace-level-3":{color:"hsl(221, 87%, 60%)"},".rainbow-braces .token.token.punctuation.brace-level-7":{color:"hsl(221, 87%, 60%)"},".rainbow-braces .token.token.punctuation.brace-level-11":{color:"hsl(221, 87%, 60%)"},".rainbow-braces .token.token.punctuation.brace-level-4":{color:"hsl(301, 63%, 40%)"},".rainbow-braces .token.token.punctuation.brace-level-8":{color:"hsl(301, 63%, 40%)"},".rainbow-braces .token.token.punctuation.brace-level-12":{color:"hsl(301, 63%, 40%)"},"pre.diff-highlight > code .token.token.deleted:not(.prefix)":{backgroundColor:"hsla(353, 100%, 66%, 0.15)"},"pre > code.diff-highlight .token.token.deleted:not(.prefix)":{backgroundColor:"hsla(353, 100%, 66%, 0.15)"},"pre.diff-highlight > code .token.token.deleted:not(.prefix)::-moz-selection":{backgroundColor:"hsla(353, 95%, 66%, 0.25)"},"pre.diff-highlight > code .token.token.deleted:not(.prefix) *::-moz-selection":{backgroundColor:"hsla(353, 95%, 66%, 0.25)"},"pre > code.diff-highlight .token.token.deleted:not(.prefix)::-moz-selection":{backgroundColor:"hsla(353, 95%, 66%, 0.25)"},"pre > code.diff-highlight .token.token.deleted:not(.prefix) *::-moz-selection":{backgroundColor:"hsla(353, 95%, 66%, 0.25)"},"pre.diff-highlight > code .token.token.deleted:not(.prefix)::selection":{backgroundColor:"hsla(353, 95%, 66%, 0.25)"},"pre.diff-highlight > code .token.token.deleted:not(.prefix) *::selection":{backgroundColor:"hsla(353, 95%, 66%, 0.25)"},"pre > code.diff-highlight .token.token.deleted:not(.prefix)::selection":{backgroundColor:"hsla(353, 95%, 66%, 0.25)"},"pre > code.diff-highlight .token.token.deleted:not(.prefix) *::selection":{backgroundColor:"hsla(353, 95%, 66%, 0.25)"},"pre.diff-highlight > code .token.token.inserted:not(.prefix)":{backgroundColor:"hsla(137, 100%, 55%, 0.15)"},"pre > code.diff-highlight .token.token.inserted:not(.prefix)":{backgroundColor:"hsla(137, 100%, 55%, 0.15)"},"pre.diff-highlight > code .token.token.inserted:not(.prefix)::-moz-selection":{backgroundColor:"hsla(135, 73%, 55%, 0.25)"},"pre.diff-highlight > code .token.token.inserted:not(.prefix) *::-moz-selection":{backgroundColor:"hsla(135, 73%, 55%, 0.25)"},"pre > code.diff-highlight .token.token.inserted:not(.prefix)::-moz-selection":{backgroundColor:"hsla(135, 73%, 55%, 0.25)"},"pre > code.diff-highlight .token.token.inserted:not(.prefix) *::-moz-selection":{backgroundColor:"hsla(135, 73%, 55%, 0.25)"},"pre.diff-highlight > code .token.token.inserted:not(.prefix)::selection":{backgroundColor:"hsla(135, 73%, 55%, 0.25)"},"pre.diff-highlight > code .token.token.inserted:not(.prefix) *::selection":{backgroundColor:"hsla(135, 73%, 55%, 0.25)"},"pre > code.diff-highlight .token.token.inserted:not(.prefix)::selection":{backgroundColor:"hsla(135, 73%, 55%, 0.25)"},"pre > code.diff-highlight .token.token.inserted:not(.prefix) *::selection":{backgroundColor:"hsla(135, 73%, 55%, 0.25)"},".prism-previewer.prism-previewer:before":{borderColor:"hsl(0, 0, 95%)"},".prism-previewer-gradient.prism-previewer-gradient div":{borderColor:"hsl(0, 0, 95%)",borderRadius:"0.3em"},".prism-previewer-color.prism-previewer-color:before":{borderRadius:"0.3em"},".prism-previewer-easing.prism-previewer-easing:before":{borderRadius:"0.3em"},".prism-previewer.prism-previewer:after":{borderTopColor:"hsl(0, 0, 95%)"},".prism-previewer-flipped.prism-previewer-flipped.after":{borderBottomColor:"hsl(0, 0, 95%)"},".prism-previewer-angle.prism-previewer-angle:before":{background:"hsl(0, 0%, 100%)"},".prism-previewer-time.prism-previewer-time:before":{background:"hsl(0, 0%, 100%)"},".prism-previewer-easing.prism-previewer-easing":{background:"hsl(0, 0%, 100%)"},".prism-previewer-angle.prism-previewer-angle circle":{stroke:"hsl(230, 8%, 24%)",strokeOpacity:"1"},".prism-previewer-time.prism-previewer-time circle":{stroke:"hsl(230, 8%, 24%)",strokeOpacity:"1"},".prism-previewer-easing.prism-previewer-easing circle":{stroke:"hsl(230, 8%, 24%)",fill:"transparent"},".prism-previewer-easing.prism-previewer-easing path":{stroke:"hsl(230, 8%, 24%)"},".prism-previewer-easing.prism-previewer-easing line":{stroke:"hsl(230, 8%, 24%)"}};e.s(["default",0,({code:e,language:s})=>{let[i,c]=(0,r.useState)(!1);return(0,o.jsxs)("div",{className:"relative rounded-lg border border-gray-200 overflow-hidden",children:[(0,o.jsx)("button",{onClick:()=>{navigator.clipboard.writeText(e),c(!0),setTimeout(()=>c(!1),2e3)},className:"absolute top-3 right-3 p-2 rounded-md bg-gray-100 hover:bg-gray-200 text-gray-600 z-10","aria-label":"Copy code",children:i?(0,o.jsx)(l.CheckIcon,{size:16}):(0,o.jsx)(n,{size:16})}),(0,o.jsx)(t.Prism,{language:s,style:a,customStyle:{margin:0,padding:"1.5rem",borderRadius:"0.5rem",fontSize:"0.9rem",backgroundColor:"#fafafa"},showLineNumbers:!0,children:e})]})}],673709)},778917,e=>{"use strict";var o=e.i(546467);e.s(["ExternalLink",()=>o.default])},191905,e=>{"use strict";var o=e.i(843476),r=e.i(599724),l=e.i(197647),n=e.i(653824),t=e.i(881073),a=e.i(404206),s=e.i(723731),i=e.i(350967),c=e.i(673709),d=e.i(778917),g=e.i(115504);let p=({href:e,className:r})=>(0,o.jsxs)("a",{href:e,target:"_blank",rel:"noopener noreferrer",title:"Open documentation in a new tab",className:(0,g.cn)("inline-flex items-center gap-2 rounded-xl border border-zinc-200 bg-white/80 px-3.5 py-2 text-sm font-medium text-zinc-700 shadow-xs","hover:bg-white focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-blue-500 active:translate-y-[0.5px]",r),children:[(0,o.jsx)("span",{children:"API Reference Docs"}),(0,o.jsx)(d.ExternalLink,{"aria-hidden":!0,className:"h-4 w-4 opacity-80"}),(0,o.jsx)("span",{className:"sr-only",children:"(opens in a new tab)"})]}),m=({proxySettings:e})=>{let d="",g=e?.LITELLM_UI_API_DOC_BASE_URL;return g&&g.trim()?d=g:e?.PROXY_BASE_URL&&(d=e.PROXY_BASE_URL),(0,o.jsx)(o.Fragment,{children:(0,o.jsx)(i.Grid,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,o.jsxs)("div",{className:"mb-5",children:[(0,o.jsxs)("div",{className:"flex items-center justify-between",children:[(0,o.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,o.jsx)(p,{className:"ml-3 shrink-0",href:"https://docs.litellm.ai/docs/proxy/user_keys"})]}),(0,o.jsxs)(r.Text,{className:"mt-2 mb-2",children:["LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below"," "]}),(0,o.jsxs)(n.TabGroup,{children:[(0,o.jsxs)(t.TabList,{children:[(0,o.jsx)(l.Tab,{children:"OpenAI Python SDK"}),(0,o.jsx)(l.Tab,{children:"LlamaIndex"}),(0,o.jsx)(l.Tab,{children:"Langchain Py"})]}),(0,o.jsxs)(s.TabPanels,{children:[(0,o.jsx)(a.TabPanel,{children:(0,o.jsx)(c.default,{language:"python",code:`import openai +client = openai.OpenAI( + api_key="your_api_key", + base_url="${d}" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys +) + +response = client.chat.completions.create( + model="gpt-3.5-turbo", # model to send to the proxy + messages = [ + { + "role": "user", + "content": "this is a test request, write a short poem" + } + ] +) + +print(response)`})}),(0,o.jsx)(a.TabPanel,{children:(0,o.jsx)(c.default,{language:"python",code:`import os, dotenv + +from llama_index.llms import AzureOpenAI +from llama_index.embeddings import AzureOpenAIEmbedding +from llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext + +llm = AzureOpenAI( + engine="azure-gpt-3.5", # model_name on litellm proxy + temperature=0.0, + azure_endpoint="${d}", # litellm proxy endpoint + api_key="sk-1234", # litellm proxy API Key + api_version="2023-07-01-preview", +) + +embed_model = AzureOpenAIEmbedding( + deployment_name="azure-embedding-model", + azure_endpoint="${d}", + api_key="sk-1234", + api_version="2023-07-01-preview", +) + +documents = SimpleDirectoryReader("llama_index_data").load_data() +service_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model) +index = VectorStoreIndex.from_documents(documents, service_context=service_context) + +query_engine = index.as_query_engine() +response = query_engine.query("What did the author do growing up?") +print(response)`})}),(0,o.jsx)(a.TabPanel,{children:(0,o.jsx)(c.default,{language:"python",code:`from langchain.chat_models import ChatOpenAI +from langchain.prompts.chat import ( + ChatPromptTemplate, + HumanMessagePromptTemplate, + SystemMessagePromptTemplate, +) +from langchain.schema import HumanMessage, SystemMessage + +chat = ChatOpenAI( + openai_api_base="${d}", + model = "gpt-3.5-turbo", + temperature=0.1 +) + +messages = [ + SystemMessage( + content="You are a helpful assistant that im using to make a test request to." + ), + HumanMessage( + content="test from litellm. tell me why it's amazing in 1 sentence" + ), +] +response = chat(messages) + +print(response)`})})]})]})]})})})};var h=e.i(135214),u=e.i(592392);e.s(["default",0,()=>{let{accessToken:e}=(0,h.default)(),r=(0,u.default)(e);return(0,o.jsx)(m,{proxySettings:r})}],191905)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/02ax9y70kcggv.js b/litellm/proxy/_experimental/out/_next/static/chunks/02ax9y70kcggv.js new file mode 100644 index 00000000000..c436d5dcf0f --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/02ax9y70kcggv.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,246349,e=>{"use strict";let t=(0,e.i(475254).default)("chevron-right",[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]]);e.s(["default",0,t])},195116,e=>{"use strict";let t=(0,e.i(475254).default)("wrench",[["path",{d:"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z",key:"cbrjhi"}]]);e.s(["Wrench",0,t],195116)},180127,e=>{"use strict";let t=(0,e.i(475254).default)("arrow-left",[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]]);e.s(["default",0,t])},434166,e=>{"use strict";e.s(["getSecureItem",0,function(e){try{let t=window.sessionStorage.getItem(e);if(null===t)return null;return decodeURIComponent(atob(t).split("").map(e=>"%"+e.charCodeAt(0).toString(16).padStart(2,"0")).join(""))}catch{return null}},"setSecureItem",0,function(e,t){window.sessionStorage.setItem(e,btoa(encodeURIComponent(t).replace(/%([0-9A-F]{2})/g,(e,t)=>String.fromCharCode(parseInt(t,16)))))}])},531278,e=>{"use strict";let t=(0,e.i(475254).default)("loader-circle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);e.s(["Loader2",0,t],531278)},302747,e=>{"use strict";var t=e.i(843476),r=e.i(115504);e.s(["Skeleton",0,function({className:e,...s}){return(0,t.jsx)("div",{"data-slot":"skeleton",className:(0,r.cn)("animate-pulse rounded-md bg-accent",e),...s})}])},463059,e=>{"use strict";var t=e.i(246349);e.s(["ChevronRight",()=>t.default])},269638,e=>{"use strict";let t=(0,e.i(475254).default)("circle-check-big",[["path",{d:"M21.801 10A10 10 0 1 1 17 3.335",key:"yps3ct"}],["path",{d:"m9 11 3 3L22 4",key:"1pflzl"}]]);e.s(["CheckCircle",0,t],269638)},292335,122520,165615,779129,280024,e=>{"use strict";let t={NONE:"none",API_KEY:"api_key",BEARER_TOKEN:"bearer_token",TOKEN:"token",BASIC:"basic",OAUTH2:"oauth2",AWS_SIGV4:"aws_sigv4"},r="client_credentials",s={SSE:"sse",HTTP:"http",STDIO:"stdio",OPENAPI:"openapi"};e.s(["AUTH_TYPE",0,t,"MCP_OAUTH2_FLOW_M2M",0,r,"OAUTH_FLOW",0,{INTERACTIVE:"interactive",M2M:"m2m"},"TRANSPORT",0,s,"getMcpOAuthMode",0,function(e){return e.auth_type!==t.OAUTH2?null:e.oauth2_flow===r?"m2m":e.delegate_auth_to_upstream?"passthrough":"obo"},"handleAuth",0,e=>null==e?t.NONE:e,"handleTransport",0,(e,t)=>null==e?s.SSE:t&&e!==s.STDIO?s.OPENAPI:e],292335);var a=e.i(271645),n=e.i(602869),i=e.i(727749);function l(e){if(e instanceof Error)return e.message;if(e&&"object"==typeof e){let t=e.detail;return"string"==typeof t?t:Array.isArray(t)?t.map(e=>e&&"object"==typeof e?"string"==typeof e.msg?e.msg:JSON.stringify(e):String(e)).join("; "):t&&"object"==typeof t&&"string"==typeof t.error?t.error:"string"==typeof e.message?e.message:JSON.stringify(e)}return String(e)}e.s(["extractErrorMessage",0,l],122520);let o=e=>{let t=new Uint8Array(e),r="";return t.forEach(e=>r+=String.fromCharCode(e)),btoa(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},c=()=>{let e=new Uint8Array(32);return window.crypto.getRandomValues(e),o(e.buffer)},d=async e=>{let t=new TextEncoder().encode(e);return o(await window.crypto.subtle.digest("SHA-256",t))};e.s(["generateCodeChallenge",0,d,"generateCodeVerifier",0,c],165615);var u=e.i(434166);let f=()=>{{let e=window.location.pathname||"",t=e.indexOf("/ui"),r=t>=0?e.slice(0,t+3).replace(/\/+$/,""):"";return`${window.location.origin}${r}/mcp/oauth/callback`}},h=(...e)=>{e.forEach(e=>{try{window.sessionStorage.removeItem(e)}catch(e){}})};e.s(["TOOLS_OAUTH_UI_STATE_KEY",0,"litellm-mcp-oauth-tools-state","buildCallbackUrl",0,f,"clearStorage",0,h],779129);let p="litellm-user-mcp-oauth-flow-state",m="litellm-user-mcp-oauth-result",x=(e,t)=>{(0,u.setSecureItem)(e,t)},g=e=>(0,u.getSecureItem)(e);e.s(["useUserMcpOAuthFlow",0,({accessToken:e,serverId:t,serverAlias:r,scopes:s,clientId:o,onSuccess:u})=>{let[v,b]=(0,a.useState)("idle"),[y,w]=(0,a.useState)(null),j=(0,a.useRef)(!1),N=(0,a.useCallback)(async()=>{try{let a;b("authorizing"),w(null);let i=o??void 0;if(!i)try{let s=await (0,n.registerMcpOAuthClient)(e,t,{client_name:r||t,grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none"});i=s?.client_id,a=s?.client_secret}catch(e){}let l=c(),u=await d(l),h=crypto.randomUUID(),m=f(),g=s?.filter(e=>e.trim()).join(" "),v=(0,n.buildMcpOAuthAuthorizeUrl)({serverId:t,clientId:i,redirectUri:m,state:h,codeChallenge:u,scope:g}),y={state:h,codeVerifier:l,serverId:t,redirectUri:m,clientId:i,clientSecret:a,scopes:s};x(p,JSON.stringify(y));let j=new URL(window.location.href);j.searchParams.set("mcpOauthReturn","apps"),x("litellm-mcp-oauth-return-url",j.toString()),window.location.href=v}catch(t){let e=l(t);w(e),b("error"),i.default.error(e)}},[e,t,r,s,o]),k=(0,a.useCallback)(async()=>{if(j.current)return;let r=g(m);if(!r)return;let s=g(p);if(!s)return;try{let e=JSON.parse(s);if(e.serverId&&e.serverId!==t)return}catch(e){}j.current=!0,h(m);let a=null,o=null;try{a=JSON.parse(r);let e=g(p);o=e?JSON.parse(e):null}catch(e){w("Failed to resume OAuth flow. Please retry."),b("error"),j.current=!1,h(p);return}try{if(!o?.state||!o.codeVerifier||!o.serverId)throw Error("OAuth session state was lost. Please retry.");if(!a?.state||a.state!==o.state)throw Error("OAuth state mismatch. Please retry.");if(a.error)throw Error(a.error_description||a.error);if(!a.code)throw Error("Authorization code missing in callback.");b("exchanging");let t=await (0,n.exchangeMcpOAuthToken)({serverId:o.serverId,code:a.code,clientId:o.clientId,clientSecret:o.clientSecret,codeVerifier:o.codeVerifier,redirectUri:o.redirectUri,accessToken:e});await (0,n.storeMCPOAuthUserCredential)(e,o.serverId,{access_token:t.access_token,refresh_token:t.refresh_token,expires_in:t.expires_in,scopes:o.scopes}),b("success"),w(null),i.default.success("Connected successfully"),u()}catch(t){let e=l(t);w(e),b("error"),i.default.error(e)}finally{h(p),setTimeout(()=>{j.current=!1},1e3)}},[e,t,u]);return(0,a.useEffect)(()=>{k()},[k]),{startOAuthFlow:N,status:v,error:y}}],280024)},248536,e=>{"use strict";var t=e.i(843476),r=e.i(271645),s=e.i(618566),a=e.i(405033),n=e.i(266027),i=e.i(555436),l=e.i(180127),l=l,o=e.i(463059),c=e.i(195116),d=e.i(269638),u=e.i(531278),f=e.i(519455),h=e.i(793479),p=e.i(302747),m=e.i(981140),x=e.i(30030),g=e.i(820783),v=e.i(991918),b=new WeakMap;function y(e,t){var r,s;let a,n,i;if("at"in Array.prototype)return Array.prototype.at.call(e,t);let l=(r=e,s=t,a=r.length,(i=(n=w(s))>=0?n:a+n)<0||i>=a?-1:i);return -1===l?void 0:e[l]}function w(e){return e!=e||0===e?0:Math.trunc(e)}(class e extends Map{#e;constructor(e){super(e),this.#e=[...super.keys()],b.set(this,!0)}set(e,t){return b.get(this)&&(this.has(e)?this.#e[this.#e.indexOf(e)]=e:this.#e.push(e)),super.set(e,t),this}insert(e,t,r){let s,a=this.has(t),n=this.#e.length,i=w(e),l=i>=0?i:n+i,o=l<0||l>=n?-1:l;if(o===this.size||a&&o===this.size-1||-1===o)return this.set(t,r),this;let c=this.size+ +!a;i<0&&l++;let d=[...this.#e],u=!1;for(let e=l;e=this.size&&(s=this.size-1),this.at(s)}keyFrom(e,t){let r=this.indexOf(e);if(-1===r)return;let s=r+t;return s<0&&(s=0),s>=this.size&&(s=this.size-1),this.keyAt(s)}find(e,t){let r=0;for(let s of this){if(Reflect.apply(e,t,[s,r,this]))return s;r++}}findIndex(e,t){let r=0;for(let s of this){if(Reflect.apply(e,t,[s,r,this]))return r;r++}return -1}filter(t,r){let s=[],a=0;for(let e of this)Reflect.apply(t,r,[e,a,this])&&s.push(e),a++;return new e(s)}map(t,r){let s=[],a=0;for(let e of this)s.push([e[0],Reflect.apply(t,r,[e,a,this])]),a++;return new e(s)}reduce(...e){let[t,r]=e,s=0,a=r??this.at(0);for(let r of this)a=0===s&&1===e.length?r:Reflect.apply(t,this,[a,r,s,this]),s++;return a}reduceRight(...e){let[t,r]=e,s=r??this.at(-1);for(let r=this.size-1;r>=0;r--){let a=this.at(r);s=r===this.size-1&&1===e.length?a:Reflect.apply(t,this,[s,a,r,this])}return s}toSorted(t){return new e([...this.entries()].sort(t))}toReversed(){let t=new e;for(let e=this.size-1;e>=0;e--){let r=this.keyAt(e),s=this.get(r);t.set(r,s)}return t}toSpliced(...t){let r=[...this.entries()];return r.splice(...t),new e(r)}slice(t,r){let s=new e,a=this.size-1;if(void 0===t)return s;t<0&&(t+=this.size),void 0!==r&&r>0&&(a=r-1);for(let e=t;e<=a;e++){let t=this.keyAt(e),r=this.get(t);s.set(t,r)}return s}every(e,t){let r=0;for(let s of this){if(!Reflect.apply(e,t,[s,r,this]))return!1;r++}return!0}some(e,t){let r=0;for(let s of this){if(Reflect.apply(e,t,[s,r,this]))return!0;r++}return!1}});var j=e.i(610772),N=e.i(248425),k=e.i(30207),S=e.i(369340),C=e.i(586318),A="rovingFocusGroup.onEntryFocus",_={bubbles:!1,cancelable:!0},T="RovingFocusGroup",[R,E,O]=function(e){let s=e+"CollectionProvider",[a,n]=(0,x.createContextScope)(s),[i,l]=a(s,{collectionRef:{current:null},itemMap:new Map}),o=e=>{let{scope:s,children:a}=e,n=r.useRef(null),l=r.useRef(new Map).current;return(0,t.jsx)(i,{scope:s,itemMap:l,collectionRef:n,children:a})};o.displayName=s;let c=e+"CollectionSlot",d=(0,v.createSlot)(c),u=r.forwardRef((e,r)=>{let{scope:s,children:a}=e,n=l(c,s),i=(0,g.useComposedRefs)(r,n.collectionRef);return(0,t.jsx)(d,{ref:i,children:a})});u.displayName=c;let f=e+"CollectionItemSlot",h="data-radix-collection-item",p=(0,v.createSlot)(f),m=r.forwardRef((e,s)=>{let{scope:a,children:n,...i}=e,o=r.useRef(null),c=(0,g.useComposedRefs)(s,o),d=l(f,a);return r.useEffect(()=>(d.itemMap.set(o,{ref:o,...i}),()=>void d.itemMap.delete(o))),(0,t.jsx)(p,{...{[h]:""},ref:c,children:n})});return m.displayName=f,[{Provider:o,Slot:u,ItemSlot:m},function(t){let s=l(e+"CollectionConsumer",t);return r.useCallback(()=>{let e=s.collectionRef.current;if(!e)return[];let t=Array.from(e.querySelectorAll(`[${h}]`));return Array.from(s.itemMap.values()).sort((e,r)=>t.indexOf(e.ref.current)-t.indexOf(r.ref.current))},[s.collectionRef,s.itemMap])},n]}(T),[I,M]=(0,x.createContextScope)(T,[O]),[P,U]=I(T),z=r.forwardRef((e,r)=>(0,t.jsx)(R.Provider,{scope:e.__scopeRovingFocusGroup,children:(0,t.jsx)(R.Slot,{scope:e.__scopeRovingFocusGroup,children:(0,t.jsx)(F,{...e,ref:r})})}));z.displayName=T;var F=r.forwardRef((e,s)=>{let{__scopeRovingFocusGroup:a,orientation:n,loop:i=!1,dir:l,currentTabStopId:o,defaultCurrentTabStopId:c,onCurrentTabStopIdChange:d,onEntryFocus:u,preventScrollOnEntryFocus:f=!1,...h}=e,p=r.useRef(null),x=(0,g.useComposedRefs)(s,p),v=(0,C.useDirection)(l),[b,y]=(0,S.useControllableState)({prop:o,defaultProp:c??null,onChange:d,caller:T}),[w,j]=r.useState(!1),R=(0,k.useCallbackRef)(u),O=E(a),I=r.useRef(!1),[M,U]=r.useState(0);return r.useEffect(()=>{let e=p.current;if(e)return e.addEventListener(A,R),()=>e.removeEventListener(A,R)},[R]),(0,t.jsx)(P,{scope:a,orientation:n,dir:v,loop:i,currentTabStopId:b,onItemFocus:r.useCallback(e=>y(e),[y]),onItemShiftTab:r.useCallback(()=>j(!0),[]),onFocusableItemAdd:r.useCallback(()=>U(e=>e+1),[]),onFocusableItemRemove:r.useCallback(()=>U(e=>e-1),[]),children:(0,t.jsx)(N.Primitive.div,{tabIndex:w||0===M?-1:0,"data-orientation":n,...h,ref:x,style:{outline:"none",...e.style},onMouseDown:(0,m.composeEventHandlers)(e.onMouseDown,()=>{I.current=!0}),onFocus:(0,m.composeEventHandlers)(e.onFocus,e=>{let t=!I.current;if(e.target===e.currentTarget&&t&&!w){let t=new CustomEvent(A,_);if(e.currentTarget.dispatchEvent(t),!t.defaultPrevented){let e=O().filter(e=>e.focusable);$([e.find(e=>e.active),e.find(e=>e.id===b),...e].filter(Boolean).map(e=>e.ref.current),f)}}I.current=!1}),onBlur:(0,m.composeEventHandlers)(e.onBlur,()=>j(!1))})})}),L="RovingFocusGroupItem",D=r.forwardRef((e,s)=>{let{__scopeRovingFocusGroup:a,focusable:n=!0,active:i=!1,tabStopId:l,children:o,...c}=e,d=(0,j.useId)(),u=l||d,f=U(L,a),h=f.currentTabStopId===u,p=E(a),{onFocusableItemAdd:x,onFocusableItemRemove:g,currentTabStopId:v}=f;return r.useEffect(()=>{if(n)return x(),()=>g()},[n,x,g]),(0,t.jsx)(R.ItemSlot,{scope:a,id:u,focusable:n,active:i,children:(0,t.jsx)(N.Primitive.span,{tabIndex:h?0:-1,"data-orientation":f.orientation,...c,ref:s,onMouseDown:(0,m.composeEventHandlers)(e.onMouseDown,e=>{n?f.onItemFocus(u):e.preventDefault()}),onFocus:(0,m.composeEventHandlers)(e.onFocus,()=>f.onItemFocus(u)),onKeyDown:(0,m.composeEventHandlers)(e.onKeyDown,e=>{if("Tab"===e.key&&e.shiftKey)return void f.onItemShiftTab();if(e.target!==e.currentTarget)return;let t=function(e,t,r){var s;let a=(s=e.key,"rtl"!==r?s:"ArrowLeft"===s?"ArrowRight":"ArrowRight"===s?"ArrowLeft":s);if(!("vertical"===t&&["ArrowLeft","ArrowRight"].includes(a))&&!("horizontal"===t&&["ArrowUp","ArrowDown"].includes(a)))return H[a]}(e,f.orientation,f.dir);if(void 0!==t){if(e.metaKey||e.ctrlKey||e.altKey||e.shiftKey)return;e.preventDefault();let a=p().filter(e=>e.focusable).map(e=>e.ref.current);if("last"===t)a.reverse();else if("prev"===t||"next"===t){var r,s;"prev"===t&&a.reverse();let n=a.indexOf(e.currentTarget);a=f.loop?(r=a,s=n+1,r.map((e,t)=>r[(s+t)%r.length])):a.slice(n+1)}setTimeout(()=>$(a))}}),children:"function"==typeof o?o({isCurrentTabStop:h,hasTabStop:null!=v}):o})})});D.displayName=L;var H={ArrowLeft:"prev",ArrowUp:"prev",ArrowRight:"next",ArrowDown:"next",PageUp:"first",Home:"first",PageDown:"last",End:"last"};function $(e,t=!1){let r=document.activeElement;for(let s of e)if(s===r||(s.focus({preventScroll:t}),document.activeElement!==r))return}var K=e.i(296626),B="Tabs",[V,W]=(0,x.createContextScope)(B,[M]),G=M(),[J,Y]=V(B),q=r.forwardRef((e,r)=>{let{__scopeTabs:s,value:a,onValueChange:n,defaultValue:i,orientation:l="horizontal",dir:o,activationMode:c="automatic",...d}=e,u=(0,C.useDirection)(o),[f,h]=(0,S.useControllableState)({prop:a,onChange:n,defaultProp:i??"",caller:B});return(0,t.jsx)(J,{scope:s,baseId:(0,j.useId)(),value:f,onValueChange:h,orientation:l,dir:u,activationMode:c,children:(0,t.jsx)(N.Primitive.div,{dir:u,"data-orientation":l,...d,ref:r})})});q.displayName=B;var Q="TabsList",X=r.forwardRef((e,r)=>{let{__scopeTabs:s,loop:a=!0,...n}=e,i=Y(Q,s),l=G(s);return(0,t.jsx)(z,{asChild:!0,...l,orientation:i.orientation,dir:i.dir,loop:a,children:(0,t.jsx)(N.Primitive.div,{role:"tablist","aria-orientation":i.orientation,...n,ref:r})})});X.displayName=Q;var Z="TabsTrigger",ee=r.forwardRef((e,r)=>{let{__scopeTabs:s,value:a,disabled:n=!1,...i}=e,l=Y(Z,s),o=G(s),c=es(l.baseId,a),d=ea(l.baseId,a),u=a===l.value;return(0,t.jsx)(D,{asChild:!0,...o,focusable:!n,active:u,children:(0,t.jsx)(N.Primitive.button,{type:"button",role:"tab","aria-selected":u,"aria-controls":d,"data-state":u?"active":"inactive","data-disabled":n?"":void 0,disabled:n,id:c,...i,ref:r,onMouseDown:(0,m.composeEventHandlers)(e.onMouseDown,e=>{n||0!==e.button||!1!==e.ctrlKey?e.preventDefault():l.onValueChange(a)}),onKeyDown:(0,m.composeEventHandlers)(e.onKeyDown,e=>{[" ","Enter"].includes(e.key)&&l.onValueChange(a)}),onFocus:(0,m.composeEventHandlers)(e.onFocus,()=>{let e="manual"!==l.activationMode;u||n||!e||l.onValueChange(a)})})})});ee.displayName=Z;var et="TabsContent",er=r.forwardRef((e,s)=>{let{__scopeTabs:a,value:n,forceMount:i,children:l,...o}=e,c=Y(et,a),d=es(c.baseId,n),u=ea(c.baseId,n),f=n===c.value,h=r.useRef(f);return r.useEffect(()=>{let e=requestAnimationFrame(()=>h.current=!1);return()=>cancelAnimationFrame(e)},[]),(0,t.jsx)(K.Presence,{present:i||f,children:({present:r})=>(0,t.jsx)(N.Primitive.div,{"data-state":f?"active":"inactive","data-orientation":c.orientation,role:"tabpanel","aria-labelledby":d,hidden:!r,id:u,tabIndex:0,...o,ref:s,style:{...e.style,animationDuration:h.current?"0s":void 0},children:r&&l})})});function es(e,t){return`${e}-trigger-${t}`}function ea(e,t){return`${e}-content-${t}`}er.displayName=et,e.s(["Content",0,er,"List",0,X,"Root",0,q,"Tabs",0,q,"TabsContent",0,er,"TabsList",0,X,"TabsTrigger",0,ee,"Trigger",0,ee,"createTabsScope",0,W],926209);var en=e.i(926209),en=en,ei=e.i(115504);function el({className:e,orientation:r="horizontal",...s}){return(0,t.jsx)(en.Root,{"data-slot":"tabs","data-orientation":r,orientation:r,className:(0,ei.cn)("group/tabs flex gap-2 data-[orientation=horizontal]:flex-col",e),...s})}let eo=(0,ei.cva)({base:"group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-[orientation=horizontal]/tabs:h-9 group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col data-[variant=line]:rounded-none",variants:{variant:{default:"bg-muted",line:"gap-1 bg-transparent"}},defaultVariants:{variant:"default"}});function ec({className:e,variant:r="default",...s}){return(0,t.jsx)(en.List,{"data-slot":"tabs-list","data-variant":r,className:(0,ei.cn)(eo({variant:r}),e),...s})}function ed({className:e,...r}){return(0,t.jsx)(en.Trigger,{"data-slot":"tabs-trigger",className:(0,ei.cn)("relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4","group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent","data-[state=active]:bg-background data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 dark:data-[state=active]:text-foreground","after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100",e),...r})}var eu=e.i(602869),ef=e.i(292335),eh=e.i(888259),ep=e.i(280024);let em=({server:e,accessToken:s,onConnect:a,variant:n="badge"})=>{let i=e.server_name??e.alias??e.server_id,{startOAuthFlow:l,status:o}=(0,ep.useUserMcpOAuthFlow)({accessToken:s,serverId:e.server_id,serverAlias:i,onSuccess:(0,r.useCallback)(()=>a(e.server_id),[a,e.server_id])}),c="authorizing"===o||"exchanging"===o;return"button"===n?(0,t.jsxs)(f.Button,{onClick:l,disabled:c,className:"font-semibold h-[38px] min-w-[110px]",children:[c&&(0,t.jsx)(u.Loader2,{className:"h-4 w-4 animate-spin mr-1.5"}),c?"Connecting…":"Connect"]}):(0,t.jsx)("span",{onClick:e=>{e.stopPropagation(),c||l()},className:`text-[11px] font-semibold rounded-md px-2 py-0.5 shrink-0 whitespace-nowrap ${c?"text-muted-foreground bg-muted cursor-default":"text-primary-foreground bg-primary cursor-pointer hover:bg-primary/90"}`,children:c?"Connecting…":"Connect"})},ex=["#1677ff","#52c41a","#fa8c16","#eb2f96","#722ed1","#13c2c2","#fa541c","#2f54eb","#a0d911","#faad14"];function eg(e){let t=0;for(let r=0;r{let[m,x]=(0,r.useState)([]),[g,v]=(0,r.useState)(!0),[b,y]=(0,r.useState)(""),[w,j]=(0,r.useState)("all"),[N,k]=(0,r.useState)(new Set),[S,C]=(0,r.useState)(null),[A,_]=(0,r.useState)({}),[T,R]=(0,r.useState)(!1),[E,O]=(0,r.useState)(new Set),I=(0,r.useRef)([]);(0,r.useEffect)(()=>{I.current=m},[m]);let M=(0,r.useRef)(s);(0,r.useEffect)(()=>{M.current=s},[s]);let P=(0,r.useRef)(a);(0,r.useEffect)(()=>{P.current=a},[a]);let U=e=>e.server_name??e.alias??e.server_id,z=(0,r.useRef)(!1),F=(0,r.useCallback)(async t=>{try{let r=await (0,eu.listMCPTools)(e,t.server_id);if(z.current)return;let s=Array.isArray(r?.tools)?r.tools:[];_(e=>({...e,[U(t)]:s.length}))}catch{}},[e]),L=(0,r.useCallback)(async t=>{try{let r=await (0,eu.getMCPOAuthUserCredentialStatus)(e,t.server_id);if(z.current)return;r.has_credential&&!r.is_expired&&O(e=>new Set(e).add(t.server_id))}catch{}},[e]);(0,r.useEffect)(()=>(z.current=!1,(0,eu.fetchMCPServers)(e).then(async e=>{if(z.current)return;let t=Array.isArray(e)?e:e?.data??[];for(let e of(x(t),v(!1),R(!0),Array.from({length:Math.ceil(t.length/5)},(e,r)=>t.slice(5*r,(r+1)*5)))){if(z.current)return;await Promise.allSettled(e.map(e=>F(e)))}z.current||R(!1),t.filter(e=>e.auth_type===ef.AUTH_TYPE.OAUTH2).forEach(e=>L(e))}).catch(()=>{z.current||(x([]),v(!1))}),()=>{z.current=!0}),[e,F,L]),(0,r.useEffect)(()=>{if(0===E.size)return;let e=I.current.filter(e=>E.has(e.server_id)&&!M.current.includes(U(e))).map(U);e.length>0&&P.current([...M.current,...e])},[E]);let D=async(t,r,n)=>{if(!r){a(s.filter(e=>e!==t)),n&&O(e=>{let t=new Set(e);return t.delete(n),t});return}k(e=>new Set(e).add(t));try{let r=n??t,s=await (0,eu.listMCPTools)(e,r);if(s?.error)return void eh.default.warning(`Could not load tools for ${t}`);M.current.includes(t)||a([...M.current,t])}catch{eh.default.warning(`Could not load tools for ${t}`)}finally{k(e=>{let r=new Set(e);return r.delete(t),r})}},{data:H,isLoading:$}=(0,n.useQuery)({queryKey:["mcp-apps-panel-detail-tools",S?.server_id],queryFn:()=>(0,eu.listMCPTools)(e,S.server_id),enabled:!!S}),K=Array.isArray(H?.tools)?H.tools:[],B=m.filter(e=>{let t=U(e),r=!b.trim()||t.toLowerCase().includes(b.toLowerCase())||(e.description??"").toLowerCase().includes(b.toLowerCase()),a="all"===w||s.includes(t);return r&&a}),V=m.filter(e=>s.includes(U(e))).length,W=Object.values(A).reduce((e,t)=>e+t,0);if(S){let r=U(S),a=s.includes(r),n=N.has(r),i=eg(r);return(0,t.jsxs)("div",{className:"w-full",children:[(0,t.jsxs)(f.Button,{variant:"ghost",size:"sm",onClick:()=>C(null),className:"-ml-3 mb-5 gap-1.5 text-muted-foreground hover:text-foreground",children:[(0,t.jsx)(l.default,{className:"h-3 w-3"}),"Back"]}),(0,t.jsxs)("div",{className:"flex items-start gap-5 mb-7",children:[S.mcp_info?.logo_url?(0,t.jsx)("img",{src:S.mcp_info.logo_url,alt:`${r} logo`,className:"w-16 h-16 rounded-2xl object-contain shrink-0 bg-muted/50",onError:e=>{let t=e.target;t.style.display="none",t.nextElementSibling&&(t.nextElementSibling.style.display="flex")}}):null,(0,t.jsx)("div",{className:"w-16 h-16 rounded-2xl flex items-center justify-center text-white font-bold text-[28px] shrink-0",style:{background:i,display:S.mcp_info?.logo_url?"none":"flex"},children:r.charAt(0).toUpperCase()}),(0,t.jsxs)("div",{className:"flex-1",children:[(0,t.jsx)("h2",{className:"m-0 mb-1 text-[22px] font-bold text-foreground",children:r}),(0,t.jsx)("p",{className:"m-0 text-sm text-muted-foreground",children:S.description??"MCP server"})]}),S.auth_type===ef.AUTH_TYPE.OAUTH2?E.has(S.server_id)?(0,t.jsx)(f.Button,{variant:"destructive",onClick:async()=>{try{await (0,eu.deleteMCPOAuthUserCredential)(e,S.server_id)}catch(e){}O(e=>{let t=new Set(e);return t.delete(S.server_id),t}),P.current(M.current.filter(e=>e!==r))},className:"font-semibold h-[38px] min-w-[110px]",children:"Disconnect"}):(0,t.jsx)(em,{server:S,accessToken:e,onConnect:e=>{O(t=>new Set(t).add(e))},variant:"button"}):(0,t.jsxs)(f.Button,{variant:a?"outline":"default",disabled:n,onClick:()=>D(r,!a,S.server_id),className:"font-semibold h-[38px] min-w-[110px]",children:[n&&(0,t.jsx)(u.Loader2,{className:"h-4 w-4 animate-spin mr-1.5"}),a?"Disconnect":"Connect"]})]}),(0,t.jsx)("h3",{className:"m-0 mb-3 text-[15px] font-semibold text-foreground",children:"Information"}),(0,t.jsx)("div",{className:"border rounded-lg overflow-hidden mb-7",children:[["Server ID",S.server_id],["Transport",(0,ef.handleTransport)(S.transport,S.spec_path)],["Status",a?"Connected":"Not connected"]].filter(([,e])=>e).map(([e,r],s,a)=>(0,t.jsxs)("div",{className:`flex px-4 py-3 text-[13px] ${s(0,t.jsxs)("div",{className:"border rounded-lg px-3.5 py-2.5 bg-muted/30 flex flex-col gap-1.5",children:[(0,t.jsx)(p.Skeleton,{className:"h-3.5 w-1/3"}),(0,t.jsx)(p.Skeleton,{className:"h-3 w-2/3"})]},r))}):0===K.length?(0,t.jsx)("div",{className:"text-muted-foreground text-[13px] py-2",children:"No tools available"}):(0,t.jsx)("div",{className:"flex flex-col gap-2",children:K.map(e=>(0,t.jsxs)("div",{className:"border rounded-lg px-3.5 py-2.5 bg-muted/30",children:[(0,t.jsxs)("div",{className:`flex items-center gap-2 ${e.description?"mb-1":""}`,children:[(0,t.jsx)(c.Wrench,{className:"h-3.5 w-3.5 text-muted-foreground"}),(0,t.jsx)("span",{className:"text-[13px] font-semibold text-foreground font-mono",children:e.name})]}),e.description&&(0,t.jsx)("p",{className:"m-0 text-xs text-muted-foreground pl-[21px]",children:e.description})]},e.name))})]})}return(0,t.jsxs)("div",{className:"w-full",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-5 gap-4 flex-wrap",children:[(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 mb-1",children:[(0,t.jsx)("h2",{className:"m-0 text-lg font-semibold text-foreground",children:"MCP Servers"}),(0,t.jsx)("span",{className:"text-[10px] font-semibold text-primary bg-primary/10 rounded px-1.5 py-0.5 uppercase tracking-wider",children:"Beta"})]}),(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)("p",{className:"m-0 text-[13px] text-muted-foreground",children:"Browse tools, authenticate once, use in chat"}),T?(0,t.jsxs)("span",{className:"flex items-center gap-1.5 text-xs text-muted-foreground",children:[(0,t.jsx)(u.Loader2,{className:"h-3 w-3 animate-spin"}),"Loading tools..."]}):W>0?(0,t.jsxs)("span",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:[(0,t.jsx)(c.Wrench,{className:"h-3 w-3"}),W," tool",1!==W?"s":""," available"]}):null]})]}),(0,t.jsxs)("div",{className:"relative w-[220px]",children:[(0,t.jsx)(i.Search,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground"}),(0,t.jsx)(h.Input,{placeholder:"Search servers...",value:b,onChange:e=>y(e.target.value),className:"pl-9 text-[13px] h-9"})]})]}),(0,t.jsx)(el,{value:w,onValueChange:e=>j(e),className:"mb-4",children:(0,t.jsxs)(ec,{variant:"line",className:"border-b rounded-none w-full justify-start h-auto p-0",children:[(0,t.jsx)(ed,{value:"all",className:"rounded-none px-4 py-2 text-[13px]",children:"All"}),(0,t.jsxs)(ed,{value:"connected",className:"rounded-none px-4 py-2 text-[13px]",children:["Connected",V>0?` (${V})`:""]})]})}),g?(0,t.jsx)("div",{className:"grid grid-cols-2 border rounded-lg overflow-hidden",children:Array.from({length:6},(e,r)=>(0,t.jsxs)("div",{className:`flex items-center gap-3 p-4 ${r%2==0?"border-r":""} ${r<4?"border-b":""}`,children:[(0,t.jsx)(p.Skeleton,{className:"w-[38px] h-[38px] rounded-xl shrink-0"}),(0,t.jsxs)("div",{className:"flex-1 min-w-0 flex flex-col gap-1.5",children:[(0,t.jsx)(p.Skeleton,{className:"h-3.5 w-2/3"}),(0,t.jsx)(p.Skeleton,{className:"h-3 w-1/2"})]})]},r))}):0===B.length?(0,t.jsx)("div",{className:"text-center text-muted-foreground text-[13px] py-12 px-3",children:0===m.length?"No MCP servers configured. Add servers in Tools -> MCP Servers.":"connected"===w?"No servers connected yet.":"No servers match your search."}):(0,t.jsx)("div",{className:"grid grid-cols-2 border rounded-lg overflow-hidden",children:B.map((r,a)=>{let n=U(r),i=s.includes(n),l=eg(n),u=A[n];return(0,t.jsxs)("div",{onClick:()=>C(r),className:`flex items-center gap-3 p-4 bg-card cursor-pointer transition-colors hover:bg-accent/30 min-w-0 ${a%2==0?"border-r":""} ${Math.floor(a/2){let t=e.target;t.style.display="none",t.nextElementSibling&&(t.nextElementSibling.style.display="flex")}}):null,(0,t.jsx)("div",{className:"w-[38px] h-[38px] rounded-xl flex items-center justify-center text-white font-bold text-base shrink-0",style:{background:l,display:r.mcp_info?.logo_url?"none":"flex"},children:n.charAt(0).toUpperCase()}),(0,t.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,t.jsx)("div",{className:"text-sm font-medium text-foreground truncate",children:n}),(0,t.jsxs)("div",{className:"text-xs text-muted-foreground mt-0.5 flex items-center gap-1.5",children:[(0,t.jsx)("span",{className:"truncate",children:r.description??"MCP server"}),void 0!==u?u>0?(0,t.jsxs)("span",{className:"shrink-0 flex items-center gap-1 text-muted-foreground",children:["· ",(0,t.jsx)(c.Wrench,{className:"h-2.5 w-2.5"})," ",u]}):null:T?(0,t.jsx)(p.Skeleton,{className:"w-7 h-3 shrink-0"}):null]})]}),r.auth_type===ef.AUTH_TYPE.OAUTH2?E.has(r.server_id)?(0,t.jsx)(d.CheckCircle,{className:"h-3.5 w-3.5 text-emerald-600 shrink-0"}):(0,t.jsx)(em,{server:r,accessToken:e,onConnect:e=>{O(t=>new Set(t).add(e))},variant:"badge"}):i?(0,t.jsx)("span",{className:"w-[7px] h-[7px] rounded-full bg-emerald-600 dark:bg-emerald-400 shrink-0"}):null,(0,t.jsx)(o.ChevronRight,{className:"h-3 w-3 text-muted-foreground/40 shrink-0"})]},r.server_id)})})]})};function eb(){let{accessToken:e,selectedMCPServers:n,setSelectedMCPServers:i}=(0,a.useChatShell)(),l=(0,s.useRouter)(),o=(0,s.useSearchParams)().get("mcpOauthReturn");return(0,r.useEffect)(()=>{if(o){let e=new URL(window.location.href);e.searchParams.delete("mcpOauthReturn"),l.replace(e.pathname+e.search)}},[o,l]),(0,t.jsx)("div",{className:"flex-1 min-h-0 overflow-auto w-full py-8 px-8",children:(0,t.jsx)(ev,{accessToken:e,selectedServers:n,onChange:i})})}e.s(["default",0,function(){return(0,t.jsx)(r.Suspense,{children:(0,t.jsx)(eb,{})})}],248536)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/02c1-r_khzb89.js b/litellm/proxy/_experimental/out/_next/static/chunks/02c1-r_khzb89.js new file mode 100644 index 00000000000..48e8446d60e --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/02c1-r_khzb89.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,21548,e=>{"use strict";var t=e.i(616303);e.s(["Empty",()=>t.default])},482725,e=>{"use strict";var t=e.i(244451);e.s(["Spin",()=>t.default])},362024,e=>{"use strict";var t=e.i(988122);e.s(["Collapse",()=>t.default])},91979,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M909.1 209.3l-56.4 44.1C775.8 155.1 656.2 92 521.9 92 290 92 102.3 279.5 102 511.5 101.7 743.7 289.8 932 521.9 932c181.3 0 335.8-115 394.6-276.1 1.5-4.2-.7-8.9-4.9-10.3l-56.7-19.5a8 8 0 00-10.1 4.8c-1.8 5-3.8 10-5.9 14.9-17.3 41-42.1 77.8-73.7 109.4A344.77 344.77 0 01655.9 829c-42.3 17.9-87.4 27-133.8 27-46.5 0-91.5-9.1-133.8-27A341.5 341.5 0 01279 755.2a342.16 342.16 0 01-73.7-109.4c-17.9-42.4-27-87.4-27-133.9s9.1-91.5 27-133.9c17.3-41 42.1-77.8 73.7-109.4 31.6-31.6 68.4-56.4 109.3-73.8 42.3-17.9 87.4-27 133.8-27 46.5 0 91.5 9.1 133.8 27a341.5 341.5 0 01109.3 73.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 003 14.1l175.6 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c-.1-6.6-7.8-10.3-13-6.2z"}}]},name:"reload",theme:"outlined"};var l=e.i(9583),o=a.forwardRef(function(e,o){return a.createElement(l.default,(0,t.default)({},e,{ref:o,icon:n}))});e.s(["ReloadOutlined",0,o],91979)},608856,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),n=e.i(209428),l=e.i(392221),o=e.i(951160),r=e.i(174428),s=t.createContext(null),i=t.createContext({}),d=e.i(211577),c=e.i(931067),u=e.i(361275),f=e.i(404948),p=e.i(244009),m=e.i(703923),h=e.i(611935),x=["prefixCls","className","containerRef"];let g=function(e){var n=e.prefixCls,l=e.className,o=e.containerRef,r=(0,m.default)(e,x),s=t.useContext(i).panel,d=(0,h.useComposeRef)(s,o);return t.createElement("div",(0,c.default)({className:(0,a.default)("".concat(n,"-content"),l),role:"dialog",ref:d},(0,p.default)(e,{aria:!0}),{"aria-modal":"true"},r))};var y=e.i(883110);function b(e){return"string"==typeof e&&String(Number(e))===e?((0,y.default)(!1,"Invalid value type of `width` or `height` which should be number type instead."),Number(e)):e}var v={width:0,height:0,overflow:"hidden",outline:"none",position:"absolute"},w=t.forwardRef(function(e,o){var r,i,m,h=e.prefixCls,x=e.open,y=e.placement,w=e.inline,j=e.push,k=e.forceRender,S=e.autoFocus,C=e.keyboard,$=e.classNames,O=e.rootClassName,E=e.rootStyle,z=e.zIndex,_=e.className,N=e.id,I=e.style,R=e.motion,D=e.width,T=e.height,M=e.children,B=e.mask,F=e.maskClosable,P=e.maskMotion,L=e.maskClassName,W=e.maskStyle,A=e.afterOpenChange,K=e.onClose,H=e.onMouseEnter,U=e.onMouseOver,q=e.onMouseLeave,X=e.onClick,Y=e.onKeyDown,J=e.onKeyUp,G=e.styles,V=e.drawerRender,Z=t.useRef(),Q=t.useRef(),ee=t.useRef();t.useImperativeHandle(o,function(){return Z.current}),t.useEffect(function(){if(x&&S){var e;null==(e=Z.current)||e.focus({preventScroll:!0})}},[x]);var et=t.useState(!1),ea=(0,l.default)(et,2),en=ea[0],el=ea[1],eo=t.useContext(s),er=null!=(r=null!=(i=null==(m="boolean"==typeof j?j?{}:{distance:0}:j||{})?void 0:m.distance)?i:null==eo?void 0:eo.pushDistance)?r:180,es=t.useMemo(function(){return{pushDistance:er,push:function(){el(!0)},pull:function(){el(!1)}}},[er]);t.useEffect(function(){var e,t;x?null==eo||null==(e=eo.push)||e.call(eo):null==eo||null==(t=eo.pull)||t.call(eo)},[x]),t.useEffect(function(){return function(){var e;null==eo||null==(e=eo.pull)||e.call(eo)}},[]);var ei=t.createElement(u.default,(0,c.default)({key:"mask"},P,{visible:B&&x}),function(e,l){var o=e.className,r=e.style;return t.createElement("div",{className:(0,a.default)("".concat(h,"-mask"),o,null==$?void 0:$.mask,L),style:(0,n.default)((0,n.default)((0,n.default)({},r),W),null==G?void 0:G.mask),onClick:F&&x?K:void 0,ref:l})}),ed="function"==typeof R?R(y):R,ec={};if(en&&er)switch(y){case"top":ec.transform="translateY(".concat(er,"px)");break;case"bottom":ec.transform="translateY(".concat(-er,"px)");break;case"left":ec.transform="translateX(".concat(er,"px)");break;default:ec.transform="translateX(".concat(-er,"px)")}"left"===y||"right"===y?ec.width=b(D):ec.height=b(T);var eu={onMouseEnter:H,onMouseOver:U,onMouseLeave:q,onClick:X,onKeyDown:Y,onKeyUp:J},ef=t.createElement(u.default,(0,c.default)({key:"panel"},ed,{visible:x,forceRender:k,onVisibleChanged:function(e){null==A||A(e)},removeOnLeave:!1,leavedClassName:"".concat(h,"-content-wrapper-hidden")}),function(l,o){var r=l.className,s=l.style,i=t.createElement(g,(0,c.default)({id:N,containerRef:o,prefixCls:h,className:(0,a.default)(_,null==$?void 0:$.content),style:(0,n.default)((0,n.default)({},I),null==G?void 0:G.content)},(0,p.default)(e,{aria:!0}),eu),M);return t.createElement("div",(0,c.default)({className:(0,a.default)("".concat(h,"-content-wrapper"),null==$?void 0:$.wrapper,r),style:(0,n.default)((0,n.default)((0,n.default)({},ec),s),null==G?void 0:G.wrapper)},(0,p.default)(e,{data:!0})),V?V(i):i)}),ep=(0,n.default)({},E);return z&&(ep.zIndex=z),t.createElement(s.Provider,{value:es},t.createElement("div",{className:(0,a.default)(h,"".concat(h,"-").concat(y),O,(0,d.default)((0,d.default)({},"".concat(h,"-open"),x),"".concat(h,"-inline"),w)),style:ep,tabIndex:-1,ref:Z,onKeyDown:function(e){var t,a,n=e.keyCode,l=e.shiftKey;switch(n){case f.default.TAB:n===f.default.TAB&&(l||document.activeElement!==ee.current?l&&document.activeElement===Q.current&&(null==(a=ee.current)||a.focus({preventScroll:!0})):null==(t=Q.current)||t.focus({preventScroll:!0}));break;case f.default.ESC:K&&C&&(e.stopPropagation(),K(e))}}},ei,t.createElement("div",{tabIndex:0,ref:Q,style:v,"aria-hidden":"true","data-sentinel":"start"}),ef,t.createElement("div",{tabIndex:0,ref:ee,style:v,"aria-hidden":"true","data-sentinel":"end"})))});let j=function(e){var a=e.open,s=e.prefixCls,d=e.placement,c=e.autoFocus,u=e.keyboard,f=e.width,p=e.mask,m=void 0===p||p,h=e.maskClosable,x=e.getContainer,g=e.forceRender,y=e.afterOpenChange,b=e.destroyOnClose,v=e.onMouseEnter,j=e.onMouseOver,k=e.onMouseLeave,S=e.onClick,C=e.onKeyDown,$=e.onKeyUp,O=e.panelRef,E=t.useState(!1),z=(0,l.default)(E,2),_=z[0],N=z[1],I=t.useState(!1),R=(0,l.default)(I,2),D=R[0],T=R[1];(0,r.default)(function(){T(!0)},[]);var M=!!D&&void 0!==a&&a,B=t.useRef(),F=t.useRef();(0,r.default)(function(){M&&(F.current=document.activeElement)},[M]);var P=t.useMemo(function(){return{panel:O}},[O]);if(!g&&!_&&!M&&b)return null;var L=(0,n.default)((0,n.default)({},e),{},{open:M,prefixCls:void 0===s?"rc-drawer":s,placement:void 0===d?"right":d,autoFocus:void 0===c||c,keyboard:void 0===u||u,width:void 0===f?378:f,mask:m,maskClosable:void 0===h||h,inline:!1===x,afterOpenChange:function(e){var t,a;N(e),null==y||y(e),e||!F.current||null!=(t=B.current)&&t.contains(F.current)||null==(a=F.current)||a.focus({preventScroll:!0})},ref:B},{onMouseEnter:v,onMouseOver:j,onMouseLeave:k,onClick:S,onKeyDown:C,onKeyUp:$});return t.createElement(i.Provider,{value:P},t.createElement(o.default,{open:M||g||_,autoDestroy:!1,getContainer:x,autoLock:m&&(M||_)},t.createElement(w,L)))};var k=e.i(981444),S=e.i(617206),C=e.i(122767),$=e.i(613541),O=e.i(340010),E=e.i(242064),z=e.i(922611),_=e.i(563113),N=e.i(185793);let I=e=>{var n,l,o,r;let s,{prefixCls:i,ariaId:d,title:c,footer:u,extra:f,closable:p,loading:m,onClose:h,headerStyle:x,bodyStyle:g,footerStyle:y,children:b,classNames:v,styles:w}=e,j=(0,E.useComponentConfig)("drawer");s=!1===p?void 0:void 0===p||!0===p?"start":(null==p?void 0:p.placement)==="end"?"end":"start";let k=t.useCallback(e=>t.createElement("button",{type:"button",onClick:h,className:(0,a.default)(`${i}-close`,{[`${i}-close-${s}`]:"end"===s})},e),[h,i,s]),[S,C]=(0,_.useClosable)((0,_.pickClosable)(e),(0,_.pickClosable)(j),{closable:!0,closeIconRender:k});return t.createElement(t.Fragment,null,c||S?t.createElement("div",{style:Object.assign(Object.assign(Object.assign({},null==(o=j.styles)?void 0:o.header),x),null==w?void 0:w.header),className:(0,a.default)(`${i}-header`,{[`${i}-header-close-only`]:S&&!c&&!f},null==(r=j.classNames)?void 0:r.header,null==v?void 0:v.header)},t.createElement("div",{className:`${i}-header-title`},"start"===s&&C,c&&t.createElement("div",{className:`${i}-title`,id:d},c)),f&&t.createElement("div",{className:`${i}-extra`},f),"end"===s&&C):null,t.createElement("div",{className:(0,a.default)(`${i}-body`,null==v?void 0:v.body,null==(n=j.classNames)?void 0:n.body),style:Object.assign(Object.assign(Object.assign({},null==(l=j.styles)?void 0:l.body),g),null==w?void 0:w.body)},m?t.createElement(N.default,{active:!0,title:!1,paragraph:{rows:5},className:`${i}-body-skeleton`}):b),(()=>{var e,n;if(!u)return null;let l=`${i}-footer`;return t.createElement("div",{className:(0,a.default)(l,null==(e=j.classNames)?void 0:e.footer,null==v?void 0:v.footer),style:Object.assign(Object.assign(Object.assign({},null==(n=j.styles)?void 0:n.footer),y),null==w?void 0:w.footer)},u)})())};e.i(296059);var R=e.i(915654),D=e.i(183293),T=e.i(246422),M=e.i(838378);let B=(e,t)=>({"&-enter, &-appear":Object.assign(Object.assign({},e),{"&-active":t}),"&-leave":Object.assign(Object.assign({},t),{"&-active":e})}),F=(e,t)=>Object.assign({"&-enter, &-appear, &-leave":{"&-start":{transition:"none"},"&-active":{transition:`all ${t}`}}},B({opacity:e},{opacity:1})),P=(0,T.genStyleHooks)("Drawer",e=>{let t=(0,M.mergeToken)(e,{});return[(e=>{let{borderRadiusSM:t,componentCls:a,zIndexPopup:n,colorBgMask:l,colorBgElevated:o,motionDurationSlow:r,motionDurationMid:s,paddingXS:i,padding:d,paddingLG:c,fontSizeLG:u,lineHeightLG:f,lineWidth:p,lineType:m,colorSplit:h,marginXS:x,colorIcon:g,colorIconHover:y,colorBgTextHover:b,colorBgTextActive:v,colorText:w,fontWeightStrong:j,footerPaddingBlock:k,footerPaddingInline:S,calc:C}=e,$=`${a}-content-wrapper`;return{[a]:{position:"fixed",inset:0,zIndex:n,pointerEvents:"none",color:w,"&-pure":{position:"relative",background:o,display:"flex",flexDirection:"column",[`&${a}-left`]:{boxShadow:e.boxShadowDrawerLeft},[`&${a}-right`]:{boxShadow:e.boxShadowDrawerRight},[`&${a}-top`]:{boxShadow:e.boxShadowDrawerUp},[`&${a}-bottom`]:{boxShadow:e.boxShadowDrawerDown}},"&-inline":{position:"absolute"},[`${a}-mask`]:{position:"absolute",inset:0,zIndex:n,background:l,pointerEvents:"auto"},[$]:{position:"absolute",zIndex:n,maxWidth:"100vw",transition:`all ${r}`,"&-hidden":{display:"none"}},[`&-left > ${$}`]:{top:0,bottom:0,left:{_skip_check_:!0,value:0},boxShadow:e.boxShadowDrawerLeft},[`&-right > ${$}`]:{top:0,right:{_skip_check_:!0,value:0},bottom:0,boxShadow:e.boxShadowDrawerRight},[`&-top > ${$}`]:{top:0,insetInline:0,boxShadow:e.boxShadowDrawerUp},[`&-bottom > ${$}`]:{bottom:0,insetInline:0,boxShadow:e.boxShadowDrawerDown},[`${a}-content`]:{display:"flex",flexDirection:"column",width:"100%",height:"100%",overflow:"auto",background:o,pointerEvents:"auto"},[`${a}-header`]:{display:"flex",flex:0,alignItems:"center",padding:`${(0,R.unit)(d)} ${(0,R.unit)(c)}`,fontSize:u,lineHeight:f,borderBottom:`${(0,R.unit)(p)} ${m} ${h}`,"&-title":{display:"flex",flex:1,alignItems:"center",minWidth:0,minHeight:0}},[`${a}-extra`]:{flex:"none"},[`${a}-close`]:Object.assign({display:"inline-flex",width:C(u).add(i).equal(),height:C(u).add(i).equal(),borderRadius:t,justifyContent:"center",alignItems:"center",color:g,fontWeight:j,fontSize:u,fontStyle:"normal",lineHeight:1,textAlign:"center",textTransform:"none",textDecoration:"none",background:"transparent",border:0,cursor:"pointer",transition:`all ${s}`,textRendering:"auto",[`&${a}-close-end`]:{marginInlineStart:x},[`&:not(${a}-close-end)`]:{marginInlineEnd:x},"&:hover":{color:y,backgroundColor:b,textDecoration:"none"},"&:active":{backgroundColor:v}},(0,D.genFocusStyle)(e)),[`${a}-title`]:{flex:1,margin:0,fontWeight:e.fontWeightStrong,fontSize:u,lineHeight:f},[`${a}-body`]:{flex:1,minWidth:0,minHeight:0,padding:c,overflow:"auto",[`${a}-body-skeleton`]:{width:"100%",height:"100%",display:"flex",justifyContent:"center"}},[`${a}-footer`]:{flexShrink:0,padding:`${(0,R.unit)(k)} ${(0,R.unit)(S)}`,borderTop:`${(0,R.unit)(p)} ${m} ${h}`},"&-rtl":{direction:"rtl"}}}})(t),(e=>{let{componentCls:t,motionDurationSlow:a}=e;return{[t]:{[`${t}-mask-motion`]:F(0,a),[`${t}-panel-motion`]:["left","right","top","bottom"].reduce((e,t)=>{let n;return Object.assign(Object.assign({},e),{[`&-${t}`]:[F(.7,a),B({transform:(n="100%",({left:`translateX(-${n})`,right:`translateX(${n})`,top:`translateY(-${n})`,bottom:`translateY(${n})`})[t])},{transform:"none"})]})},{})}}})(t)]},e=>({zIndexPopup:e.zIndexPopupBase,footerPaddingBlock:e.paddingXS,footerPaddingInline:e.padding}));var L=function(e,t){var a={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&0>t.indexOf(n)&&(a[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var l=0,n=Object.getOwnPropertySymbols(e);lt.indexOf(n[l])&&Object.prototype.propertyIsEnumerable.call(e,n[l])&&(a[n[l]]=e[n[l]]);return a};let W={distance:180},A=e=>{let{rootClassName:n,width:l,height:o,size:r="default",mask:s=!0,push:i=W,open:d,afterOpenChange:c,onClose:u,prefixCls:f,getContainer:p,panelRef:m=null,style:x,className:g,"aria-labelledby":y,visible:b,afterVisibleChange:v,maskStyle:w,drawerStyle:_,contentWrapperStyle:N,destroyOnClose:R,destroyOnHidden:D}=e,T=L(e,["rootClassName","width","height","size","mask","push","open","afterOpenChange","onClose","prefixCls","getContainer","panelRef","style","className","aria-labelledby","visible","afterVisibleChange","maskStyle","drawerStyle","contentWrapperStyle","destroyOnClose","destroyOnHidden"]),M=(0,k.default)(),B=T.title?M:void 0,{getPopupContainer:F,getPrefixCls:A,direction:K,className:H,style:U,classNames:q,styles:X}=(0,E.useComponentConfig)("drawer"),Y=A("drawer",f),[J,G,V]=P(Y),Z=void 0===p&&F?()=>F(document.body):p,Q=(0,a.default)({"no-mask":!s,[`${Y}-rtl`]:"rtl"===K},n,G,V),ee=t.useMemo(()=>null!=l?l:"large"===r?736:378,[l,r]),et=t.useMemo(()=>null!=o?o:"large"===r?736:378,[o,r]),ea={motionName:(0,$.getTransitionName)(Y,"mask-motion"),motionAppear:!0,motionEnter:!0,motionLeave:!0,motionDeadline:500},en=(0,z.usePanelRef)(),el=(0,h.composeRef)(m,en),[eo,er]=(0,C.useZIndex)("Drawer",T.zIndex),{classNames:es={},styles:ei={}}=T;return J(t.createElement(S.default,{form:!0,space:!0},t.createElement(O.default.Provider,{value:er},t.createElement(j,Object.assign({prefixCls:Y,onClose:u,maskMotion:ea,motion:e=>({motionName:(0,$.getTransitionName)(Y,`panel-motion-${e}`),motionAppear:!0,motionEnter:!0,motionLeave:!0,motionDeadline:500})},T,{classNames:{mask:(0,a.default)(es.mask,q.mask),content:(0,a.default)(es.content,q.content),wrapper:(0,a.default)(es.wrapper,q.wrapper)},styles:{mask:Object.assign(Object.assign(Object.assign({},ei.mask),w),X.mask),content:Object.assign(Object.assign(Object.assign({},ei.content),_),X.content),wrapper:Object.assign(Object.assign(Object.assign({},ei.wrapper),N),X.wrapper)},open:null!=d?d:b,mask:s,push:i,width:ee,height:et,style:Object.assign(Object.assign({},U),x),className:(0,a.default)(H,g),rootClassName:Q,getContainer:Z,afterOpenChange:null!=c?c:v,panelRef:el,zIndex:eo,"aria-labelledby":null!=y?y:B,destroyOnClose:null!=D?D:R}),t.createElement(I,Object.assign({prefixCls:Y},T,{ariaId:B,onClose:u}))))))};A._InternalPanelDoNotUseOrYouWillBeFired=e=>{let{prefixCls:n,style:l,className:o,placement:r="right"}=e,s=L(e,["prefixCls","style","className","placement"]),{getPrefixCls:i}=t.useContext(E.ConfigContext),d=i("drawer",n),[c,u,f]=P(d),p=(0,a.default)(d,`${d}-pure`,`${d}-${r}`,u,f,o);return c(t.createElement("div",{className:p,style:l},t.createElement(I,Object.assign({prefixCls:d},s))))},e.s(["Drawer",0,A],608856)},425656,e=>{"use strict";var t=e.i(843476),a=e.i(271645),n=e.i(464571),l=e.i(362024),o=e.i(608856),r=e.i(21548),s=e.i(482725),i=e.i(291542),d=e.i(592968),c=e.i(898586),u=e.i(91979),f=e.i(602869);let{Text:p}=c.Typography,m={pending:"#a1a1aa",running:"#3b82f6",paused:"#f59e0b",completed:"#22c55e",failed:"#ef4444"},h={"step.started":{bar:"#f0fdf4",border:"#86efac",text:"#16a34a"},"step.failed":{bar:"#fef2f2",border:"#fca5a5",text:"#dc2626"},"hook.waiting":{bar:"#fffbeb",border:"#fcd34d",text:"#d97706"},"hook.received":{bar:"#eff6ff",border:"#93c5fd",text:"#2563eb"}};function x(e){let t=Date.now()-new Date(e).getTime();if(isNaN(t))return e;let a=Math.floor(t/1e3);if(a<60)return`${a}s ago`;let n=Math.floor(a/60);if(n<60)return`${n}m ago`;let l=Math.floor(n/60);return l<24?`${l}h ago`:`${Math.floor(l/24)}d ago`}function g(e){return e<0?"":e<1e3?`${e}ms`:`${(e/1e3).toFixed(1)}s`}function y(e){let t=e.metadata?.title;return t?String(t):e.workflow_type??e.run_id.slice(0,8)}function b(e){return e.slice(0,8)}let v=({status:e,size:a=8})=>(0,t.jsx)("span",{style:{display:"inline-block",width:a,height:a,borderRadius:"50%",background:m[e]??"#a1a1aa",flexShrink:0}}),w=({value:e})=>{let[n,l]=(0,a.useState)(!1);return e.length<=120?(0,t.jsx)("span",{style:{color:"#27272a",wordBreak:"break-all"},children:e}):(0,t.jsxs)("span",{style:{color:"#27272a",wordBreak:"break-all"},children:[n?e:e.slice(0,120)+"…",(0,t.jsx)("button",{onClick:()=>l(e=>!e),style:{background:"none",border:"none",padding:"0 4px",cursor:"pointer",color:"#2563eb",fontSize:11,flexShrink:0},children:n?"less":"more"})]})},j=({run:e})=>{let a=e.metadata??{},n=[{key:"state",label:"state"},{key:"worktree_path",label:"worktree"},{key:"grill_session_id",label:"grill session"},{key:"session_id",label:"session"}],l=new Set(["title",...n.map(e=>e.key)]),o=Object.entries(a).filter(([e,t])=>!l.has(e)&&null!=t&&""!==t);return(0,t.jsxs)("div",{style:{borderRadius:8,border:"1px solid #e4e4e7",marginBottom:16,overflow:"hidden"},children:[(0,t.jsxs)("div",{style:{padding:"14px 20px",borderBottom:"1px solid #f4f4f5",display:"flex",alignItems:"center",gap:10},children:[(0,t.jsx)(v,{status:e.status,size:10}),(0,t.jsx)("span",{style:{fontSize:14,fontWeight:600,color:"#18181b",flex:1},children:y(e)}),(0,t.jsx)("span",{style:{fontFamily:"monospace",fontSize:11,color:"#a1a1aa",background:"#f4f4f5",padding:"2px 8px",borderRadius:4},children:b(e.run_id)}),(0,t.jsx)("span",{style:{fontSize:11,color:"#a1a1aa",background:"#f4f4f5",padding:"2px 8px",borderRadius:4},children:e.workflow_type})]}),(0,t.jsxs)("div",{style:{padding:"12px 20px",display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(220px, 1fr))",gap:"8px 24px",fontFamily:"monospace",fontSize:12},children:[(0,t.jsx)(k,{label:"status",children:(0,t.jsx)("span",{style:{textTransform:"capitalize",color:"#27272a"},children:e.status})}),(0,t.jsx)(k,{label:"created",children:(0,t.jsx)("span",{style:{color:"#27272a"},children:x(e.created_at)})}),a.pr_url&&(0,t.jsx)(k,{label:"pr",children:(0,t.jsx)("a",{href:String(a.pr_url),target:"_blank",rel:"noopener noreferrer",style:{color:"#2563eb",textDecoration:"none",wordBreak:"break-all"},children:String(a.pr_url)})}),n.map(({key:e,label:n})=>{let l=a[e];if(null==l||""===l)return null;let o="object"==typeof l?JSON.stringify(l):String(l);return(0,t.jsx)(k,{label:n,children:(0,t.jsx)(w,{value:o})},e)}),o.map(([e,a])=>{let n="object"==typeof a?JSON.stringify(a):String(a);return(0,t.jsx)(k,{label:e,children:(0,t.jsx)(w,{value:n})},e)})]})]})},k=({label:e,children:a})=>(0,t.jsxs)("div",{style:{display:"flex",flexDirection:"column",gap:1},children:[(0,t.jsx)("span",{style:{fontSize:10,color:"#a1a1aa",textTransform:"uppercase",letterSpacing:"0.06em"},children:e}),(0,t.jsx)("span",{style:{fontSize:12},children:a})]}),S=({run:e,events:n})=>{if(0===n.length)return(0,t.jsx)("div",{style:{padding:"16px 0",color:"#a1a1aa",fontSize:12,fontFamily:"monospace"},children:"No events recorded"});let l=new Date(e.created_at).getTime(),o=Math.max(...n.map(e=>new Date(e.created_at).getTime())),r=Math.max(o-l,1),s=g(o-l);return(0,t.jsxs)("div",{style:{fontFamily:"monospace",fontSize:12},children:[(0,t.jsxs)("div",{style:{display:"grid",gridTemplateColumns:"160px 1fr",gap:"0 12px",marginBottom:2},children:[(0,t.jsx)("div",{}),(0,t.jsx)("div",{style:{position:"relative",height:16},children:[0,100].map(e=>(0,t.jsx)("span",{style:{position:"absolute",left:`${e}%`,transform:100===e?"translateX(-100%)":void 0,fontSize:10,color:"#a1a1aa"},children:0===e?"0":s},e))})]}),(0,t.jsxs)("div",{style:{display:"grid",gridTemplateColumns:"160px 1fr",gap:"0 12px",marginBottom:4},children:[(0,t.jsx)("div",{style:{color:"#3f3f46",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",paddingTop:2},children:y(e)}),(0,t.jsx)("div",{style:{height:24,background:"#f4f4f5",border:"1px solid #d4d4d8",borderRadius:4,display:"flex",alignItems:"center",paddingLeft:8},children:(0,t.jsx)("span",{style:{color:"#71717a",fontSize:11},children:s})})]}),(0,t.jsx)("div",{style:{display:"grid",gridTemplateColumns:"160px 1fr",gap:"0 12px",rowGap:3},children:n.map(e=>{let s=new Date(e.created_at).getTime(),i=(s-l)/r*100,c=n.findIndex(t=>t.sequence_number>e.sequence_number),u=c>=0?new Date(n[c].created_at).getTime():o+Math.max(.12*r,500),f=Math.max(8,(u-s)/r*100),p=h[e.event_type]??{bar:"#f4f4f5",border:"#d4d4d8",text:"#52525b"},m=g(u-s);return(0,t.jsxs)(a.default.Fragment,{children:[(0,t.jsx)("div",{style:{color:p.text,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",paddingTop:2,paddingLeft:12},children:e.step_name||e.event_type}),(0,t.jsx)("div",{style:{position:"relative",height:24},children:(0,t.jsx)(d.Tooltip,{title:(0,t.jsxs)("div",{style:{fontFamily:"monospace",fontSize:11,lineHeight:1.6},children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{style:{color:"#a1a1aa"},children:"type: "}),(0,t.jsx)("span",{style:{color:p.text},children:e.event_type})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{style:{color:"#a1a1aa"},children:"step: "}),e.step_name]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{style:{color:"#a1a1aa"},children:"seq: "}),e.sequence_number]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{style:{color:"#a1a1aa"},children:"time: "}),x(e.created_at)]}),e.data&&Object.keys(e.data).length>0&&(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{style:{color:"#a1a1aa"},children:"data: "}),JSON.stringify(e.data)]})]}),children:(0,t.jsxs)("div",{style:{position:"absolute",left:`${Math.min(i,92)}%`,width:`${Math.min(f,100-Math.min(i,92))}%`,height:"100%",background:p.bar,border:`1px solid ${p.border}`,borderRadius:4,display:"flex",alignItems:"center",paddingLeft:8,cursor:"default",overflow:"hidden",gap:6},children:[(0,t.jsx)("span",{style:{color:p.text,whiteSpace:"nowrap",fontSize:11},children:e.event_type}),m&&(0,t.jsx)("span",{style:{color:"#a1a1aa",whiteSpace:"nowrap",fontSize:11},children:m})]})})})]},e.event_id)})})]})},C=({msg:e})=>{let a={user:"#2563eb",assistant:"#16a34a",system:"#7c3aed",tool_result:"#d97706"}[e.role]??"#52525b";return(0,t.jsxs)("div",{style:{display:"grid",gridTemplateColumns:"80px 1fr",gap:"0 16px",padding:"10px 0",borderBottom:"1px solid #f4f4f5",fontFamily:"monospace",fontSize:12,alignItems:"start"},children:[(0,t.jsxs)("span",{style:{color:a,paddingTop:1},children:["[",e.role,"]"]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{style:{color:"#27272a",lineHeight:1.6,whiteSpace:"pre-wrap",wordBreak:"break-word",display:"block"},children:e.content}),(0,t.jsx)("span",{style:{color:"#a1a1aa",fontSize:11,marginTop:2,display:"block"},children:x(e.created_at)})]})]})},$=({accessToken:e})=>{let[d,c]=(0,a.useState)([]),[p,m]=(0,a.useState)(!1),[h,g]=(0,a.useState)(null),[w,k]=(0,a.useState)([]),[$,O]=(0,a.useState)([]),[E,z]=(0,a.useState)(!1),[_,N]=(0,a.useState)(!1),I=(0,a.useCallback)(async()=>{if(e){m(!0);try{let t=await fetch(`${f.proxyBaseUrl??""}/v1/workflows/runs?limit=100`,{headers:{Authorization:`Bearer ${e}`}});if(!t.ok)throw Error(`HTTP ${t.status}`);let a=await t.json();c(a.runs??[])}catch(e){console.error("workflow runs fetch failed:",e)}finally{m(!1)}}},[e]),R=(0,a.useCallback)(async t=>{if(e){g(t),N(!0),z(!0),k([]),O([]);try{let a=f.proxyBaseUrl??"",[n,l]=await Promise.all([fetch(`${a}/v1/workflows/runs/${t.run_id}/events`,{headers:{Authorization:`Bearer ${e}`}}),fetch(`${a}/v1/workflows/runs/${t.run_id}/messages`,{headers:{Authorization:`Bearer ${e}`}})]),o=n.ok?await n.json():{events:[]},r=l.ok?await l.json():{messages:[]};k([...o.events??[]].sort((e,t)=>e.sequence_number-t.sequence_number)),O([...r.messages??[]].sort((e,t)=>e.sequence_number-t.sequence_number))}catch(e){console.error("workflow run detail fetch failed:",e)}finally{z(!1)}}},[e]);(0,a.useEffect)(()=>{I()},[I]);let D=[{title:"Run",dataIndex:"run_id",key:"run",render:(e,a)=>(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:8},children:[(0,t.jsx)(v,{status:a.status,size:7}),(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{style:{fontSize:13,color:"#18181b",fontWeight:500,lineHeight:1.4},children:y(a)}),(0,t.jsx)("div",{style:{fontFamily:"monospace",fontSize:11,color:"#a1a1aa"},children:b(a.run_id)})]})]})},{title:"Type",dataIndex:"workflow_type",key:"workflow_type",render:e=>(0,t.jsx)("span",{style:{fontFamily:"monospace",fontSize:12,color:"#71717a"},children:e})},{title:"Status",dataIndex:"status",key:"status",render:(e,a)=>{let n=a.metadata?.state;return(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:6},children:[(0,t.jsx)(v,{status:e,size:7}),(0,t.jsx)("span",{style:{fontSize:12,color:"#52525b",textTransform:"capitalize"},children:n??e})]})}},{title:"Created",dataIndex:"created_at",key:"created_at",render:e=>(0,t.jsx)("span",{style:{fontSize:12,color:"#a1a1aa"},children:x(e)})}];return(0,t.jsxs)("div",{style:{width:"100%",padding:"24px 32px",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',minHeight:"calc(100vh - 64px)",background:"#fff"},children:[(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:20},children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{style:{fontSize:18,fontWeight:600,color:"#18181b"},children:"Workflow Runs"}),(0,t.jsx)("div",{style:{fontSize:13,color:"#71717a",marginTop:2},children:"Durable state tracking for agents and automated workflows"})]}),(0,t.jsx)(n.Button,{icon:(0,t.jsx)(u.ReloadOutlined,{}),onClick:I,loading:p,style:{color:"#71717a",borderColor:"#e4e4e7"},children:"Refresh"})]}),(0,t.jsx)("div",{className:"rounded-lg custom-border overflow-x-auto w-full",children:(0,t.jsx)(i.Table,{dataSource:d,columns:D,rowKey:"run_id",loading:p,size:"small",pagination:{pageSize:50,hideOnSinglePage:!0,size:"small"},onRow:e=>({onClick:()=>R(e),style:{cursor:"pointer"}}),locale:{emptyText:(0,t.jsx)(r.Empty,{description:(0,t.jsx)("span",{style:{color:"#a1a1aa",fontSize:13},children:"No workflow runs yet"}),image:r.Empty.PRESENTED_IMAGE_SIMPLE})},className:"[&_.ant-table-cell]:py-0.5 [&_.ant-table-thead_.ant-table-cell]:py-1",style:{border:"none"}})}),(0,t.jsx)(o.Drawer,{open:_,onClose:()=>N(!1),width:680,title:null,closable:!1,bodyStyle:{padding:0},styles:{body:{padding:0}},children:h?E?(0,t.jsx)("div",{style:{display:"flex",justifyContent:"center",padding:80},children:(0,t.jsx)(s.Spin,{})}):(0,t.jsxs)("div",{style:{padding:"24px 28px",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'},children:[(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:16},children:[(0,t.jsx)("button",{onClick:()=>N(!1),style:{background:"none",border:"none",cursor:"pointer",padding:"4px 0",fontSize:12,color:"#a1a1aa",display:"flex",alignItems:"center",gap:4},children:"← close"}),(0,t.jsx)(n.Button,{size:"small",icon:(0,t.jsx)(u.ReloadOutlined,{}),onClick:()=>R(h),loading:E,style:{color:"#71717a",borderColor:"#e4e4e7"},children:"Refresh"})]}),(0,t.jsx)(j,{run:h}),(0,t.jsx)(l.Collapse,{defaultActiveKey:["timeline"],ghost:!1,style:{border:"1px solid #e4e4e7",borderRadius:8,overflow:"hidden"},items:[{key:"timeline",label:(0,t.jsxs)("span",{style:{fontSize:12,fontWeight:500,color:"#3f3f46"},children:["Timeline",(0,t.jsxs)("span",{style:{marginLeft:6,fontSize:11,color:"#a1a1aa",fontWeight:400},children:[w.length," ",1===w.length?"event":"events"]})]}),children:(0,t.jsx)("div",{style:{padding:"4px 4px 12px"},children:(0,t.jsx)(S,{run:h,events:w})})},{key:"messages",label:(0,t.jsxs)("span",{style:{fontSize:12,fontWeight:500,color:"#3f3f46"},children:["Messages",(0,t.jsx)("span",{style:{marginLeft:6,fontSize:11,color:"#a1a1aa",fontWeight:400},children:$.length})]}),children:0===$.length?(0,t.jsx)("div",{style:{padding:"12px 4px",color:"#a1a1aa",fontSize:12,fontFamily:"monospace"},children:"No messages"}):(0,t.jsx)("div",{style:{paddingBottom:4},children:$.map(e=>(0,t.jsx)(C,{msg:e},e.message_id))})}]})]}):null})]})};var O=e.i(135214);e.s(["default",0,function(){let{accessToken:e}=(0,O.default)();return(0,t.jsx)($,{accessToken:e})}],425656)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/02eah8_db3ldv.js b/litellm/proxy/_experimental/out/_next/static/chunks/02eah8_db3ldv.js new file mode 100644 index 00000000000..74495e8e91e --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/02eah8_db3ldv.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,250980,e=>{"use strict";var l=e.i(271645);let s=l.forwardRef(function(e,s){return l.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:s},e),l.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z"}))});e.s(["PlusCircleIcon",0,s],250980)},695411,e=>{"use strict";var l=e.i(602869);let s=async e=>{try{let s=await (0,l.modelHubCall)(e);if(s?.data.length>0){let e=s.data.map(e=>({model_group:e.model_group,mode:e?.mode}));return e.sort((e,l)=>e.model_group.localeCompare(l.model_group)),e}return[]}catch(e){throw console.error("Error fetching model info:",e),e}};e.s(["fetchAvailableModels",0,s])},841947,e=>{"use strict";let l=(0,e.i(475254).default)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);e.s(["default",0,l])},603908,e=>{"use strict";let l=(0,e.i(475254).default)("plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]);e.s(["default",0,l])},107233,e=>{"use strict";var l=e.i(603908);e.s(["Plus",()=>l.default])},37727,e=>{"use strict";var l=e.i(841947);e.s(["X",()=>l.default])},158392,63209,e=>{"use strict";var l=e.i(843476),s=e.i(311451);let t={ttl:3600,lowest_latency_buffer:0},r=({routingStrategyArgs:e})=>{let r={ttl:"Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)("div",{className:"space-y-6",children:[(0,l.jsxs)("div",{className:"max-w-3xl",children:[(0,l.jsx)("h3",{className:"text-sm font-medium text-gray-900",children:"Latency-Based Configuration"}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mt-1",children:"Fine-tune latency-based routing behavior"})]}),(0,l.jsx)("div",{className:"grid grid-cols-1 gap-6 lg:grid-cols-2 xl:grid-cols-3",children:Object.entries(e||t).map(([e,t])=>(0,l.jsx)("div",{className:"space-y-2",children:(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("span",{className:"text-xs font-medium text-gray-700 uppercase tracking-wide",children:e.replace(/_/g," ")}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mt-0.5 mb-2",children:r[e]||""}),(0,l.jsx)(s.Input,{name:e,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t?.toString(),className:"font-mono text-sm w-full"})]})},e))})]}),(0,l.jsx)("div",{className:"border-t border-gray-200"})]})},a=({routerSettings:e,routerFieldsMetadata:t})=>(0,l.jsxs)("div",{className:"space-y-6",children:[(0,l.jsxs)("div",{className:"max-w-3xl",children:[(0,l.jsx)("h3",{className:"text-sm font-medium text-gray-900",children:"Reliability & Retries"}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mt-1",children:"Configure retry logic and failure handling"})]}),(0,l.jsx)("div",{className:"grid grid-cols-1 gap-6 lg:grid-cols-2 xl:grid-cols-3",children:Object.entries(e).filter(([e])=>"fallbacks"!=e&&"context_window_fallbacks"!=e&&"routing_strategy_args"!=e&&"routing_strategy"!=e&&"enable_tag_filtering"!=e&&"retry_policy"!=e&&"model_group_retry_policy"!=e&&"routing_groups"!=e).map(([e,r])=>(0,l.jsx)("div",{className:"space-y-2",children:(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("span",{className:"text-xs font-medium text-gray-700 uppercase tracking-wide",children:t[e]?.ui_field_name||e}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mt-0.5 mb-2",children:t[e]?.field_description||""}),(0,l.jsx)(s.Input,{name:e,defaultValue:null==r||"null"===r?"":"object"==typeof r?JSON.stringify(r,null,2):r?.toString()||"",placeholder:"—",className:"font-mono text-sm w-full"})]})},e))})]});var i=e.i(199133);let n=({selectedStrategy:e,availableStrategies:s,routingStrategyDescriptions:t,routerFieldsMetadata:r,onStrategyChange:a})=>(0,l.jsxs)("div",{className:"space-y-2 max-w-3xl",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{className:"text-xs font-medium text-gray-700 uppercase tracking-wide",children:r.routing_strategy?.ui_field_name||"Routing Strategy"}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mt-0.5 mb-2",children:r.routing_strategy?.field_description||""})]}),(0,l.jsx)("div",{className:"routing-strategy-select max-w-3xl",children:(0,l.jsx)(i.Select,{value:e,onChange:a,style:{width:"100%"},size:"large",children:s.map(e=>(0,l.jsx)(i.Select.Option,{value:e,label:e,children:(0,l.jsxs)("div",{className:"flex flex-col gap-0.5 py-1",children:[(0,l.jsx)("span",{className:"font-mono text-sm font-medium",children:e}),t[e]&&(0,l.jsx)("span",{className:"text-xs text-gray-500 font-normal",children:t[e]})]})},e))})})]});var o=e.i(790848);let c=({enabled:e,routerFieldsMetadata:s,onToggle:t})=>(0,l.jsx)("div",{className:"space-y-3 max-w-3xl",children:(0,l.jsxs)("div",{className:"flex items-start justify-between",children:[(0,l.jsxs)("div",{className:"flex-1",children:[(0,l.jsx)("label",{className:"text-xs font-medium text-gray-700 uppercase tracking-wide",children:s.enable_tag_filtering?.ui_field_name||"Enable Tag Filtering"}),(0,l.jsxs)("p",{className:"text-xs text-gray-500 mt-0.5",children:[s.enable_tag_filtering?.field_description||"",s.enable_tag_filtering?.link&&(0,l.jsxs)(l.Fragment,{children:[" ",(0,l.jsx)("a",{href:s.enable_tag_filtering.link,target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:text-blue-800 underline",children:"Learn more"})]})]})]}),(0,l.jsx)(o.Switch,{checked:e,onChange:t,className:"ml-4"})]})});e.s(["default",0,({value:e,onChange:s,routerFieldsMetadata:t,availableRoutingStrategies:i,routingStrategyDescriptions:o})=>(0,l.jsxs)("div",{className:"w-full space-y-8 py-2",children:[(0,l.jsxs)("div",{className:"space-y-6",children:[(0,l.jsxs)("div",{className:"max-w-3xl",children:[(0,l.jsx)("h3",{className:"text-sm font-medium text-gray-900",children:"Routing Settings"}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mt-1",children:"Configure how requests are routed to deployments"})]}),i.length>0&&(0,l.jsx)(n,{selectedStrategy:e.selectedStrategy||e.routerSettings.routing_strategy||null,availableStrategies:i,routingStrategyDescriptions:o,routerFieldsMetadata:t,onStrategyChange:l=>{s({...e,selectedStrategy:l})}}),(0,l.jsx)(c,{enabled:e.enableTagFiltering,routerFieldsMetadata:t,onToggle:l=>{s({...e,enableTagFiltering:l})}})]}),(0,l.jsx)("div",{className:"border-t border-gray-200"}),"latency-based-routing"===e.selectedStrategy&&(0,l.jsx)(r,{routingStrategyArgs:e.routerSettings.routing_strategy_args}),(0,l.jsx)(a,{routerSettings:e.routerSettings,routerFieldsMetadata:t})]})],158392);var d=e.i(361653);e.s(["AlertCircle",()=>d.default],63209)},425063,e=>{"use strict";let l=(0,e.i(475254).default)("arrow-down",[["path",{d:"M12 5v14",key:"s699le"}],["path",{d:"m19 12-7 7-7-7",key:"1idqje"}]]);e.s(["ArrowDown",0,l],425063)},419470,e=>{"use strict";var l=e.i(843476),s=e.i(994388),t=e.i(653496),r=e.i(107233),a=e.i(271645),i=e.i(888259),n=e.i(199133),o=e.i(592968),c=e.i(63209),d=e.i(425063),m=e.i(37727);function u({group:e,onChange:s,availableModels:t,maxFallbacks:r}){let a=t.filter(l=>l!==e.primaryModel),i=e.fallbackModels.length{let t=[...e.fallbackModels];t.includes(l)&&(t=t.filter(e=>e!==l)),s({...e,primaryModel:l,fallbackModels:t})},showSearch:!0,getPopupContainer:e=>e.parentElement||document.body,filterOption:(e,l)=>(l?.label??"").toLowerCase().includes(e.toLowerCase()),options:t.map(e=>({label:e,value:e}))}),!e.primaryModel&&(0,l.jsxs)("div",{className:"mt-2 flex items-center gap-2 text-amber-600 text-xs bg-amber-50 p-2 rounded-sm",children:[(0,l.jsx)(c.AlertCircle,{className:"w-4 h-4"}),(0,l.jsx)("span",{children:"Select a model to begin configuring fallbacks"})]})]}),(0,l.jsx)("div",{className:"flex items-center justify-center -my-4 z-10",children:(0,l.jsxs)("div",{className:"bg-indigo-50 text-indigo-500 px-4 py-1 rounded-full text-xs font-bold border border-indigo-100 flex items-center gap-2 shadow-xs",children:[(0,l.jsx)(d.ArrowDown,{className:"w-4 h-4"}),"IF FAILS, TRY..."]})}),(0,l.jsxs)("div",{className:`transition-opacity duration-300 ${!e.primaryModel?"opacity-50 pointer-events-none":"opacity-100"}`,children:[(0,l.jsxs)("label",{className:"block text-sm font-semibold text-gray-700 mb-2",children:["Fallback Chain ",(0,l.jsx)("span",{className:"text-red-500",children:"*"}),(0,l.jsxs)("span",{className:"text-xs text-gray-500 font-normal ml-2",children:["(Max ",r," fallbacks at a time)"]})]}),(0,l.jsxs)("div",{className:"bg-gray-50 rounded-xl p-4 border border-gray-200",children:[(0,l.jsxs)("div",{className:"mb-4",children:[(0,l.jsx)(n.Select,{mode:"multiple",className:"w-full",size:"large",placeholder:i?"Select fallback models to add...":`Maximum ${r} fallbacks reached`,value:e.fallbackModels,onChange:l=>{let t=l.slice(0,r);s({...e,fallbackModels:t})},disabled:!e.primaryModel,getPopupContainer:e=>e.parentElement||document.body,options:a.map(e=>({label:e,value:e})),optionRender:(s,t)=>{let r=e.fallbackModels.includes(s.value),a=r?e.fallbackModels.indexOf(s.value)+1:null;return(0,l.jsxs)("div",{className:"flex items-center gap-2",children:[r&&null!==a&&(0,l.jsx)("span",{className:"flex items-center justify-center w-5 h-5 rounded-sm bg-indigo-100 text-indigo-600 text-xs font-bold",children:a}),(0,l.jsx)("span",{children:s.label})]})},maxTagCount:"responsive",maxTagPlaceholder:e=>(0,l.jsx)(o.Tooltip,{styles:{root:{pointerEvents:"none"}},title:e.map(({value:e})=>e).join(", "),children:(0,l.jsxs)("span",{children:["+",e.length," more"]})}),showSearch:!0,filterOption:(e,l)=>(l?.label??"").toLowerCase().includes(e.toLowerCase())}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mt-1 ml-1",children:i?`Search and select multiple models. Selected models will appear below in order. (${e.fallbackModels.length}/${r} used)`:`Maximum ${r} fallbacks reached. Remove some to add more.`})]}),(0,l.jsx)("div",{className:"space-y-2 min-h-[100px]",children:0===e.fallbackModels.length?(0,l.jsxs)("div",{className:"h-32 border-2 border-dashed border-gray-300 rounded-lg flex flex-col items-center justify-center text-gray-400",children:[(0,l.jsx)("span",{className:"text-sm",children:"No fallback models selected"}),(0,l.jsx)("span",{className:"text-xs mt-1",children:"Add models from the dropdown above"})]}):e.fallbackModels.map((t,r)=>(0,l.jsxs)("div",{className:"group flex items-center justify-between p-3 bg-white rounded-lg border border-gray-200 hover:border-indigo-300 hover:shadow-xs transition-all",children:[(0,l.jsxs)("div",{className:"flex items-center gap-3",children:[(0,l.jsx)("div",{className:"flex items-center justify-center w-6 h-6 rounded-sm bg-gray-100 text-gray-400 group-hover:text-indigo-500 group-hover:bg-indigo-50",children:(0,l.jsx)("span",{className:"text-xs font-bold",children:r+1})}),(0,l.jsx)("div",{children:(0,l.jsx)("span",{className:"font-medium text-gray-800",children:t})})]}),(0,l.jsx)("button",{type:"button",onClick:()=>{let l;return l=e.fallbackModels.filter((e,l)=>l!==r),void s({...e,fallbackModels:l})},className:"opacity-0 group-hover:opacity-100 transition-opacity text-gray-400 hover:text-red-500 p-1",children:(0,l.jsx)(m.X,{className:"w-4 h-4"})})]},`${t}-${r}`))})]})]})]})}e.s(["FallbackSelectionForm",0,function({groups:e,onGroupsChange:n,availableModels:o,maxFallbacks:c=10,maxGroups:d=5}){let[m,g]=(0,a.useState)(e.length>0?e[0].id:"1");(0,a.useEffect)(()=>{e.length>0?e.some(e=>e.id===m)||g(e[0].id):g("1")},[e]);let p=()=>{if(e.length>=d)return;let l=Date.now().toString();n([...e,{id:l,primaryModel:null,fallbackModels:[]}]),g(l)},h=l=>{n(e.map(e=>e.id===l.id?l:e))},x=e.map((s,t)=>{let r=s.primaryModel?s.primaryModel:`Group ${t+1}`;return{key:s.id,label:r,closable:e.length>1,children:(0,l.jsx)(u,{group:s,onChange:h,availableModels:o,maxFallbacks:c})}});return 0===e.length?(0,l.jsxs)("div",{className:"text-center py-12 bg-gray-50 rounded-lg border border-dashed border-gray-300",children:[(0,l.jsx)("p",{className:"text-gray-500 mb-4",children:"No fallback groups configured"}),(0,l.jsx)(s.Button,{variant:"primary",onClick:p,icon:()=>(0,l.jsx)(r.Plus,{className:"w-4 h-4"}),children:"Create First Group"})]}):(0,l.jsx)(t.Tabs,{type:"editable-card",activeKey:m,onChange:g,onEdit:(l,s)=>{"add"===s?p():"remove"===s&&e.length>1&&(l=>{if(1===e.length)return i.default.warning("At least one group is required");let s=e.filter(e=>e.id!==l);n(s),m===l&&s.length>0&&g(s[s.length-1].id)})(l)},items:x,className:"fallback-tabs",tabBarStyle:{marginBottom:0},hideAdd:e.length>=d})}],419470)},246349,e=>{"use strict";let l=(0,e.i(475254).default)("chevron-right",[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]]);e.s(["default",0,l])},992619,e=>{"use strict";var l=e.i(843476),s=e.i(271645),t=e.i(779241),r=e.i(599724),a=e.i(199133),i=e.i(983561),n=e.i(695411);e.s(["default",0,({accessToken:e,value:o,placeholder:c="Select a Model",onChange:d,disabled:m=!1,style:u,className:g,showLabel:p=!0,labelText:h="Select Model"})=>{let[x,f]=(0,s.useState)(o),[y,b]=(0,s.useState)(!1),[v,j]=(0,s.useState)([]),w=(0,s.useRef)(null);return(0,s.useEffect)(()=>{f(o)},[o]),(0,s.useEffect)(()=>{e&&(async()=>{try{let l=await (0,n.fetchAvailableModels)(e);l.length>0&&j(l)}catch(e){console.error("Error fetching model info:",e)}})()},[e]),(0,l.jsxs)("div",{children:[p&&(0,l.jsxs)(r.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,l.jsx)(i.RobotOutlined,{className:"mr-2"})," ",h]}),(0,l.jsx)(a.Select,{value:x,placeholder:c,onChange:e=>{"custom"===e?(b(!0),f(void 0)):(b(!1),f(e),d&&d(e))},options:[...Array.from(new Set(v.map(e=>e.model_group))).map((e,l)=>({value:e,label:e,key:l})),{value:"custom",label:"Enter custom model",key:"custom"}],style:{width:"100%",...u},showSearch:!0,className:`rounded-md ${g||""}`,disabled:m}),y&&(0,l.jsx)(t.TextInput,{className:"mt-2",placeholder:"Enter custom model name",onValueChange:e=>{w.current&&clearTimeout(w.current),w.current=setTimeout(()=>{f(e),d&&d(e)},500)},disabled:m})]})}])},91739,e=>{"use strict";var l=e.i(544195);e.s(["Radio",()=>l.default])},988297,e=>{"use strict";var l=e.i(271645);let s=l.forwardRef(function(e,s){return l.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:s},e),l.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 4v16m8-8H4"}))});e.s(["PlusIcon",0,s],988297)},797672,e=>{"use strict";var l=e.i(271645);let s=l.forwardRef(function(e,s){return l.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:s},e),l.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"}))});e.s(["PencilIcon",0,s],797672)},361653,e=>{"use strict";let l=(0,e.i(475254).default)("circle-alert",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]]);e.s(["default",0,l])},409797,e=>{"use strict";var l=e.i(631171);e.s(["ChevronDownIcon",()=>l.default])},531516,696609,e=>{"use strict";var l=e.i(843476),s=e.i(271645),t=e.i(536916),r=e.i(599724),a=e.i(409797),i=e.i(246349),i=i;let n=/\b(delete|remove|destroy|purge|drop|erase|unlink)\b/i,o=/\b(create|add|insert|new|post|submit|register|make|generate|write|upload)\b/i,c=/\b(update|edit|modify|change|patch|put|set|rename|move|transform)\b/i,d=/\b(get|read|list|fetch|search|find|query|retrieve|show|view|check|describe|info)\b/i;function m(e,l=""){let s=e.toLowerCase();if(d.test(s))return"read";if(n.test(s))return"delete";if(c.test(s))return"update";if(o.test(s))return"create";if(l){let e=l.toLowerCase();if(d.test(e))return"read";if(n.test(e))return"delete";if(c.test(e))return"update";if(o.test(e))return"create"}return"unknown"}function u(e){let l={read:[],create:[],update:[],delete:[],unknown:[]};for(let s of e)l[m(s.name,s.description)].push(s);return l}let g={read:{label:"Read",description:"Safe operations — fetch, list, search. No side effects.",risk:"low"},create:{label:"Create",description:"Add new resources — insert, upload, register.",risk:"medium"},update:{label:"Update",description:"Modify existing resources — edit, patch, rename.",risk:"medium"},delete:{label:"Delete",description:"Destructive operations — remove, purge, destroy.",risk:"high"},unknown:{label:"Other",description:"Operations that could not be automatically classified.",risk:"unknown"}};e.s(["CRUD_GROUP_META",0,g,"classifyToolOp",0,m,"groupToolsByCrud",0,u],696609);let p=["read","create","update","delete","unknown"],h={low:"bg-green-100 text-green-800",medium:"bg-yellow-100 text-yellow-800",high:"bg-red-100 text-red-800 font-semibold",unknown:"bg-gray-100 text-gray-700"},x={read:"border-green-200",create:"border-blue-200",update:"border-yellow-200",delete:"border-red-300",unknown:"border-gray-200"},f={read:"bg-green-50",create:"bg-blue-50",update:"bg-yellow-50",delete:"bg-red-50",unknown:"bg-gray-50"};e.s(["default",0,({tools:e,value:n,onChange:o,readOnly:c=!1,searchFilter:d=""})=>{let[m,y]=(0,s.useState)({read:!1,create:!1,update:!1,delete:!1,unknown:!0}),b=(0,s.useMemo)(()=>u(e),[e]),v=(0,s.useMemo)(()=>new Set(void 0===n?e.map(e=>e.name):n),[n,e]),j=e=>{if(c)return;let l=new Set(v);l.has(e)?l.delete(e):l.add(e),o(Array.from(l))};return 0===e.length?null:(0,l.jsx)("div",{className:"space-y-3",children:p.map(e=>{let s,n=b[e];if(0===n.length)return null;if(d){let e=d.toLowerCase();if(!n.some(l=>l.name.toLowerCase().includes(e)||(l.description??"").toLowerCase().includes(e)))return null}let u=g[e],p=(s=b[e]).length>0&&s.every(e=>v.has(e.name)),w=(e=>{let l=b[e];if(0===l.length)return!1;let s=l.filter(e=>v.has(e.name)).length;return s>0&&s{y(l=>({...l,[e]:!l[e]}))},children:[N?(0,l.jsx)(i.default,{className:"w-4 h-4 text-gray-500 shrink-0"}):(0,l.jsx)(a.ChevronDownIcon,{className:"w-4 h-4 text-gray-500 shrink-0"}),(0,l.jsx)("span",{className:"font-semibold text-gray-900 text-sm",children:u.label}),(0,l.jsx)("span",{className:`text-xs px-2 py-0.5 rounded-full ${h[u.risk]}`,children:"high"===u.risk?"High Risk":"medium"===u.risk?"Medium Risk":"low"===u.risk?"Safe":"Unclassified"}),(0,l.jsxs)("span",{className:"text-xs text-gray-500 ml-1",children:[n.filter(e=>v.has(e.name)).length,"/",n.length," allowed"]})]}),!c&&(0,l.jsxs)("div",{className:"flex items-center gap-2 ml-4",children:[(0,l.jsx)(r.Text,{className:"text-xs text-gray-500",children:p?"All on":w?"Partial":"All off"}),(0,l.jsx)(t.Checkbox,{checked:p,indeterminate:w,onChange:l=>((e,l)=>{if(c)return;let s=new Set(v);for(let t of b[e])l?s.add(t.name):s.delete(t.name);o(Array.from(s))})(e,l.target.checked),onClick:e=>e.stopPropagation()})]})]}),!N&&(0,l.jsx)("div",{className:"px-4 pt-2 pb-1 text-xs text-gray-500 bg-white border-b border-gray-100",children:u.description}),!N&&(0,l.jsx)("div",{className:"bg-white divide-y divide-gray-50",children:n.filter(e=>!d||e.name.toLowerCase().includes(d.toLowerCase())||(e.description??"").toLowerCase().includes(d.toLowerCase())).map(e=>{let s,a=(s=e.name,v.has(s));return(0,l.jsxs)("div",{className:`flex items-start gap-3 px-4 py-2.5 transition-colors hover:bg-gray-50 ${!c?"cursor-pointer":""} ${a?"":"opacity-60"}`,onClick:()=>j(e.name),children:[(0,l.jsx)(t.Checkbox,{checked:a,onChange:()=>j(e.name),disabled:c,onClick:e=>e.stopPropagation()}),(0,l.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,l.jsx)(r.Text,{className:"font-medium text-gray-900 text-sm",children:e.name}),e.description&&(0,l.jsx)(r.Text,{className:"text-xs text-gray-500 mt-0.5 leading-snug",children:e.description})]}),(0,l.jsx)("span",{className:`text-xs px-1.5 py-0.5 rounded shrink-0 ${a?"bg-green-100 text-green-700":"bg-gray-100 text-gray-500"}`,children:a?"on":"off"})]},e.name)})})]},e)})})}],531516)},309426,e=>{"use strict";var l=e.i(290571),s=e.i(444755),t=e.i(673706),r=e.i(271645),a=e.i(46757);let i=(0,t.makeClassName)("Col"),n=r.default.forwardRef((e,t)=>{let n,o,c,d,{numColSpan:m=1,numColSpanSm:u,numColSpanMd:g,numColSpanLg:p,children:h,className:x}=e,f=(0,l.__rest)(e,["numColSpan","numColSpanSm","numColSpanMd","numColSpanLg","children","className"]),y=(e,l)=>e&&Object.keys(l).includes(String(e))?l[e]:"";return r.default.createElement("div",Object.assign({ref:t,className:(0,s.tremorTwMerge)(i("root"),(n=y(m,a.colSpan),o=y(u,a.colSpanSm),c=y(g,a.colSpanMd),d=y(p,a.colSpanLg),(0,s.tremorTwMerge)(n,o,c,d)),x)},f),h)});n.displayName="Col",e.s(["Col",0,n],309426)},213205,e=>{"use strict";e.i(247167);var l=e.i(931067),s=e.i(271645);let t={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M678.3 642.4c24.2-13 51.9-20.4 81.4-20.4h.1c3 0 4.4-3.6 2.2-5.6a371.67 371.67 0 00-103.7-65.8c-.4-.2-.8-.3-1.2-.5C719.2 505 759.6 431.7 759.6 349c0-137-110.8-248-247.5-248S264.7 212 264.7 349c0 82.7 40.4 156 102.6 201.1-.4.2-.8.3-1.2.5-44.7 18.9-84.8 46-119.3 80.6a373.42 373.42 0 00-80.4 119.5A373.6 373.6 0 00137 888.8a8 8 0 008 8.2h59.9c4.3 0 7.9-3.5 8-7.8 2-77.2 32.9-149.5 87.6-204.3C357 628.2 432.2 597 512.2 597c56.7 0 111.1 15.7 158 45.1a8.1 8.1 0 008.1.3zM512.2 521c-45.8 0-88.9-17.9-121.4-50.4A171.2 171.2 0 01340.5 349c0-45.9 17.9-89.1 50.3-121.6S466.3 177 512.2 177s88.9 17.9 121.4 50.4A171.2 171.2 0 01683.9 349c0 45.9-17.9 89.1-50.3 121.6C601.1 503.1 558 521 512.2 521zM880 759h-84v-84c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v84h-84c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h84v84c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-84h84c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8z"}}]},name:"user-add",theme:"outlined"};var r=e.i(9583),a=s.forwardRef(function(e,a){return s.createElement(r.default,(0,l.default)({},e,{ref:a,icon:t}))});e.s(["UserAddOutlined",0,a],213205)},355619,e=>{"use strict";var l=e.i(602869);let s=async(e,s,t)=>{try{if(null===e||null===s)return;if(null!==t){let r=(await (0,l.modelAvailableCall)(t,e,s,!0,null,!0)).data.map(e=>e.id),a=[],i=[];return r.forEach(e=>{e.endsWith("/*")?a.push(e):i.push(e)}),[...a,...i]}}catch(e){console.error("Error fetching user models:",e)}};e.s(["fetchAvailableModelsForTeamOrKey",0,s,"getModelDisplayName",0,e=>{if("all-proxy-models"===e)return"All Proxy Models";if(e.endsWith("/*")){let l=e.replace("/*","");return`All ${l} models`}return e},"unfurlWildcardModelsInList",0,(e,l)=>{let s=[],t=[];return e.forEach(e=>{if(e.endsWith("/*")){let r=e.replace("/*",""),a=l.filter(e=>e.startsWith(r+"/"));t.push(...a),s.push(e)}else t.push(e)}),[...s,...t].filter((e,l,s)=>s.indexOf(e)===l)}])},860585,e=>{"use strict";var l=e.i(843476),s=e.i(199133);let{Option:t}=s.Select;e.s(["default",0,({value:e,onChange:r,className:a="",style:i={}})=>(0,l.jsxs)(s.Select,{style:{width:"100%",...i},value:e||void 0,onChange:r,className:a,placeholder:"n/a",allowClear:!0,children:[(0,l.jsx)(t,{value:"1h",children:"hourly"}),(0,l.jsx)(t,{value:"24h",children:"daily"}),(0,l.jsx)(t,{value:"7d",children:"weekly"}),(0,l.jsx)(t,{value:"30d",children:"monthly"})]}),"getBudgetDurationLabel",0,e=>e?({"1h":"hourly","24h":"daily","7d":"weekly","30d":"monthly"})[e]||e:"Not set"])},350967,46757,e=>{"use strict";var l=e.i(290571),s=e.i(444755),t=e.i(673706),r=e.i(271645);let a={0:"grid-cols-none",1:"grid-cols-1",2:"grid-cols-2",3:"grid-cols-3",4:"grid-cols-4",5:"grid-cols-5",6:"grid-cols-6",7:"grid-cols-7",8:"grid-cols-8",9:"grid-cols-9",10:"grid-cols-10",11:"grid-cols-11",12:"grid-cols-12"},i={0:"sm:grid-cols-none",1:"sm:grid-cols-1",2:"sm:grid-cols-2",3:"sm:grid-cols-3",4:"sm:grid-cols-4",5:"sm:grid-cols-5",6:"sm:grid-cols-6",7:"sm:grid-cols-7",8:"sm:grid-cols-8",9:"sm:grid-cols-9",10:"sm:grid-cols-10",11:"sm:grid-cols-11",12:"sm:grid-cols-12"},n={0:"md:grid-cols-none",1:"md:grid-cols-1",2:"md:grid-cols-2",3:"md:grid-cols-3",4:"md:grid-cols-4",5:"md:grid-cols-5",6:"md:grid-cols-6",7:"md:grid-cols-7",8:"md:grid-cols-8",9:"md:grid-cols-9",10:"md:grid-cols-10",11:"md:grid-cols-11",12:"md:grid-cols-12"},o={0:"lg:grid-cols-none",1:"lg:grid-cols-1",2:"lg:grid-cols-2",3:"lg:grid-cols-3",4:"lg:grid-cols-4",5:"lg:grid-cols-5",6:"lg:grid-cols-6",7:"lg:grid-cols-7",8:"lg:grid-cols-8",9:"lg:grid-cols-9",10:"lg:grid-cols-10",11:"lg:grid-cols-11",12:"lg:grid-cols-12"};e.s(["colSpan",0,{1:"col-span-1",2:"col-span-2",3:"col-span-3",4:"col-span-4",5:"col-span-5",6:"col-span-6",7:"col-span-7",8:"col-span-8",9:"col-span-9",10:"col-span-10",11:"col-span-11",12:"col-span-12",13:"col-span-13"},"colSpanLg",0,{1:"lg:col-span-1",2:"lg:col-span-2",3:"lg:col-span-3",4:"lg:col-span-4",5:"lg:col-span-5",6:"lg:col-span-6",7:"lg:col-span-7",8:"lg:col-span-8",9:"lg:col-span-9",10:"lg:col-span-10",11:"lg:col-span-11",12:"lg:col-span-12",13:"lg:col-span-13"},"colSpanMd",0,{1:"md:col-span-1",2:"md:col-span-2",3:"md:col-span-3",4:"md:col-span-4",5:"md:col-span-5",6:"md:col-span-6",7:"md:col-span-7",8:"md:col-span-8",9:"md:col-span-9",10:"md:col-span-10",11:"md:col-span-11",12:"md:col-span-12",13:"md:col-span-13"},"colSpanSm",0,{1:"sm:col-span-1",2:"sm:col-span-2",3:"sm:col-span-3",4:"sm:col-span-4",5:"sm:col-span-5",6:"sm:col-span-6",7:"sm:col-span-7",8:"sm:col-span-8",9:"sm:col-span-9",10:"sm:col-span-10",11:"sm:col-span-11",12:"sm:col-span-12",13:"sm:col-span-13"},"gridCols",0,a,"gridColsLg",0,o,"gridColsMd",0,n,"gridColsSm",0,i],46757);let c=(0,t.makeClassName)("Grid"),d=(e,l)=>e&&Object.keys(l).includes(String(e))?l[e]:"",m=r.default.forwardRef((e,t)=>{let{numItems:m=1,numItemsSm:u,numItemsMd:g,numItemsLg:p,children:h,className:x}=e,f=(0,l.__rest)(e,["numItems","numItemsSm","numItemsMd","numItemsLg","children","className"]),y=d(m,a),b=d(u,i),v=d(g,n),j=d(p,o),w=(0,s.tremorTwMerge)(y,b,v,j);return r.default.createElement("div",Object.assign({ref:t,className:(0,s.tremorTwMerge)(c("root"),"grid",w,x)},f),h)});m.displayName="Grid",e.s(["Grid",0,m],350967)},981339,e=>{"use strict";var l=e.i(185793);e.s(["Skeleton",()=>l.default])},500727,e=>{"use strict";var l=e.i(266027),s=e.i(243652),t=e.i(602869),r=e.i(135214);let a=(0,s.createQueryKeys)("mcpServers");e.s(["useMCPServers",0,e=>{let{accessToken:s}=(0,r.default)();return(0,l.useQuery)({queryKey:a.list(e?{filters:{teamId:e}}:void 0),queryFn:async()=>await (0,t.fetchMCPServers)(s,e),enabled:!!s})}])},699857,e=>{"use strict";var l=e.i(266027),s=e.i(243652),t=e.i(602869),r=e.i(135214);let a=(0,s.createQueryKeys)("mcpToolsets");e.s(["useMCPToolsets",0,()=>{let{accessToken:e}=(0,r.default)();return(0,l.useQuery)({queryKey:a.list(),queryFn:async()=>await (0,t.fetchMCPToolsets)(e),enabled:!!e})}])},916940,e=>{"use strict";var l=e.i(843476),s=e.i(271645),t=e.i(199133),r=e.i(602869);e.s(["default",0,({onChange:e,value:a,className:i,accessToken:n,placeholder:o="Select vector stores",disabled:c=!1})=>{let[d,m]=(0,s.useState)([]),[u,g]=(0,s.useState)(!1);return(0,s.useEffect)(()=>{(async()=>{if(n){g(!0);try{let e=await (0,r.vectorStoreListCall)(n);e.data&&m(e.data)}catch(e){console.error("Error fetching vector stores:",e)}finally{g(!1)}}})()},[n]),(0,l.jsx)("div",{children:(0,l.jsx)(t.Select,{mode:"multiple",placeholder:o,onChange:e,value:a,loading:u,className:i,allowClear:!0,options:d.map(e=>({label:`${e.vector_store_name||e.vector_store_id} (${e.vector_store_id})`,value:e.vector_store_id,title:e.vector_store_description||e.vector_store_id})),optionFilterProp:"label",showSearch:!0,style:{width:"100%"},disabled:c})})}])},75921,e=>{"use strict";var l=e.i(843476),s=e.i(266027),t=e.i(243652),r=e.i(602869),a=e.i(135214);let i=(0,t.createQueryKeys)("mcpAccessGroups");var n=e.i(500727),o=e.i(699857),c=e.i(199133),d=e.i(234713);let m="toolset:";e.s(["default",0,({onChange:e,value:t,className:u,accessToken:g,placeholder:p="Select MCP servers",disabled:h=!1,teamId:x,allowNoMcpServers:f=!1,allowAllProxyMcpServers:y=!1})=>{let{data:b=[],isLoading:v}=(0,n.useMCPServers)(x),{data:j=[],isLoading:w}=(()=>{let{accessToken:e}=(0,a.default)();return(0,s.useQuery)({queryKey:i.list({}),queryFn:async()=>await (0,r.fetchMCPAccessGroups)(e),enabled:!!e})})(),{data:N=[],isLoading:S}=(0,o.useMCPToolsets)(),k=new Set(j),_=[...j.map(e=>({label:e,value:e,type:"accessGroup",searchText:`${e} Access Group`})),...b.map(e=>({label:`${e.server_name||e.server_id} (${e.server_id})`,value:e.server_id,type:"server",searchText:`${e.server_name||e.server_id} ${e.server_id} MCP Server`})),...N.map(e=>({label:e.toolset_name,value:`${m}${e.toolset_id}`,type:"toolset",searchText:`${e.toolset_name} ${e.toolset_id} Toolset`}))],C={accessGroup:"#52c41a",server:"#1890ff",toolset:"#722ed1"},M={accessGroup:"Access Group",server:"MCP Server",toolset:"Toolset"},E=[...t?.servers||[],...t?.accessGroups||[],...(t?.toolsets||[]).map(e=>`${m}${e}`)],L=f&&E.includes(d.NO_MCP_SERVERS_SENTINEL),R=E.includes(d.ALL_PROXY_MCP_SERVERS_SENTINEL);return(0,l.jsx)("div",{children:(0,l.jsxs)(c.Select,{mode:"multiple",placeholder:p,onChange:l=>{if(y&&l.includes(d.ALL_PROXY_MCP_SERVERS_SENTINEL))return void e({servers:[d.ALL_PROXY_MCP_SERVERS_SENTINEL],accessGroups:[],toolsets:[]});if(f&&l.includes(d.NO_MCP_SERVERS_SENTINEL))return void e({servers:[d.NO_MCP_SERVERS_SENTINEL],accessGroups:[],toolsets:[]});let s=l.filter(e=>e.startsWith(m)).map(e=>e.slice(m.length)),t=l.filter(e=>!e.startsWith(m));e({servers:t.filter(e=>!k.has(e)),accessGroups:t.filter(e=>k.has(e)),toolsets:s})},value:E,loading:v||w||S,className:u,allowClear:!0,showSearch:!0,style:{width:"100%"},disabled:h,filterOption:(e,l)=>l?.value===d.NO_MCP_SERVERS_SENTINEL||l?.value===d.ALL_PROXY_MCP_SERVERS_SENTINEL||(_.find(e=>e.value===l?.value)?.searchText||"").toLowerCase().includes(e.toLowerCase()),children:[(y||R)&&(0,l.jsx)(c.Select.Option,{value:d.ALL_PROXY_MCP_SERVERS_SENTINEL,label:"All Proxy MCP Servers",children:(0,l.jsx)("span",{style:{color:"#1890ff",fontWeight:500},children:"All Proxy MCP Servers"})},d.ALL_PROXY_MCP_SERVERS_SENTINEL),f&&(0,l.jsx)(c.Select.Option,{value:d.NO_MCP_SERVERS_SENTINEL,label:"No MCP Servers",children:(0,l.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[(0,l.jsx)("span",{style:{flex:1},children:"No MCP Servers"}),(0,l.jsx)("span",{style:{color:"#8c8c8c",fontSize:"12px",fontWeight:500,opacity:.8},children:"Block all"})]})},d.NO_MCP_SERVERS_SENTINEL),_.map(e=>(0,l.jsx)(c.Select.Option,{value:e.value,label:e.label,disabled:L||R,children:(0,l.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[(0,l.jsx)("span",{style:{display:"inline-block",width:8,height:8,borderRadius:"50%",background:C[e.type],flexShrink:0}}),(0,l.jsx)("span",{style:{flex:1},children:e.label}),(0,l.jsx)("span",{style:{color:C[e.type],fontSize:"12px",fontWeight:500,opacity:.8},children:M[e.type]})]})},e.value))]})})}],75921)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/02iqizny3-cps.js b/litellm/proxy/_experimental/out/_next/static/chunks/02iqizny3-cps.js new file mode 100644 index 00000000000..8a139b3e0b2 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/02iqizny3-cps.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,250980,e=>{"use strict";var l=e.i(271645);let s=l.forwardRef(function(e,s){return l.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:s},e),l.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z"}))});e.s(["PlusCircleIcon",0,s],250980)},695411,e=>{"use strict";var l=e.i(602869);let s=async e=>{try{let s=await (0,l.modelHubCall)(e);if(s?.data.length>0){let e=s.data.map(e=>({model_group:e.model_group,mode:e?.mode}));return e.sort((e,l)=>e.model_group.localeCompare(l.model_group)),e}return[]}catch(e){throw console.error("Error fetching model info:",e),e}};e.s(["fetchAvailableModels",0,s])},841947,e=>{"use strict";let l=(0,e.i(475254).default)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);e.s(["default",0,l])},603908,e=>{"use strict";let l=(0,e.i(475254).default)("plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]);e.s(["default",0,l])},107233,e=>{"use strict";var l=e.i(603908);e.s(["Plus",()=>l.default])},37727,e=>{"use strict";var l=e.i(841947);e.s(["X",()=>l.default])},425063,e=>{"use strict";let l=(0,e.i(475254).default)("arrow-down",[["path",{d:"M12 5v14",key:"s699le"}],["path",{d:"m19 12-7 7-7-7",key:"1idqje"}]]);e.s(["ArrowDown",0,l],425063)},158392,63209,e=>{"use strict";var l=e.i(843476),s=e.i(311451);let t={ttl:3600,lowest_latency_buffer:0},r=({routingStrategyArgs:e})=>{let r={ttl:"Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)("div",{className:"space-y-6",children:[(0,l.jsxs)("div",{className:"max-w-3xl",children:[(0,l.jsx)("h3",{className:"text-sm font-medium text-gray-900",children:"Latency-Based Configuration"}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mt-1",children:"Fine-tune latency-based routing behavior"})]}),(0,l.jsx)("div",{className:"grid grid-cols-1 gap-6 lg:grid-cols-2 xl:grid-cols-3",children:Object.entries(e||t).map(([e,t])=>(0,l.jsx)("div",{className:"space-y-2",children:(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("span",{className:"text-xs font-medium text-gray-700 uppercase tracking-wide",children:e.replace(/_/g," ")}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mt-0.5 mb-2",children:r[e]||""}),(0,l.jsx)(s.Input,{name:e,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t?.toString(),className:"font-mono text-sm w-full"})]})},e))})]}),(0,l.jsx)("div",{className:"border-t border-gray-200"})]})},a=({routerSettings:e,routerFieldsMetadata:t})=>(0,l.jsxs)("div",{className:"space-y-6",children:[(0,l.jsxs)("div",{className:"max-w-3xl",children:[(0,l.jsx)("h3",{className:"text-sm font-medium text-gray-900",children:"Reliability & Retries"}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mt-1",children:"Configure retry logic and failure handling"})]}),(0,l.jsx)("div",{className:"grid grid-cols-1 gap-6 lg:grid-cols-2 xl:grid-cols-3",children:Object.entries(e).filter(([e])=>"fallbacks"!=e&&"context_window_fallbacks"!=e&&"routing_strategy_args"!=e&&"routing_strategy"!=e&&"enable_tag_filtering"!=e&&"retry_policy"!=e&&"model_group_retry_policy"!=e&&"routing_groups"!=e).map(([e,r])=>(0,l.jsx)("div",{className:"space-y-2",children:(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("span",{className:"text-xs font-medium text-gray-700 uppercase tracking-wide",children:t[e]?.ui_field_name||e}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mt-0.5 mb-2",children:t[e]?.field_description||""}),(0,l.jsx)(s.Input,{name:e,defaultValue:null==r||"null"===r?"":"object"==typeof r?JSON.stringify(r,null,2):r?.toString()||"",placeholder:"—",className:"font-mono text-sm w-full"})]})},e))})]});var i=e.i(199133);let n=({selectedStrategy:e,availableStrategies:s,routingStrategyDescriptions:t,routerFieldsMetadata:r,onStrategyChange:a})=>(0,l.jsxs)("div",{className:"space-y-2 max-w-3xl",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("label",{className:"text-xs font-medium text-gray-700 uppercase tracking-wide",children:r.routing_strategy?.ui_field_name||"Routing Strategy"}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mt-0.5 mb-2",children:r.routing_strategy?.field_description||""})]}),(0,l.jsx)("div",{className:"routing-strategy-select max-w-3xl",children:(0,l.jsx)(i.Select,{value:e,onChange:a,style:{width:"100%"},size:"large",children:s.map(e=>(0,l.jsx)(i.Select.Option,{value:e,label:e,children:(0,l.jsxs)("div",{className:"flex flex-col gap-0.5 py-1",children:[(0,l.jsx)("span",{className:"font-mono text-sm font-medium",children:e}),t[e]&&(0,l.jsx)("span",{className:"text-xs text-gray-500 font-normal",children:t[e]})]})},e))})})]});var o=e.i(790848);let c=({enabled:e,routerFieldsMetadata:s,onToggle:t})=>(0,l.jsx)("div",{className:"space-y-3 max-w-3xl",children:(0,l.jsxs)("div",{className:"flex items-start justify-between",children:[(0,l.jsxs)("div",{className:"flex-1",children:[(0,l.jsx)("label",{className:"text-xs font-medium text-gray-700 uppercase tracking-wide",children:s.enable_tag_filtering?.ui_field_name||"Enable Tag Filtering"}),(0,l.jsxs)("p",{className:"text-xs text-gray-500 mt-0.5",children:[s.enable_tag_filtering?.field_description||"",s.enable_tag_filtering?.link&&(0,l.jsxs)(l.Fragment,{children:[" ",(0,l.jsx)("a",{href:s.enable_tag_filtering.link,target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:text-blue-800 underline",children:"Learn more"})]})]})]}),(0,l.jsx)(o.Switch,{checked:e,onChange:t,className:"ml-4"})]})});e.s(["default",0,({value:e,onChange:s,routerFieldsMetadata:t,availableRoutingStrategies:i,routingStrategyDescriptions:o})=>(0,l.jsxs)("div",{className:"w-full space-y-8 py-2",children:[(0,l.jsxs)("div",{className:"space-y-6",children:[(0,l.jsxs)("div",{className:"max-w-3xl",children:[(0,l.jsx)("h3",{className:"text-sm font-medium text-gray-900",children:"Routing Settings"}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mt-1",children:"Configure how requests are routed to deployments"})]}),i.length>0&&(0,l.jsx)(n,{selectedStrategy:e.selectedStrategy||e.routerSettings.routing_strategy||null,availableStrategies:i,routingStrategyDescriptions:o,routerFieldsMetadata:t,onStrategyChange:l=>{s({...e,selectedStrategy:l})}}),(0,l.jsx)(c,{enabled:e.enableTagFiltering,routerFieldsMetadata:t,onToggle:l=>{s({...e,enableTagFiltering:l})}})]}),(0,l.jsx)("div",{className:"border-t border-gray-200"}),"latency-based-routing"===e.selectedStrategy&&(0,l.jsx)(r,{routingStrategyArgs:e.routerSettings.routing_strategy_args}),(0,l.jsx)(a,{routerSettings:e.routerSettings,routerFieldsMetadata:t})]})],158392);var d=e.i(361653);e.s(["AlertCircle",()=>d.default],63209)},419470,e=>{"use strict";var l=e.i(843476),s=e.i(994388),t=e.i(653496),r=e.i(107233),a=e.i(271645),i=e.i(888259),n=e.i(199133),o=e.i(592968),c=e.i(63209),d=e.i(425063),m=e.i(37727);function u({group:e,onChange:s,availableModels:t,maxFallbacks:r}){let a=t.filter(l=>l!==e.primaryModel),i=e.fallbackModels.length{let t=[...e.fallbackModels];t.includes(l)&&(t=t.filter(e=>e!==l)),s({...e,primaryModel:l,fallbackModels:t})},showSearch:!0,getPopupContainer:e=>e.parentElement||document.body,filterOption:(e,l)=>(l?.label??"").toLowerCase().includes(e.toLowerCase()),options:t.map(e=>({label:e,value:e}))}),!e.primaryModel&&(0,l.jsxs)("div",{className:"mt-2 flex items-center gap-2 text-amber-600 text-xs bg-amber-50 p-2 rounded-sm",children:[(0,l.jsx)(c.AlertCircle,{className:"w-4 h-4"}),(0,l.jsx)("span",{children:"Select a model to begin configuring fallbacks"})]})]}),(0,l.jsx)("div",{className:"flex items-center justify-center -my-4 z-10",children:(0,l.jsxs)("div",{className:"bg-indigo-50 text-indigo-500 px-4 py-1 rounded-full text-xs font-bold border border-indigo-100 flex items-center gap-2 shadow-xs",children:[(0,l.jsx)(d.ArrowDown,{className:"w-4 h-4"}),"IF FAILS, TRY..."]})}),(0,l.jsxs)("div",{className:`transition-opacity duration-300 ${!e.primaryModel?"opacity-50 pointer-events-none":"opacity-100"}`,children:[(0,l.jsxs)("label",{className:"block text-sm font-semibold text-gray-700 mb-2",children:["Fallback Chain ",(0,l.jsx)("span",{className:"text-red-500",children:"*"}),(0,l.jsxs)("span",{className:"text-xs text-gray-500 font-normal ml-2",children:["(Max ",r," fallbacks at a time)"]})]}),(0,l.jsxs)("div",{className:"bg-gray-50 rounded-xl p-4 border border-gray-200",children:[(0,l.jsxs)("div",{className:"mb-4",children:[(0,l.jsx)(n.Select,{mode:"multiple",className:"w-full",size:"large",placeholder:i?"Select fallback models to add...":`Maximum ${r} fallbacks reached`,value:e.fallbackModels,onChange:l=>{let t=l.slice(0,r);s({...e,fallbackModels:t})},disabled:!e.primaryModel,getPopupContainer:e=>e.parentElement||document.body,options:a.map(e=>({label:e,value:e})),optionRender:(s,t)=>{let r=e.fallbackModels.includes(s.value),a=r?e.fallbackModels.indexOf(s.value)+1:null;return(0,l.jsxs)("div",{className:"flex items-center gap-2",children:[r&&null!==a&&(0,l.jsx)("span",{className:"flex items-center justify-center w-5 h-5 rounded-sm bg-indigo-100 text-indigo-600 text-xs font-bold",children:a}),(0,l.jsx)("span",{children:s.label})]})},maxTagCount:"responsive",maxTagPlaceholder:e=>(0,l.jsx)(o.Tooltip,{styles:{root:{pointerEvents:"none"}},title:e.map(({value:e})=>e).join(", "),children:(0,l.jsxs)("span",{children:["+",e.length," more"]})}),showSearch:!0,filterOption:(e,l)=>(l?.label??"").toLowerCase().includes(e.toLowerCase())}),(0,l.jsx)("p",{className:"text-xs text-gray-500 mt-1 ml-1",children:i?`Search and select multiple models. Selected models will appear below in order. (${e.fallbackModels.length}/${r} used)`:`Maximum ${r} fallbacks reached. Remove some to add more.`})]}),(0,l.jsx)("div",{className:"space-y-2 min-h-[100px]",children:0===e.fallbackModels.length?(0,l.jsxs)("div",{className:"h-32 border-2 border-dashed border-gray-300 rounded-lg flex flex-col items-center justify-center text-gray-400",children:[(0,l.jsx)("span",{className:"text-sm",children:"No fallback models selected"}),(0,l.jsx)("span",{className:"text-xs mt-1",children:"Add models from the dropdown above"})]}):e.fallbackModels.map((t,r)=>(0,l.jsxs)("div",{className:"group flex items-center justify-between p-3 bg-white rounded-lg border border-gray-200 hover:border-indigo-300 hover:shadow-xs transition-all",children:[(0,l.jsxs)("div",{className:"flex items-center gap-3",children:[(0,l.jsx)("div",{className:"flex items-center justify-center w-6 h-6 rounded-sm bg-gray-100 text-gray-400 group-hover:text-indigo-500 group-hover:bg-indigo-50",children:(0,l.jsx)("span",{className:"text-xs font-bold",children:r+1})}),(0,l.jsx)("div",{children:(0,l.jsx)("span",{className:"font-medium text-gray-800",children:t})})]}),(0,l.jsx)("button",{type:"button",onClick:()=>{let l;return l=e.fallbackModels.filter((e,l)=>l!==r),void s({...e,fallbackModels:l})},className:"opacity-0 group-hover:opacity-100 transition-opacity text-gray-400 hover:text-red-500 p-1",children:(0,l.jsx)(m.X,{className:"w-4 h-4"})})]},`${t}-${r}`))})]})]})]})}e.s(["FallbackSelectionForm",0,function({groups:e,onGroupsChange:n,availableModels:o,maxFallbacks:c=10,maxGroups:d=5}){let[m,g]=(0,a.useState)(e.length>0?e[0].id:"1");(0,a.useEffect)(()=>{e.length>0?e.some(e=>e.id===m)||g(e[0].id):g("1")},[e]);let p=()=>{if(e.length>=d)return;let l=Date.now().toString();n([...e,{id:l,primaryModel:null,fallbackModels:[]}]),g(l)},h=l=>{n(e.map(e=>e.id===l.id?l:e))},x=e.map((s,t)=>{let r=s.primaryModel?s.primaryModel:`Group ${t+1}`;return{key:s.id,label:r,closable:e.length>1,children:(0,l.jsx)(u,{group:s,onChange:h,availableModels:o,maxFallbacks:c})}});return 0===e.length?(0,l.jsxs)("div",{className:"text-center py-12 bg-gray-50 rounded-lg border border-dashed border-gray-300",children:[(0,l.jsx)("p",{className:"text-gray-500 mb-4",children:"No fallback groups configured"}),(0,l.jsx)(s.Button,{variant:"primary",onClick:p,icon:()=>(0,l.jsx)(r.Plus,{className:"w-4 h-4"}),children:"Create First Group"})]}):(0,l.jsx)(t.Tabs,{type:"editable-card",activeKey:m,onChange:g,onEdit:(l,s)=>{"add"===s?p():"remove"===s&&e.length>1&&(l=>{if(1===e.length)return i.default.warning("At least one group is required");let s=e.filter(e=>e.id!==l);n(s),m===l&&s.length>0&&g(s[s.length-1].id)})(l)},items:x,className:"fallback-tabs",tabBarStyle:{marginBottom:0},hideAdd:e.length>=d})}],419470)},246349,e=>{"use strict";let l=(0,e.i(475254).default)("chevron-right",[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]]);e.s(["default",0,l])},992619,e=>{"use strict";var l=e.i(843476),s=e.i(271645),t=e.i(779241),r=e.i(599724),a=e.i(199133),i=e.i(983561),n=e.i(695411);e.s(["default",0,({accessToken:e,value:o,placeholder:c="Select a Model",onChange:d,disabled:m=!1,style:u,className:g,showLabel:p=!0,labelText:h="Select Model"})=>{let[x,f]=(0,s.useState)(o),[y,b]=(0,s.useState)(!1),[v,j]=(0,s.useState)([]),w=(0,s.useRef)(null);return(0,s.useEffect)(()=>{f(o)},[o]),(0,s.useEffect)(()=>{e&&(async()=>{try{let l=await (0,n.fetchAvailableModels)(e);l.length>0&&j(l)}catch(e){console.error("Error fetching model info:",e)}})()},[e]),(0,l.jsxs)("div",{children:[p&&(0,l.jsxs)(r.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,l.jsx)(i.RobotOutlined,{className:"mr-2"})," ",h]}),(0,l.jsx)(a.Select,{value:x,placeholder:c,onChange:e=>{"custom"===e?(b(!0),f(void 0)):(b(!1),f(e),d&&d(e))},options:[...Array.from(new Set(v.map(e=>e.model_group))).map((e,l)=>({value:e,label:e,key:l})),{value:"custom",label:"Enter custom model",key:"custom"}],style:{width:"100%",...u},showSearch:!0,className:`rounded-md ${g||""}`,disabled:m}),y&&(0,l.jsx)(t.TextInput,{className:"mt-2",placeholder:"Enter custom model name",onValueChange:e=>{w.current&&clearTimeout(w.current),w.current=setTimeout(()=>{f(e),d&&d(e)},500)},disabled:m})]})}])},91739,e=>{"use strict";var l=e.i(544195);e.s(["Radio",()=>l.default])},988297,e=>{"use strict";var l=e.i(271645);let s=l.forwardRef(function(e,s){return l.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:s},e),l.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 4v16m8-8H4"}))});e.s(["PlusIcon",0,s],988297)},797672,e=>{"use strict";var l=e.i(271645);let s=l.forwardRef(function(e,s){return l.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:s},e),l.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"}))});e.s(["PencilIcon",0,s],797672)},361653,e=>{"use strict";let l=(0,e.i(475254).default)("circle-alert",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]]);e.s(["default",0,l])},409797,e=>{"use strict";var l=e.i(631171);e.s(["ChevronDownIcon",()=>l.default])},531516,696609,e=>{"use strict";var l=e.i(843476),s=e.i(271645),t=e.i(536916),r=e.i(599724),a=e.i(409797),i=e.i(246349),i=i;let n=/\b(delete|remove|destroy|purge|drop|erase|unlink)\b/i,o=/\b(create|add|insert|new|post|submit|register|make|generate|write|upload)\b/i,c=/\b(update|edit|modify|change|patch|put|set|rename|move|transform)\b/i,d=/\b(get|read|list|fetch|search|find|query|retrieve|show|view|check|describe|info)\b/i;function m(e,l=""){let s=e.toLowerCase();if(d.test(s))return"read";if(n.test(s))return"delete";if(c.test(s))return"update";if(o.test(s))return"create";if(l){let e=l.toLowerCase();if(d.test(e))return"read";if(n.test(e))return"delete";if(c.test(e))return"update";if(o.test(e))return"create"}return"unknown"}function u(e){let l={read:[],create:[],update:[],delete:[],unknown:[]};for(let s of e)l[m(s.name,s.description)].push(s);return l}let g={read:{label:"Read",description:"Safe operations — fetch, list, search. No side effects.",risk:"low"},create:{label:"Create",description:"Add new resources — insert, upload, register.",risk:"medium"},update:{label:"Update",description:"Modify existing resources — edit, patch, rename.",risk:"medium"},delete:{label:"Delete",description:"Destructive operations — remove, purge, destroy.",risk:"high"},unknown:{label:"Other",description:"Operations that could not be automatically classified.",risk:"unknown"}};e.s(["CRUD_GROUP_META",0,g,"classifyToolOp",0,m,"groupToolsByCrud",0,u],696609);let p=["read","create","update","delete","unknown"],h={low:"bg-green-100 text-green-800",medium:"bg-yellow-100 text-yellow-800",high:"bg-red-100 text-red-800 font-semibold",unknown:"bg-gray-100 text-gray-700"},x={read:"border-green-200",create:"border-blue-200",update:"border-yellow-200",delete:"border-red-300",unknown:"border-gray-200"},f={read:"bg-green-50",create:"bg-blue-50",update:"bg-yellow-50",delete:"bg-red-50",unknown:"bg-gray-50"};e.s(["default",0,({tools:e,value:n,onChange:o,readOnly:c=!1,searchFilter:d=""})=>{let[m,y]=(0,s.useState)({read:!1,create:!1,update:!1,delete:!1,unknown:!0}),b=(0,s.useMemo)(()=>u(e),[e]),v=(0,s.useMemo)(()=>new Set(void 0===n?e.map(e=>e.name):n),[n,e]),j=e=>{if(c)return;let l=new Set(v);l.has(e)?l.delete(e):l.add(e),o(Array.from(l))};return 0===e.length?null:(0,l.jsx)("div",{className:"space-y-3",children:p.map(e=>{let s,n=b[e];if(0===n.length)return null;if(d){let e=d.toLowerCase();if(!n.some(l=>l.name.toLowerCase().includes(e)||(l.description??"").toLowerCase().includes(e)))return null}let u=g[e],p=(s=b[e]).length>0&&s.every(e=>v.has(e.name)),w=(e=>{let l=b[e];if(0===l.length)return!1;let s=l.filter(e=>v.has(e.name)).length;return s>0&&s{y(l=>({...l,[e]:!l[e]}))},children:[N?(0,l.jsx)(i.default,{className:"w-4 h-4 text-gray-500 shrink-0"}):(0,l.jsx)(a.ChevronDownIcon,{className:"w-4 h-4 text-gray-500 shrink-0"}),(0,l.jsx)("span",{className:"font-semibold text-gray-900 text-sm",children:u.label}),(0,l.jsx)("span",{className:`text-xs px-2 py-0.5 rounded-full ${h[u.risk]}`,children:"high"===u.risk?"High Risk":"medium"===u.risk?"Medium Risk":"low"===u.risk?"Safe":"Unclassified"}),(0,l.jsxs)("span",{className:"text-xs text-gray-500 ml-1",children:[n.filter(e=>v.has(e.name)).length,"/",n.length," allowed"]})]}),!c&&(0,l.jsxs)("div",{className:"flex items-center gap-2 ml-4",children:[(0,l.jsx)(r.Text,{className:"text-xs text-gray-500",children:p?"All on":w?"Partial":"All off"}),(0,l.jsx)(t.Checkbox,{checked:p,indeterminate:w,onChange:l=>((e,l)=>{if(c)return;let s=new Set(v);for(let t of b[e])l?s.add(t.name):s.delete(t.name);o(Array.from(s))})(e,l.target.checked),onClick:e=>e.stopPropagation()})]})]}),!N&&(0,l.jsx)("div",{className:"px-4 pt-2 pb-1 text-xs text-gray-500 bg-white border-b border-gray-100",children:u.description}),!N&&(0,l.jsx)("div",{className:"bg-white divide-y divide-gray-50",children:n.filter(e=>!d||e.name.toLowerCase().includes(d.toLowerCase())||(e.description??"").toLowerCase().includes(d.toLowerCase())).map(e=>{let s,a=(s=e.name,v.has(s));return(0,l.jsxs)("div",{className:`flex items-start gap-3 px-4 py-2.5 transition-colors hover:bg-gray-50 ${!c?"cursor-pointer":""} ${a?"":"opacity-60"}`,onClick:()=>j(e.name),children:[(0,l.jsx)(t.Checkbox,{checked:a,onChange:()=>j(e.name),disabled:c,onClick:e=>e.stopPropagation()}),(0,l.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,l.jsx)(r.Text,{className:"font-medium text-gray-900 text-sm",children:e.name}),e.description&&(0,l.jsx)(r.Text,{className:"text-xs text-gray-500 mt-0.5 leading-snug",children:e.description})]}),(0,l.jsx)("span",{className:`text-xs px-1.5 py-0.5 rounded shrink-0 ${a?"bg-green-100 text-green-700":"bg-gray-100 text-gray-500"}`,children:a?"on":"off"})]},e.name)})})]},e)})})}],531516)},309426,e=>{"use strict";var l=e.i(290571),s=e.i(444755),t=e.i(673706),r=e.i(271645),a=e.i(46757);let i=(0,t.makeClassName)("Col"),n=r.default.forwardRef((e,t)=>{let n,o,c,d,{numColSpan:m=1,numColSpanSm:u,numColSpanMd:g,numColSpanLg:p,children:h,className:x}=e,f=(0,l.__rest)(e,["numColSpan","numColSpanSm","numColSpanMd","numColSpanLg","children","className"]),y=(e,l)=>e&&Object.keys(l).includes(String(e))?l[e]:"";return r.default.createElement("div",Object.assign({ref:t,className:(0,s.tremorTwMerge)(i("root"),(n=y(m,a.colSpan),o=y(u,a.colSpanSm),c=y(g,a.colSpanMd),d=y(p,a.colSpanLg),(0,s.tremorTwMerge)(n,o,c,d)),x)},f),h)});n.displayName="Col",e.s(["Col",0,n],309426)},355619,e=>{"use strict";var l=e.i(602869);let s=async(e,s,t)=>{try{if(null===e||null===s)return;if(null!==t){let r=(await (0,l.modelAvailableCall)(t,e,s,!0,null,!0)).data.map(e=>e.id),a=[],i=[];return r.forEach(e=>{e.endsWith("/*")?a.push(e):i.push(e)}),[...a,...i]}}catch(e){console.error("Error fetching user models:",e)}};e.s(["fetchAvailableModelsForTeamOrKey",0,s,"getModelDisplayName",0,e=>{if("all-proxy-models"===e)return"All Proxy Models";if(e.endsWith("/*")){let l=e.replace("/*","");return`All ${l} models`}return e},"unfurlWildcardModelsInList",0,(e,l)=>{let s=[],t=[];return e.forEach(e=>{if(e.endsWith("/*")){let r=e.replace("/*",""),a=l.filter(e=>e.startsWith(r+"/"));t.push(...a),s.push(e)}else t.push(e)}),[...s,...t].filter((e,l,s)=>s.indexOf(e)===l)}])},860585,e=>{"use strict";var l=e.i(843476),s=e.i(199133);let{Option:t}=s.Select;e.s(["default",0,({value:e,onChange:r,className:a="",style:i={}})=>(0,l.jsxs)(s.Select,{style:{width:"100%",...i},value:e||void 0,onChange:r,className:a,placeholder:"n/a",allowClear:!0,children:[(0,l.jsx)(t,{value:"1h",children:"hourly"}),(0,l.jsx)(t,{value:"24h",children:"daily"}),(0,l.jsx)(t,{value:"7d",children:"weekly"}),(0,l.jsx)(t,{value:"30d",children:"monthly"})]}),"getBudgetDurationLabel",0,e=>e?({"1h":"hourly","24h":"daily","7d":"weekly","30d":"monthly"})[e]||e:"Not set"])},213205,e=>{"use strict";e.i(247167);var l=e.i(931067),s=e.i(271645);let t={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M678.3 642.4c24.2-13 51.9-20.4 81.4-20.4h.1c3 0 4.4-3.6 2.2-5.6a371.67 371.67 0 00-103.7-65.8c-.4-.2-.8-.3-1.2-.5C719.2 505 759.6 431.7 759.6 349c0-137-110.8-248-247.5-248S264.7 212 264.7 349c0 82.7 40.4 156 102.6 201.1-.4.2-.8.3-1.2.5-44.7 18.9-84.8 46-119.3 80.6a373.42 373.42 0 00-80.4 119.5A373.6 373.6 0 00137 888.8a8 8 0 008 8.2h59.9c4.3 0 7.9-3.5 8-7.8 2-77.2 32.9-149.5 87.6-204.3C357 628.2 432.2 597 512.2 597c56.7 0 111.1 15.7 158 45.1a8.1 8.1 0 008.1.3zM512.2 521c-45.8 0-88.9-17.9-121.4-50.4A171.2 171.2 0 01340.5 349c0-45.9 17.9-89.1 50.3-121.6S466.3 177 512.2 177s88.9 17.9 121.4 50.4A171.2 171.2 0 01683.9 349c0 45.9-17.9 89.1-50.3 121.6C601.1 503.1 558 521 512.2 521zM880 759h-84v-84c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v84h-84c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h84v84c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-84h84c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8z"}}]},name:"user-add",theme:"outlined"};var r=e.i(9583),a=s.forwardRef(function(e,a){return s.createElement(r.default,(0,l.default)({},e,{ref:a,icon:t}))});e.s(["UserAddOutlined",0,a],213205)},350967,46757,e=>{"use strict";var l=e.i(290571),s=e.i(444755),t=e.i(673706),r=e.i(271645);let a={0:"grid-cols-none",1:"grid-cols-1",2:"grid-cols-2",3:"grid-cols-3",4:"grid-cols-4",5:"grid-cols-5",6:"grid-cols-6",7:"grid-cols-7",8:"grid-cols-8",9:"grid-cols-9",10:"grid-cols-10",11:"grid-cols-11",12:"grid-cols-12"},i={0:"sm:grid-cols-none",1:"sm:grid-cols-1",2:"sm:grid-cols-2",3:"sm:grid-cols-3",4:"sm:grid-cols-4",5:"sm:grid-cols-5",6:"sm:grid-cols-6",7:"sm:grid-cols-7",8:"sm:grid-cols-8",9:"sm:grid-cols-9",10:"sm:grid-cols-10",11:"sm:grid-cols-11",12:"sm:grid-cols-12"},n={0:"md:grid-cols-none",1:"md:grid-cols-1",2:"md:grid-cols-2",3:"md:grid-cols-3",4:"md:grid-cols-4",5:"md:grid-cols-5",6:"md:grid-cols-6",7:"md:grid-cols-7",8:"md:grid-cols-8",9:"md:grid-cols-9",10:"md:grid-cols-10",11:"md:grid-cols-11",12:"md:grid-cols-12"},o={0:"lg:grid-cols-none",1:"lg:grid-cols-1",2:"lg:grid-cols-2",3:"lg:grid-cols-3",4:"lg:grid-cols-4",5:"lg:grid-cols-5",6:"lg:grid-cols-6",7:"lg:grid-cols-7",8:"lg:grid-cols-8",9:"lg:grid-cols-9",10:"lg:grid-cols-10",11:"lg:grid-cols-11",12:"lg:grid-cols-12"};e.s(["colSpan",0,{1:"col-span-1",2:"col-span-2",3:"col-span-3",4:"col-span-4",5:"col-span-5",6:"col-span-6",7:"col-span-7",8:"col-span-8",9:"col-span-9",10:"col-span-10",11:"col-span-11",12:"col-span-12",13:"col-span-13"},"colSpanLg",0,{1:"lg:col-span-1",2:"lg:col-span-2",3:"lg:col-span-3",4:"lg:col-span-4",5:"lg:col-span-5",6:"lg:col-span-6",7:"lg:col-span-7",8:"lg:col-span-8",9:"lg:col-span-9",10:"lg:col-span-10",11:"lg:col-span-11",12:"lg:col-span-12",13:"lg:col-span-13"},"colSpanMd",0,{1:"md:col-span-1",2:"md:col-span-2",3:"md:col-span-3",4:"md:col-span-4",5:"md:col-span-5",6:"md:col-span-6",7:"md:col-span-7",8:"md:col-span-8",9:"md:col-span-9",10:"md:col-span-10",11:"md:col-span-11",12:"md:col-span-12",13:"md:col-span-13"},"colSpanSm",0,{1:"sm:col-span-1",2:"sm:col-span-2",3:"sm:col-span-3",4:"sm:col-span-4",5:"sm:col-span-5",6:"sm:col-span-6",7:"sm:col-span-7",8:"sm:col-span-8",9:"sm:col-span-9",10:"sm:col-span-10",11:"sm:col-span-11",12:"sm:col-span-12",13:"sm:col-span-13"},"gridCols",0,a,"gridColsLg",0,o,"gridColsMd",0,n,"gridColsSm",0,i],46757);let c=(0,t.makeClassName)("Grid"),d=(e,l)=>e&&Object.keys(l).includes(String(e))?l[e]:"",m=r.default.forwardRef((e,t)=>{let{numItems:m=1,numItemsSm:u,numItemsMd:g,numItemsLg:p,children:h,className:x}=e,f=(0,l.__rest)(e,["numItems","numItemsSm","numItemsMd","numItemsLg","children","className"]),y=d(m,a),b=d(u,i),v=d(g,n),j=d(p,o),w=(0,s.tremorTwMerge)(y,b,v,j);return r.default.createElement("div",Object.assign({ref:t,className:(0,s.tremorTwMerge)(c("root"),"grid",w,x)},f),h)});m.displayName="Grid",e.s(["Grid",0,m],350967)},981339,e=>{"use strict";var l=e.i(185793);e.s(["Skeleton",()=>l.default])},500727,e=>{"use strict";var l=e.i(266027),s=e.i(243652),t=e.i(602869),r=e.i(135214);let a=(0,s.createQueryKeys)("mcpServers");e.s(["useMCPServers",0,e=>{let{accessToken:s}=(0,r.default)();return(0,l.useQuery)({queryKey:a.list(e?{filters:{teamId:e}}:void 0),queryFn:async()=>await (0,t.fetchMCPServers)(s,e),enabled:!!s})}])},699857,e=>{"use strict";var l=e.i(266027),s=e.i(243652),t=e.i(602869),r=e.i(135214);let a=(0,s.createQueryKeys)("mcpToolsets");e.s(["useMCPToolsets",0,()=>{let{accessToken:e}=(0,r.default)();return(0,l.useQuery)({queryKey:a.list(),queryFn:async()=>await (0,t.fetchMCPToolsets)(e),enabled:!!e})}])},916940,e=>{"use strict";var l=e.i(843476),s=e.i(271645),t=e.i(199133),r=e.i(602869);e.s(["default",0,({onChange:e,value:a,className:i,accessToken:n,placeholder:o="Select vector stores",disabled:c=!1})=>{let[d,m]=(0,s.useState)([]),[u,g]=(0,s.useState)(!1);return(0,s.useEffect)(()=>{(async()=>{if(n){g(!0);try{let e=await (0,r.vectorStoreListCall)(n);e.data&&m(e.data)}catch(e){console.error("Error fetching vector stores:",e)}finally{g(!1)}}})()},[n]),(0,l.jsx)("div",{children:(0,l.jsx)(t.Select,{mode:"multiple",placeholder:o,onChange:e,value:a,loading:u,className:i,allowClear:!0,options:d.map(e=>({label:`${e.vector_store_name||e.vector_store_id} (${e.vector_store_id})`,value:e.vector_store_id,title:e.vector_store_description||e.vector_store_id})),optionFilterProp:"label",showSearch:!0,style:{width:"100%"},disabled:c})})}])},75921,e=>{"use strict";var l=e.i(843476),s=e.i(266027),t=e.i(243652),r=e.i(602869),a=e.i(135214);let i=(0,t.createQueryKeys)("mcpAccessGroups");var n=e.i(500727),o=e.i(699857),c=e.i(199133),d=e.i(234713);let m="toolset:";e.s(["default",0,({onChange:e,value:t,className:u,accessToken:g,placeholder:p="Select MCP servers",disabled:h=!1,teamId:x,allowNoMcpServers:f=!1,allowAllProxyMcpServers:y=!1})=>{let{data:b=[],isLoading:v}=(0,n.useMCPServers)(x),{data:j=[],isLoading:w}=(()=>{let{accessToken:e}=(0,a.default)();return(0,s.useQuery)({queryKey:i.list({}),queryFn:async()=>await (0,r.fetchMCPAccessGroups)(e),enabled:!!e})})(),{data:N=[],isLoading:S}=(0,o.useMCPToolsets)(),k=new Set(j),_=[...j.map(e=>({label:e,value:e,type:"accessGroup",searchText:`${e} Access Group`})),...b.map(e=>({label:`${e.server_name||e.server_id} (${e.server_id})`,value:e.server_id,type:"server",searchText:`${e.server_name||e.server_id} ${e.server_id} MCP Server`})),...N.map(e=>({label:e.toolset_name,value:`${m}${e.toolset_id}`,type:"toolset",searchText:`${e.toolset_name} ${e.toolset_id} Toolset`}))],C={accessGroup:"#52c41a",server:"#1890ff",toolset:"#722ed1"},M={accessGroup:"Access Group",server:"MCP Server",toolset:"Toolset"},E=[...t?.servers||[],...t?.accessGroups||[],...(t?.toolsets||[]).map(e=>`${m}${e}`)],L=f&&E.includes(d.NO_MCP_SERVERS_SENTINEL),R=E.includes(d.ALL_PROXY_MCP_SERVERS_SENTINEL);return(0,l.jsx)("div",{children:(0,l.jsxs)(c.Select,{mode:"multiple",placeholder:p,onChange:l=>{if(y&&l.includes(d.ALL_PROXY_MCP_SERVERS_SENTINEL))return void e({servers:[d.ALL_PROXY_MCP_SERVERS_SENTINEL],accessGroups:[],toolsets:[]});if(f&&l.includes(d.NO_MCP_SERVERS_SENTINEL))return void e({servers:[d.NO_MCP_SERVERS_SENTINEL],accessGroups:[],toolsets:[]});let s=l.filter(e=>e.startsWith(m)).map(e=>e.slice(m.length)),t=l.filter(e=>!e.startsWith(m));e({servers:t.filter(e=>!k.has(e)),accessGroups:t.filter(e=>k.has(e)),toolsets:s})},value:E,loading:v||w||S,className:u,allowClear:!0,showSearch:!0,style:{width:"100%"},disabled:h,filterOption:(e,l)=>l?.value===d.NO_MCP_SERVERS_SENTINEL||l?.value===d.ALL_PROXY_MCP_SERVERS_SENTINEL||(_.find(e=>e.value===l?.value)?.searchText||"").toLowerCase().includes(e.toLowerCase()),children:[(y||R)&&(0,l.jsx)(c.Select.Option,{value:d.ALL_PROXY_MCP_SERVERS_SENTINEL,label:"All Proxy MCP Servers",children:(0,l.jsx)("span",{style:{color:"#1890ff",fontWeight:500},children:"All Proxy MCP Servers"})},d.ALL_PROXY_MCP_SERVERS_SENTINEL),f&&(0,l.jsx)(c.Select.Option,{value:d.NO_MCP_SERVERS_SENTINEL,label:"No MCP Servers",children:(0,l.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[(0,l.jsx)("span",{style:{flex:1},children:"No MCP Servers"}),(0,l.jsx)("span",{style:{color:"#8c8c8c",fontSize:"12px",fontWeight:500,opacity:.8},children:"Block all"})]})},d.NO_MCP_SERVERS_SENTINEL),_.map(e=>(0,l.jsx)(c.Select.Option,{value:e.value,label:e.label,disabled:L||R,children:(0,l.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[(0,l.jsx)("span",{style:{display:"inline-block",width:8,height:8,borderRadius:"50%",background:C[e.type],flexShrink:0}}),(0,l.jsx)("span",{style:{flex:1},children:e.label}),(0,l.jsx)("span",{style:{color:C[e.type],fontSize:"12px",fontWeight:500,opacity:.8},children:M[e.type]})]})},e.value))]})})}],75921)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/02j-r.3jw.7le.js b/litellm/proxy/_experimental/out/_next/static/chunks/02j-r.3jw.7le.js new file mode 100644 index 00000000000..126c5975733 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/02j-r.3jw.7le.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,9314,e=>{"use strict";var t=e.i(843476),s=e.i(199133),l=e.i(981339),a=e.i(645526),r=e.i(599724),i=e.i(263147);e.s(["default",0,({value:e,onChange:n,placeholder:o="Select access groups",disabled:d=!1,style:c,className:u,showLabel:m=!1,labelText:p="Access Group",allowClear:g=!0})=>{let{data:h,isLoading:x,isError:y}=(0,i.useAccessGroups)();if(x)return(0,t.jsxs)("div",{children:[m&&(0,t.jsxs)(r.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,t.jsx)(a.TeamOutlined,{className:"mr-2"})," ",p]}),(0,t.jsx)(l.Skeleton.Input,{active:!0,block:!0,style:{height:32,...c}})]});let f=(h??[]).map(e=>({label:(0,t.jsxs)("span",{children:[(0,t.jsx)("span",{className:"font-medium",children:e.access_group_name})," ",(0,t.jsxs)("span",{className:"text-gray-400 text-xs",children:["(",e.access_group_id,")"]})]}),value:e.access_group_id,selectedLabel:e.access_group_name,searchText:`${e.access_group_name} ${e.access_group_id}`}));return(0,t.jsxs)("div",{children:[m&&(0,t.jsxs)(r.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,t.jsx)(a.TeamOutlined,{className:"mr-2"})," ",p]}),(0,t.jsx)(s.Select,{mode:"multiple",value:e,placeholder:o,onChange:n,disabled:d,allowClear:g,showSearch:!0,style:{width:"100%",...c},className:`rounded-md ${u??""}`,notFoundContent:y?(0,t.jsx)("span",{className:"text-red-500",children:"Failed to load access groups"}):"No access groups found",filterOption:(e,t)=>(f.find(e=>e.value===t?.value)?.searchText??"").toLowerCase().includes(e.toLowerCase()),optionLabelProp:"selectedLabel",options:f.map(e=>({label:e.label,value:e.value,selectedLabel:e.selectedLabel}))})]})}])},552130,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(199133),a=e.i(602869);e.s(["default",0,({onChange:e,value:r,className:i,accessToken:n,placeholder:o="Select agents",disabled:d=!1})=>{let[c,u]=(0,s.useState)([]),[m,p]=(0,s.useState)([]),[g,h]=(0,s.useState)(!1);(0,s.useEffect)(()=>{(async()=>{if(n){h(!0);try{let e=await (0,a.getAgentsList)(n),t=e?.agents||[];u(t);let s=new Set;t.forEach(e=>{let t=e.agent_access_groups;t&&Array.isArray(t)&&t.forEach(e=>s.add(e))}),p(Array.from(s))}catch(e){console.error("Error fetching agents:",e)}finally{h(!1)}}})()},[n]);let x=[...m.map(e=>({label:e,value:`group:${e}`,isAccessGroup:!0,searchText:`${e} Access Group`})),...c.map(e=>({label:`${e.agent_name||e.agent_id}`,value:e.agent_id,isAccessGroup:!1,searchText:`${e.agent_name||e.agent_id} ${e.agent_id} Agent`}))],y=[...r?.agents||[],...(r?.accessGroups||[]).map(e=>`group:${e}`)];return(0,t.jsx)("div",{children:(0,t.jsx)(l.Select,{mode:"multiple",placeholder:o,onChange:t=>{e({agents:t.filter(e=>!e.startsWith("group:")),accessGroups:t.filter(e=>e.startsWith("group:")).map(e=>e.replace("group:",""))})},value:y,loading:g,className:i,allowClear:!0,showSearch:!0,style:{width:"100%"},disabled:d,filterOption:(e,t)=>(x.find(e=>e.value===t?.value)?.searchText||"").toLowerCase().includes(e.toLowerCase()),children:x.map(e=>(0,t.jsx)(l.Select.Option,{value:e.value,label:e.label,children:(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[(0,t.jsx)("span",{style:{display:"inline-block",width:8,height:8,borderRadius:"50%",background:e.isAccessGroup?"#52c41a":"#722ed1",flexShrink:0}}),(0,t.jsx)("span",{style:{flex:1},children:e.label}),(0,t.jsx)("span",{style:{color:e.isAccessGroup?"#52c41a":"#722ed1",fontSize:"12px",fontWeight:500,opacity:.8},children:e.isAccessGroup?"Access Group":"Agent"})]})},e.value))})})}])},844565,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(199133),a=e.i(602869);e.s(["default",0,({onChange:e,value:r,className:i,accessToken:n,placeholder:o="Select pass through routes",disabled:d=!1,teamId:c})=>{let[u,m]=(0,s.useState)([]),[p,g]=(0,s.useState)(!1);return(0,s.useEffect)(()=>{(async()=>{if(n){g(!0);try{let e=await (0,a.getPassThroughEndpointsCall)(n,c);if(e.endpoints){let t=e.endpoints.flatMap(e=>{let t=e.path,s=e.methods;return s&&s.length>0?s.map(e=>({label:`${e} ${t}`,value:t})):[{label:t,value:t}]});m(t)}}catch(e){console.error("Error fetching pass through routes:",e)}finally{g(!1)}}})()},[n,c]),(0,t.jsx)(l.Select,{mode:"tags",placeholder:o,onChange:e,value:r,loading:p,className:i,allowClear:!0,options:u,optionFilterProp:"label",showSearch:!0,style:{width:"100%"},disabled:d})}])},810757,477386,e=>{"use strict";var t=e.i(271645);let s=t.forwardRef(function(e,s){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:s},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"}),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"}))});e.s(["CogIcon",0,s],810757);let l=t.forwardRef(function(e,s){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:s},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"}))});e.s(["BanIcon",0,l],477386)},557662,e=>{"use strict";let t="/ui/assets/logos/",s=[{id:"arize",displayName:"Arize",logo:`${t}arize.png`,supports_key_team_logging:!0,dynamic_params:{arize_api_key:"password",arize_space_id:"password"},description:"Arize Logging Integration"},{id:"braintrust",displayName:"Braintrust",logo:`${t}braintrust.png`,supports_key_team_logging:!1,dynamic_params:{braintrust_api_key:"password",braintrust_project_name:"text"},description:"Braintrust Logging Integration"},{id:"custom_callback_api",displayName:"Custom Callback API",logo:`${t}custom.svg`,supports_key_team_logging:!0,dynamic_params:{custom_callback_api_url:"text",custom_callback_api_headers:"text"},description:"Custom Callback API Logging Integration"},{id:"galileo",displayName:"Galileo",logo:`${t}galileo.ico`,supports_key_team_logging:!1,dynamic_params:{GALILEO_API_KEY:"password",GALILEO_PROJECT_ID:"text",GALILEO_LOG_STREAM_ID:"text",GALILEO_BASE_URL:"text",GALILEO_USERNAME:"text",GALILEO_PASSWORD:"password"},description:"Galileo AI Observability Integration"},{id:"datadog",displayName:"Datadog",logo:`${t}datadog.png`,supports_key_team_logging:!1,dynamic_params:{dd_api_key:"password",dd_site:"text"},description:"Datadog Logging Integration"},{id:"lago",displayName:"Lago",logo:`${t}lago.svg`,supports_key_team_logging:!1,dynamic_params:{lago_api_url:"text",lago_api_key:"password"},description:"Lago Billing Logging Integration"},{id:"langfuse",displayName:"Langfuse",logo:`${t}langfuse.png`,supports_key_team_logging:!0,dynamic_params:{langfuse_public_key:"text",langfuse_secret_key:"password",langfuse_host:"text"},description:"Langfuse v2 Logging Integration"},{id:"langfuse_otel",displayName:"Langfuse OTEL",logo:`${t}langfuse.png`,supports_key_team_logging:!0,dynamic_params:{langfuse_public_key:"text",langfuse_secret_key:"password",langfuse_host:"text"},description:"Langfuse v3 OTEL Logging Integration"},{id:"langsmith",displayName:"LangSmith",logo:`${t}langsmith.png`,supports_key_team_logging:!0,dynamic_params:{langsmith_api_key:"password",langsmith_project:"text",langsmith_base_url:"text",langsmith_sampling_rate:"number"},description:"Langsmith Logging Integration"},{id:"openmeter",displayName:"OpenMeter",logo:`${t}openmeter.png`,supports_key_team_logging:!1,dynamic_params:{openmeter_api_key:"password",openmeter_base_url:"text"},description:"OpenMeter Logging Integration"},{id:"otel",displayName:"Open Telemetry",logo:`${t}otel.png`,supports_key_team_logging:!1,dynamic_params:{otel_endpoint:"text",otel_headers:"text"},description:"OpenTelemetry Logging Integration"},{id:"s3",displayName:"S3",logo:`${t}aws.svg`,supports_key_team_logging:!1,dynamic_params:{s3_bucket_name:"text",aws_access_key_id:"password",aws_secret_access_key:"password",aws_region:"text"},description:"S3 Bucket (AWS) Logging Integration"},{id:"SQS",displayName:"SQS",logo:`${t}aws.svg`,supports_key_team_logging:!1,dynamic_params:{sqs_queue_url:"text",aws_access_key_id:"password",aws_secret_access_key:"password",aws_region:"text"},description:"SQS Queue (AWS) Logging Integration"}],l=s.reduce((e,t)=>(e[t.displayName]=t,e),{}),a=s.reduce((e,t)=>(e[t.displayName]=t.id,e),{}),r=s.reduce((e,t)=>(e[t.id]=t.displayName,e),{});e.s(["callbackInfo",0,l,"callback_map",0,a,"mapDisplayToInternalNames",0,e=>e.map(e=>a[e]||e),"mapInternalToDisplayNames",0,e=>e.map(e=>r[e]||e),"reverse_callback_map",0,r])},390605,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(602869),a=e.i(599724),r=e.i(482725),i=e.i(91739),n=e.i(500727),o=e.i(531516),d=e.i(696609);e.s(["default",0,({accessToken:e,selectedServers:c,toolPermissions:u,onChange:m,disabled:p=!1})=>{let{data:g=[]}=(0,n.useMCPServers)(),[h,x]=(0,s.useState)({}),[y,f]=(0,s.useState)({}),[b,_]=(0,s.useState)({}),[j,v]=(0,s.useState)({}),w=(0,s.useRef)(u);(0,s.useEffect)(()=>{w.current=u},[u]);let N=(0,s.useMemo)(()=>0===c.length?[]:g.filter(e=>c.includes(e.server_id)),[g,c]),k=async(e,t)=>{f(t=>({...t,[e]:!0})),_(t=>({...t,[e]:""}));try{let s=await (0,l.listMCPTools)(t,e);if(s.error)_(t=>({...t,[e]:s.message||"Failed to fetch tools"})),x(t=>({...t,[e]:[]}));else{let t=s.tools||[];x(s=>({...s,[e]:t}));let l=w.current;if(!l[e]&&t.length>0){let s=t.filter(e=>"delete"!==(0,d.classifyToolOp)(e.name,e.description||"")).map(e=>e.name);m({...l,[e]:s})}}}catch(t){console.error(`Error fetching tools for server ${e}:`,t),_(t=>({...t,[e]:"Failed to fetch tools"})),x(t=>({...t,[e]:[]}))}finally{f(t=>({...t,[e]:!1}))}};(0,s.useEffect)(()=>{N.forEach(t=>{h[t.server_id]||y[t.server_id]||k(t.server_id,e)})},[N,e]);let S=(e,t)=>{m({...u,[e]:t})};return 0===c.length?null:(0,t.jsx)("div",{className:"space-y-4",children:N.map(e=>{let s=e.server_name||e.alias||e.server_id,l=h[e.server_id]||[],n=u[e.server_id]||[],d=y[e.server_id],c=b[e.server_id],g=j[e.server_id]??"crud";return(0,t.jsxs)("div",{className:"border rounded-lg bg-gray-50",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between p-4 border-b bg-white rounded-t-lg",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(a.Text,{className:"font-semibold text-gray-900",children:s}),e.description&&(0,t.jsx)(a.Text,{className:"text-sm text-gray-500",children:e.description})]}),(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[!p&&l.length>0&&(0,t.jsx)(i.Radio.Group,{value:g,onChange:t=>v(s=>({...s,[e.server_id]:t.target.value})),size:"small",optionType:"button",buttonStyle:"solid",options:[{label:"Risk Groups",value:"crud"},{label:"Flat List",value:"flat"}]}),!p&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("button",{type:"button",className:"text-sm text-blue-600 hover:text-blue-700 font-medium",onClick:()=>{var t;let s;return s=h[t=e.server_id]||[],void m({...u,[t]:s.map(e=>e.name)})},disabled:d,children:"Select All"}),(0,t.jsx)("button",{type:"button",className:"text-sm text-blue-600 hover:text-blue-700 font-medium",onClick:()=>{var t;return t=e.server_id,void m({...u,[t]:[]})},disabled:d,children:"Deselect All"})]})]})]}),(0,t.jsxs)("div",{className:"p-4",children:[d&&(0,t.jsxs)("div",{className:"flex items-center justify-center py-8",children:[(0,t.jsx)(r.Spin,{size:"large"}),(0,t.jsx)(a.Text,{className:"ml-3 text-gray-500",children:"Loading tools..."})]}),c&&!d&&(0,t.jsxs)("div",{className:"p-4 bg-red-50 border border-red-200 rounded-lg text-center",children:[(0,t.jsx)(a.Text,{className:"text-red-600 font-medium",children:"Unable to load tools"}),(0,t.jsx)(a.Text,{className:"text-sm text-red-500 mt-1",children:c})]}),!d&&!c&&l.length>0&&"crud"===g&&(0,t.jsx)(o.default,{tools:l,value:u[e.server_id]?n:void 0,onChange:t=>S(e.server_id,t),readOnly:p}),!d&&!c&&l.length>0&&"flat"===g&&(0,t.jsx)("div",{className:"space-y-2",children:l.map(s=>{let l=n.includes(s.name);return(0,t.jsxs)("div",{className:"flex items-start gap-2",children:[(0,t.jsx)("input",{type:"checkbox",checked:l,onChange:()=>{if(p)return;let t=l?n.filter(e=>e!==s.name):[...n,s.name];S(e.server_id,t)},disabled:p,className:"mt-0.5"}),(0,t.jsx)("div",{className:"flex-1 min-w-0",children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(a.Text,{className:"font-medium text-gray-900",children:s.name}),(0,t.jsxs)(a.Text,{className:"text-sm text-gray-500",children:["- ",s.description||"No description"]})]})})]},s.name)})}),!d&&!c&&0===l.length&&(0,t.jsx)("div",{className:"text-center py-6",children:(0,t.jsx)(a.Text,{className:"text-gray-500",children:"No tools available"})})]})]},e.server_id)})})}])},266484,e=>{"use strict";var t=e.i(843476),s=e.i(199133),l=e.i(592968),a=e.i(312361),r=e.i(827252),i=e.i(994388),n=e.i(304967),o=e.i(779241),d=e.i(988297),c=e.i(68155),u=e.i(810757),m=e.i(477386),p=e.i(557662),g=e.i(555987),h=e.i(435451);let{Option:x}=s.Select;e.s(["default",0,({value:e=[],onChange:y,disabledCallbacks:f=[],onDisabledCallbacksChange:b})=>{let _=Object.entries(p.callbackInfo).filter(([e,t])=>t.supports_key_team_logging).map(([e,t])=>e),j=Object.keys(p.callbackInfo),v=e=>{y?.(e)},w=(t,s,l)=>{let a=[...e];if("callback_name"===s){let e=p.callback_map[l]||l;a[t]={...a[t],[s]:e,callback_vars:{}}}else a[t]={...a[t],[s]:l};v(a)},N=(t,s,l)=>{let a=[...e];a[t]={...a[t],callback_vars:{...a[t].callback_vars,[s]:l}},v(a)};return(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)(m.BanIcon,{className:"w-5 h-5 text-red-500"}),(0,t.jsx)("span",{className:"text-base font-semibold text-gray-800",children:"Disabled Callbacks"}),(0,t.jsx)(l.Tooltip,{title:"Select callbacks to disable for this key. Disabled callbacks will not receive any logging data.",children:(0,t.jsx)(r.InfoCircleOutlined,{className:"text-gray-400 cursor-help"})})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Disabled Callbacks"}),(0,t.jsx)(s.Select,{mode:"multiple",placeholder:"Select callbacks to disable",value:f,onChange:e=>{let t=(0,p.mapDisplayToInternalNames)(e);b?.(t)},style:{width:"100%"},optionLabelProp:"label",children:j.map(e=>{let s=(0,g.resolveLogoSrc)(p.callbackInfo[e]?.logo),a=p.callbackInfo[e]?.description;return(0,t.jsx)(x,{value:e,label:e,children:(0,t.jsx)(l.Tooltip,{title:a,placement:"right",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[s&&(0,t.jsx)("img",{src:s,alt:e,className:"w-4 h-4 object-contain",onError:t=>{let s=t.target,l=s.parentElement;if(l){let t=document.createElement("div");t.className="w-4 h-4 rounded-full bg-gray-200 flex items-center justify-center text-xs",t.textContent=e.charAt(0),l.replaceChild(t,s)}}}),(0,t.jsx)("span",{children:e})]})})},e)})}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Select callbacks that should be disabled for this key. These callbacks will not receive any logging data."})]})]}),(0,t.jsx)(a.Divider,{}),(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)(u.CogIcon,{className:"w-5 h-5 text-blue-500"}),(0,t.jsx)("span",{className:"text-base font-semibold text-gray-800",children:"Logging Integrations"}),(0,t.jsx)(l.Tooltip,{title:"Configure callback logging integrations for this team.",children:(0,t.jsx)(r.InfoCircleOutlined,{className:"text-gray-400 cursor-help"})})]}),(0,t.jsx)(i.Button,{variant:"secondary",onClick:()=>{v([...e,{callback_name:"",callback_type:"success",callback_vars:{}}])},icon:d.PlusIcon,size:"sm",className:"hover:border-blue-400 hover:text-blue-500",type:"button",children:"Add Integration"})]}),(0,t.jsx)("div",{className:"space-y-4",children:e.map((a,d)=>{let u=a.callback_name?Object.entries(p.callback_map).find(([e,t])=>t===a.callback_name)?.[0]:void 0,m=u?(0,g.resolveLogoSrc)(p.callbackInfo[u]?.logo):null;return(0,t.jsxs)(n.Card,{className:"border border-gray-200 shadow-xs hover:shadow-md transition-shadow duration-200",decoration:"top",decorationColor:"blue",children:[(0,t.jsxs)("div",{className:"flex justify-between items-start mb-4",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[m&&(0,t.jsx)("img",{src:m,alt:u,className:"w-5 h-5 object-contain"}),(0,t.jsxs)("span",{className:"text-sm font-medium",children:[u||"New Integration"," Configuration"]})]}),(0,t.jsx)(i.Button,{variant:"light",onClick:()=>{v(e.filter((e,t)=>t!==d))},icon:c.TrashIcon,size:"xs",color:"red",className:"hover:bg-red-50",type:"button",children:"Remove"})]}),(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Integration Type"}),(0,t.jsx)(s.Select,{value:u,placeholder:"Select integration",onChange:e=>w(d,"callback_name",e),className:"w-full",optionLabelProp:"label",children:_.map(e=>{let s=(0,g.resolveLogoSrc)(p.callbackInfo[e]?.logo),a=p.callbackInfo[e]?.description;return(0,t.jsx)(x,{value:e,label:e,children:(0,t.jsx)(l.Tooltip,{title:a,placement:"right",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[s&&(0,t.jsx)("img",{src:s,alt:e,className:"w-4 h-4 object-contain",onError:t=>{let s=t.target,l=s.parentElement;if(l){let t=document.createElement("div");t.className="w-4 h-4 rounded-full bg-gray-200 flex items-center justify-center text-xs",t.textContent=e.charAt(0),l.replaceChild(t,s)}}}),(0,t.jsx)("span",{children:e})]})})},e)})})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Event Type"}),(0,t.jsxs)(s.Select,{value:a.callback_type,onChange:e=>w(d,"callback_type",e),className:"w-full",children:[(0,t.jsx)(x,{value:"success",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("div",{className:"w-2 h-2 bg-green-500 rounded-full"}),(0,t.jsx)("span",{children:"Success Only"})]})}),(0,t.jsx)(x,{value:"failure",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("div",{className:"w-2 h-2 bg-red-500 rounded-full"}),(0,t.jsx)("span",{children:"Failure Only"})]})}),(0,t.jsx)(x,{value:"success_and_failure",children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("div",{className:"w-2 h-2 bg-blue-500 rounded-full"}),(0,t.jsx)("span",{children:"Success & Failure"})]})})]})]})]}),((e,s)=>{if(!e.callback_name)return null;let a=Object.entries(p.callback_map).find(([t,s])=>s===e.callback_name)?.[0];if(!a)return null;let i=p.callbackInfo[a]?.dynamic_params||{};return 0===Object.keys(i).length?null:(0,t.jsxs)("div",{className:"mt-6 pt-4 border-t border-gray-100",children:[(0,t.jsxs)("div",{className:"flex items-center space-x-2 mb-4",children:[(0,t.jsx)("div",{className:"w-3 h-3 bg-blue-100 rounded-full flex items-center justify-center",children:(0,t.jsx)("div",{className:"w-1.5 h-1.5 bg-blue-500 rounded-full"})}),(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Integration Parameters"})]}),(0,t.jsx)("div",{className:"grid grid-cols-1 gap-4",children:Object.entries(i).map(([a,i])=>(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 capitalize flex items-center space-x-1",children:[(0,t.jsx)("span",{children:a.replace(/_/g," ")}),(0,t.jsx)(l.Tooltip,{title:`Environment variable reference recommended: os.environ/${a.toUpperCase()}`,children:(0,t.jsx)(r.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})}),"password"===i&&(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-medium bg-yellow-100 text-yellow-800",children:"Sensitive"}),"number"===i&&(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-0.5 rounded-sm text-xs font-medium bg-yellow-100 text-yellow-800",children:"Number"})]}),"number"===i&&(0,t.jsx)("span",{className:"text-xs text-gray-500",children:"Value must be between 0 and 1"}),"number"===i?(0,t.jsx)(h.default,{step:.01,width:400,placeholder:`os.environ/${a.toUpperCase()}`,value:e.callback_vars[a]||"",onChange:e=>N(s,a,e.target.value)}):(0,t.jsx)(o.TextInput,{type:"password"===i?"password":"text",placeholder:`os.environ/${a.toUpperCase()}`,value:e.callback_vars[a]||"",onChange:e=>N(s,a,e.target.value)})]},a))})]})})(a,d)]})]},d)})}),0===e.length&&(0,t.jsxs)("div",{className:"text-center py-12 text-gray-500 border-2 border-dashed border-gray-200 rounded-lg bg-gray-50/50",children:[(0,t.jsx)(u.CogIcon,{className:"w-12 h-12 text-gray-300 mb-3 mx-auto"}),(0,t.jsx)("div",{className:"text-base font-medium mb-1",children:"No logging integrations configured"}),(0,t.jsx)("div",{className:"text-sm text-gray-400",children:'Click "Add Integration" to configure logging for this team'})]})]})}])},460285,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(404206),a=e.i(723731),r=e.i(653824),i=e.i(881073),n=e.i(197647),o=e.i(602869),d=e.i(158392),c=e.i(419470),u=e.i(695411);let m=(0,s.forwardRef)(({accessToken:e,value:m,onChange:p,modelData:g},h)=>{let[x,y]=(0,s.useState)({routerSettings:{},selectedStrategy:null,enableTagFiltering:!1}),[f,b]=(0,s.useState)([]),[_,j]=(0,s.useState)([]),[v,w]=(0,s.useState)([]),[N,k]=(0,s.useState)([]),[S,C]=(0,s.useState)({}),[T,I]=(0,s.useState)({}),A=(0,s.useRef)(!1),L=(0,s.useRef)(null);(0,s.useEffect)(()=>{let e=m?.router_settings?JSON.stringify({routing_strategy:m.router_settings.routing_strategy,fallbacks:m.router_settings.fallbacks,enable_tag_filtering:m.router_settings.enable_tag_filtering}):null;if(A.current&&e===L.current){A.current=!1;return}if(A.current&&e!==L.current&&(A.current=!1),e!==L.current)if(L.current=e,m?.router_settings){let e=m.router_settings,{fallbacks:t,...s}=e;y({routerSettings:s,selectedStrategy:e.routing_strategy||null,enableTagFiltering:e.enable_tag_filtering??!1});let l=e.fallbacks||[];b(l),j(l&&0!==l.length?l.map((e,t)=>{let[s,l]=Object.entries(e)[0];return{id:(t+1).toString(),primaryModel:s||null,fallbackModels:l||[]}}):[{id:"1",primaryModel:null,fallbackModels:[]}])}else y({routerSettings:{},selectedStrategy:null,enableTagFiltering:!1}),b([]),j([{id:"1",primaryModel:null,fallbackModels:[]}])},[m]),(0,s.useEffect)(()=>{e&&(0,o.getRouterSettingsCall)(e).then(e=>{if(e.fields){let t={};e.fields.forEach(e=>{t[e.field_name]={ui_field_name:e.ui_field_name,field_description:e.field_description,options:e.options,link:e.link}}),C(t);let s=e.fields.find(e=>"routing_strategy"===e.field_name);s?.options&&k(s.options),e.routing_strategy_descriptions&&I(e.routing_strategy_descriptions)}})},[e]),(0,s.useEffect)(()=>{e&&(async()=>{try{let t=await (0,u.fetchAvailableModels)(e);w(t)}catch(e){console.error("Error fetching model info for fallbacks:",e)}})()},[e]);let F=()=>{let e=new Set(["allowed_fails","cooldown_time","num_retries","timeout","retry_after"]),t=new Set(["model_group_alias","retry_policy"]),s=Object.fromEntries(Object.entries({...x.routerSettings,enable_tag_filtering:x.enableTagFiltering,routing_strategy:x.selectedStrategy,fallbacks:f.length>0?f:null}).map(([s,l])=>{if("routing_strategy_args"!==s&&"routing_strategy"!==s&&"enable_tag_filtering"!==s&&"fallbacks"!==s){let a=document.querySelector(`input[name="${s}"]`);if(a){if(void 0!==a.value&&""!==a.value){let r=((s,l,a)=>{if(null==l)return a;let r=String(l).trim();if(""===r||"null"===r.toLowerCase())return null;if(e.has(s)){let e=Number(r);return Number.isNaN(e)?a:e}if(t.has(s)){if(""===r)return null;try{return JSON.parse(r)}catch{return a}}return"true"===r.toLowerCase()||"false"!==r.toLowerCase()&&r})(s,a.value,l);return[s,r]}return[s,null]}}else if("routing_strategy"===s)return[s,x.selectedStrategy];else if("enable_tag_filtering"===s)return[s,x.enableTagFiltering];else if("fallbacks"===s)return[s,f.length>0?f:null];else if("routing_strategy_args"===s&&"latency-based-routing"===x.selectedStrategy){let e=document.querySelector('input[name="lowest_latency_buffer"]'),t=document.querySelector('input[name="ttl"]'),s={};return e?.value&&(s.lowest_latency_buffer=Number(e.value)),t?.value&&(s.ttl=Number(t.value)),["routing_strategy_args",Object.keys(s).length>0?s:null]}return[s,l]}).filter(e=>null!=e)),l=(e,t=!1)=>null==e||"object"==typeof e&&!Array.isArray(e)&&0===Object.keys(e).length||t&&("number"!=typeof e||Number.isNaN(e))?null:e;return{routing_strategy:l(s.routing_strategy),allowed_fails:l(s.allowed_fails,!0),cooldown_time:l(s.cooldown_time,!0),num_retries:l(s.num_retries,!0),timeout:l(s.timeout,!0),retry_after:l(s.retry_after,!0),fallbacks:f.length>0?f:null,context_window_fallbacks:l(s.context_window_fallbacks),retry_policy:l(s.retry_policy),model_group_alias:l(s.model_group_alias),enable_tag_filtering:x.enableTagFiltering,routing_strategy_args:l(s.routing_strategy_args)}};(0,s.useEffect)(()=>{if(!p)return;let e=setTimeout(()=>{A.current=!0,p({router_settings:F()})},100);return()=>clearTimeout(e)},[x,f]);let M=Array.from(new Set(v.map(e=>e.model_group))).sort();return((0,s.useImperativeHandle)(h,()=>({getValue:()=>({router_settings:F()})})),e)?(0,t.jsx)("div",{className:"w-full",children:(0,t.jsxs)(r.TabGroup,{className:"w-full",children:[(0,t.jsxs)(i.TabList,{variant:"line",defaultValue:"1",className:"px-8 pt-4",children:[(0,t.jsx)(n.Tab,{value:"1",children:"Loadbalancing"}),(0,t.jsx)(n.Tab,{value:"2",children:"Fallbacks"})]}),(0,t.jsxs)(a.TabPanels,{className:"px-8 py-6",children:[(0,t.jsx)(l.TabPanel,{children:(0,t.jsx)(d.default,{value:x,onChange:y,routerFieldsMetadata:S,availableRoutingStrategies:N,routingStrategyDescriptions:T})}),(0,t.jsx)(l.TabPanel,{children:(0,t.jsx)(c.FallbackSelectionForm,{groups:_,onGroupsChange:e=>{j(e),b(e.filter(e=>e.primaryModel&&e.fallbackModels.length>0).map(e=>({[e.primaryModel]:e.fallbackModels})))},availableModels:M,maxGroups:5})})]})]})}):null});m.displayName="RouterSettingsAccordion",e.s(["default",0,m])},207082,e=>{"use strict";var t=e.i(619273),s=e.i(266027),l=e.i(243652),a=e.i(602869),r=e.i(431703),i=e.i(135214);let n=(0,l.createQueryKeys)("keys"),o=async(e,t,s,l={})=>{try{let i=(0,a.getProxyBaseUrl)(),n=new URLSearchParams(Object.entries({team_id:l.teamID,project_id:l.projectID,agent_id:l.agentID,organization_id:l.organizationID,key_alias:l.selectedKeyAlias,key_hash:l.keyHash,user_id:l.userID,page:t,size:s,sort_by:l.sortBy,sort_order:l.sortOrder,expand:l.expand,status:l.status,return_full_object:"true",include_team_keys:"true",include_created_by_keys:"true",substring_matching:"true"}).filter(([,e])=>null!=e).map(([e,t])=>[e,String(t)])),o=`${i?`${i}/key/list`:"/key/list"}?${n}`,d=await fetch(o,{method:"GET",headers:{[(0,a.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!d.ok){let e=await d.json(),t=(0,r.deriveErrorMessage)(e);throw(0,a.handleError)(t),Error(t)}return await d.json()}catch(e){throw console.error("Failed to list keys:",e),e}},d=(0,l.createQueryKeys)("deletedKeys");e.s(["keyKeys",0,n,"useDeletedKeys",0,(e,l,a={})=>{let{accessToken:r}=(0,i.default)();return(0,s.useQuery)({queryKey:d.list({page:e,limit:l,...a}),queryFn:async()=>await o(r,e,l,{...a,status:"deleted"}),enabled:!!r,staleTime:3e4,placeholderData:t.keepPreviousData})},"useKeys",0,(e,l,a={})=>{let{accessToken:r}=(0,i.default)();return(0,s.useQuery)({queryKey:n.list({page:e,limit:l,...a}),queryFn:async()=>await o(r,e,l,a),enabled:!!r,staleTime:3e4,placeholderData:t.keepPreviousData})}])},510674,e=>{"use strict";var t=e.i(266027),s=e.i(243652),l=e.i(602869),a=e.i(431703),r=e.i(135214),i=e.i(708347);let n=(0,s.createQueryKeys)("projects"),o=[...i.all_admin_roles,...i.internalUserRoles],d=async e=>{let t=(0,l.getProxyBaseUrl)(),s=`${t}/project/list`,r=await fetch(s,{method:"GET",headers:{[(0,l.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!r.ok){let e=await r.json(),t=(0,a.deriveErrorMessage)(e);throw(0,l.handleError)(t),Error(t)}return r.json()};e.s(["projectKeys",0,n,"useProjects",0,()=>{let{accessToken:e,userRole:s}=(0,r.default)();return(0,t.useQuery)({queryKey:n.list({}),queryFn:async()=>d(e),enabled:!!e&&o.includes(s)})}])},392110,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(199133),a=e.i(592968),r=e.i(312361),i=e.i(790848),n=e.i(536916),o=e.i(827252),d=e.i(779241);let{Option:c}=l.Select;e.s(["default",0,({form:e,autoRotationEnabled:u,onAutoRotationChange:m,rotationInterval:p,onRotationIntervalChange:g,isCreateMode:h=!1,neverExpire:x=!1,onNeverExpireChange:y})=>{let f=p&&!["7d","30d","90d","180d","365d"].includes(p),[b,_]=(0,s.useState)(f),[j,v]=(0,s.useState)(f?p:""),[w,N]=(0,s.useState)(e?.getFieldValue?.("duration")||"");return(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Key Expiry Settings"}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,t.jsx)("span",{children:"Expire Key"}),(0,t.jsx)(a.Tooltip,{title:"Set when this key should expire. Format: 30s (seconds), 30m (minutes), 30h (hours), 30d (days). Leave empty to keep the current expiry unchanged.",children:(0,t.jsx)(o.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})}),!h&&y&&(0,t.jsx)(n.Checkbox,{checked:x,onChange:t=>{let s=t.target.checked;y(s),s&&(N(""),e&&"function"==typeof e.setFieldValue?e.setFieldValue("duration",""):e&&"function"==typeof e.setFieldsValue&&e.setFieldsValue({duration:""}))},className:"ml-2 text-sm font-normal text-gray-600",children:"Never Expire"})]}),(0,t.jsx)(d.TextInput,{name:"duration",placeholder:h?"e.g., 30d or leave empty to never expire":"e.g., 30d",className:"w-full",value:w,onValueChange:t=>{N(t),e&&"function"==typeof e.setFieldValue?e.setFieldValue("duration",t):e&&"function"==typeof e.setFieldsValue&&e.setFieldsValue({duration:t})},disabled:!h&&x})]})]}),(0,t.jsx)(r.Divider,{}),(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Auto-Rotation Settings"}),(0,t.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,t.jsx)("span",{children:"Enable Auto-Rotation"}),(0,t.jsx)(a.Tooltip,{title:"Key will automatically regenerate at the specified interval for enhanced security.",children:(0,t.jsx)(o.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})})]}),(0,t.jsx)(i.Switch,{checked:u,onChange:m,size:"default",className:u?"":"bg-gray-400"})]}),u&&(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"text-sm font-medium text-gray-700 flex items-center space-x-1",children:[(0,t.jsx)("span",{children:"Rotation Interval"}),(0,t.jsx)(a.Tooltip,{title:"How often the key should be automatically rotated. Choose the interval that best fits your security requirements.",children:(0,t.jsx)(o.InfoCircleOutlined,{className:"text-gray-400 cursor-help text-xs"})})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)(l.Select,{value:b?"custom":p,onChange:e=>{"custom"===e?_(!0):(_(!1),v(""),g(e))},className:"w-full",placeholder:"Select interval",children:[(0,t.jsx)(c,{value:"7d",children:"7 days"}),(0,t.jsx)(c,{value:"30d",children:"30 days"}),(0,t.jsx)(c,{value:"90d",children:"90 days"}),(0,t.jsx)(c,{value:"180d",children:"180 days"}),(0,t.jsx)(c,{value:"365d",children:"365 days"}),(0,t.jsx)(c,{value:"custom",children:"Custom interval"})]}),b&&(0,t.jsxs)("div",{className:"space-y-1",children:[(0,t.jsx)(d.TextInput,{value:j,onChange:e=>{let t=e.target.value;v(t),g(t)},placeholder:"e.g., 1s, 5m, 2h, 14d"}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Supported formats: seconds (s), minutes (m), hours (h), days (d)"})]})]})]})]}),u&&(0,t.jsx)("div",{className:"bg-blue-50 p-3 rounded-md text-sm text-blue-700",children:"When rotation occurs, you'll receive a notification with the new key. The old key will be deactivated after a brief grace period."})]})]})}])},939510,e=>{"use strict";var t=e.i(843476),s=e.i(808613),l=e.i(199133),a=e.i(592968),r=e.i(827252);let{Option:i}=l.Select;e.s(["default",0,({type:e,name:n,showDetailedDescriptions:o=!0,className:d="",initialValue:c=null,form:u,onChange:m})=>{let p=e.toUpperCase(),g=e.toLowerCase(),h=`Select 'guaranteed_throughput' to prevent overallocating ${p} limit when the key belongs to a Team with specific ${p} limits.`;return(0,t.jsx)(s.Form.Item,{label:(0,t.jsxs)("span",{children:[p," Rate Limit Type"," ",(0,t.jsx)(a.Tooltip,{title:h,children:(0,t.jsx)(r.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:n,initialValue:c,className:d,children:(0,t.jsx)(l.Select,{defaultValue:o?"default":void 0,placeholder:"Select rate limit type",style:{width:"100%"},optionLabelProp:o?"label":void 0,onChange:e=>{u&&u.setFieldValue(n,e),m&&m(e)},children:o?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i,{value:"best_effort_throughput",label:"Default",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)("div",{style:{fontWeight:500},children:"Default"}),(0,t.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["Best effort throughput - no error if we're overallocating ",g," (Team/Key Limits checked at runtime)."]})]})}),(0,t.jsx)(i,{value:"guaranteed_throughput",label:"Guaranteed throughput",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)("div",{style:{fontWeight:500},children:"Guaranteed throughput"}),(0,t.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["Guaranteed throughput - raise an error if we're overallocating ",g," (also checks model-specific limits)"]})]})}),(0,t.jsx)(i,{value:"dynamic",label:"Dynamic",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)("div",{style:{fontWeight:500},children:"Dynamic"}),(0,t.jsxs)("div",{style:{fontSize:"11px",color:"#6b7280",marginTop:"2px"},children:["If the key has a set ",p," (e.g. 2 ",p,") and there are no 429 errors, it can dynamically exceed the limit when the model being called is not erroring."]})]})})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i,{value:"best_effort_throughput",children:"Best effort throughput"}),(0,t.jsx)(i,{value:"guaranteed_throughput",children:"Guaranteed throughput"}),(0,t.jsx)(i,{value:"dynamic",children:"Dynamic"})]})})})}])},363256,e=>{"use strict";var t=e.i(843476),s=e.i(199133);let{Text:l}=e.i(898586).Typography;e.s(["default",0,({organizations:e,value:a,onChange:r,disabled:i,loading:n,style:o})=>(0,t.jsx)(s.Select,{showSearch:!0,placeholder:"All Organizations",value:a,onChange:r,disabled:i,loading:n,allowClear:!0,style:{minWidth:280,...o},filterOption:(t,s)=>{if(!s)return!1;let l=e?.find(e=>e.organization_id===s.key);if(!l)return!1;let a=t.toLowerCase().trim(),r=(l.organization_alias||"").toLowerCase(),i=(l.organization_id||"").toLowerCase();return r.includes(a)||i.includes(a)},children:e?.map(e=>(0,t.jsxs)(s.Select.Option,{value:e.organization_id,children:[(0,t.jsx)("span",{className:"font-medium",children:e.organization_alias})," ",(0,t.jsxs)(l,{type:"secondary",children:["(",e.organization_id,")"]})]},e.organization_id))})])},128233,319312,e=>{"use strict";var t=e.i(843476),s=e.i(464571),l=e.i(199133),a=e.i(592968),r=e.i(425063),i=e.i(107233),n=e.i(37727),o=e.i(271645);e.s(["BudgetFallbacksEditor",0,function({value:e,onChange:d,availableModels:c}){let[u,m]=(0,o.useState)(()=>{let t;return 0===(t=Object.keys(e)).length?[]:t.map((t,s)=>({id:String(s+1),primaryModel:t,fallbackModels:e[t]}))}),p=e=>{m(e),d(Object.fromEntries(e.filter(e=>null!==e.primaryModel&&e.fallbackModels.length>0).map(e=>[e.primaryModel,e.fallbackModels])))},g=()=>{p([...u,{id:Date.now().toString(),primaryModel:null,fallbackModels:[]}])},h=(e,t)=>{p(u.map(s=>s.id===e?{...s,...t}:s))},x=new Set(u.map(e=>e.primaryModel).filter(Boolean));return 0===u.length?(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-xs text-gray-500 mb-2",children:"When a model exceeds its per-model budget, requests automatically reroute to fallback models"}),(0,t.jsx)(s.Button,{size:"small",onClick:g,icon:(0,t.jsx)(i.Plus,{className:"w-3 h-3"}),children:"Add Budget Fallback"})]}):(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"When a model exceeds its per-model budget, requests automatically reroute to fallback models"}),u.map(e=>{let s=c.filter(t=>t===e.primaryModel||!x.has(t)),i=c.filter(t=>t!==e.primaryModel);return(0,t.jsxs)("div",{className:"relative rounded-lg border border-gray-200 bg-gray-50 p-4",children:[(0,t.jsx)("button",{type:"button",onClick:()=>{var t;return t=e.id,void p(u.filter(e=>e.id!==t))},className:"absolute top-2 right-2 text-gray-400 hover:text-red-500 transition-colors p-1",children:(0,t.jsx)(n.X,{className:"w-4 h-4"})}),(0,t.jsxs)("div",{className:"mb-3",children:[(0,t.jsx)("label",{className:"block text-xs font-medium text-gray-600 mb-1",children:"Primary Model"}),(0,t.jsx)(l.Select,{className:"w-full",placeholder:"Select model",value:e.primaryModel,onChange:t=>{let s=e.fallbackModels.filter(e=>e!==t);h(e.id,{primaryModel:t,fallbackModels:s})},showSearch:!0,filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase()),options:s.map(e=>({label:e,value:e})),getPopupContainer:e=>e.parentElement||document.body})]}),(0,t.jsx)("div",{className:"flex items-center justify-center -my-1 mb-2",children:(0,t.jsxs)("div",{className:"bg-amber-50 text-amber-600 px-3 py-0.5 rounded-full text-[10px] font-bold border border-amber-100 flex items-center gap-1",children:[(0,t.jsx)(r.ArrowDown,{className:"w-3 h-3"}),"IF BUDGET EXCEEDED, TRY"]})}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs font-medium text-gray-600 mb-1",children:"Fallback Models"}),(0,t.jsx)(l.Select,{mode:"multiple",className:"w-full",placeholder:e.primaryModel?"Select fallback models":"Select a primary model first",value:e.fallbackModels,onChange:t=>h(e.id,{fallbackModels:t}),disabled:!e.primaryModel,showSearch:!0,filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase()),options:i.map(e=>({label:e,value:e})),getPopupContainer:e=>e.parentElement||document.body,maxTagCount:"responsive",maxTagPlaceholder:e=>(0,t.jsx)(a.Tooltip,{styles:{root:{pointerEvents:"none"}},title:e.map(({value:e})=>e).join(", "),children:(0,t.jsxs)("span",{children:["+",e.length," more"]})})}),e.fallbackModels.length>1&&(0,t.jsx)("div",{className:"text-[10px] text-gray-400 mt-1 ml-1",children:"Tried in order; first model still within its own budget is used"})]})]},e.id)}),(0,t.jsx)(s.Button,{size:"small",onClick:g,icon:(0,t.jsx)(i.Plus,{className:"w-3 h-3"}),children:"Add Budget Fallback"})]})}],128233);var d=e.i(28651);let c=[{value:"1h",label:"Hourly",resetHint:"Resets every hour"},{value:"24h",label:"Daily",resetHint:"Resets daily at midnight UTC"},{value:"7d",label:"Weekly",resetHint:"Resets every Sunday at midnight UTC"},{value:"30d",label:"Monthly",resetHint:"Resets on the 1st of every month at midnight UTC"}];e.s(["BudgetWindowsEditor",0,function({value:e,onChange:a}){let r=(t,s,l)=>{a(e.map((e,a)=>a===t?{...e,[s]:l}:e))};return(0,t.jsxs)("div",{children:[e.map((i,n)=>{let o=c.find(e=>e.value===i.budget_duration)?.resetHint;return(0,t.jsxs)("div",{style:{marginBottom:12},children:[(0,t.jsxs)("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[(0,t.jsx)(l.Select,{value:i.budget_duration,onChange:e=>r(n,"budget_duration",e),style:{width:130},options:c.map(e=>({value:e.value,label:e.label}))}),(0,t.jsx)(d.InputNumber,{step:.01,min:0,precision:2,value:i.max_budget??void 0,onChange:e=>r(n,"max_budget",e??null),placeholder:"Max spend ($)",style:{width:160},prefix:"$"}),(0,t.jsx)(s.Button,{type:"text",danger:!0,size:"small",onClick:()=>{a(e.filter((e,t)=>t!==n))},style:{padding:"0 4px"},children:"✕"})]}),o&&(0,t.jsxs)("div",{style:{fontSize:11,color:"#888",marginTop:3,marginLeft:2},children:["↻ ",o]})]},n)}),(0,t.jsx)(s.Button,{size:"small",onClick:t=>{t.preventDefault(),a([...e,{budget_duration:"24h",max_budget:null}])},children:"+ Add Budget Window"})]})}],319312)},109034,e=>{"use strict";var t=e.i(266027),s=e.i(243652),l=e.i(602869),a=e.i(135214);let r=(0,s.createQueryKeys)("tags");e.s(["useTags",0,()=>{let{accessToken:e,userId:s,userRole:i}=(0,a.default)();return(0,t.useQuery)({queryKey:r.list({}),queryFn:async()=>await (0,l.tagListCall)(e),enabled:!!(e&&s&&i)})}])},533882,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(250980),a=e.i(797672),r=e.i(68155),i=e.i(304967),n=e.i(629569),o=e.i(599724),d=e.i(269200),c=e.i(427612),u=e.i(64848),m=e.i(942232),p=e.i(496020),g=e.i(977572),h=e.i(992619),x=e.i(727749);e.s(["default",0,({accessToken:e,initialModelAliases:y={},onAliasUpdate:f,showExampleConfig:b=!0})=>{let[_,j]=(0,s.useState)([]),[v,w]=(0,s.useState)({aliasName:"",targetModel:""}),[N,k]=(0,s.useState)(null);(0,s.useEffect)(()=>{j(Object.entries(y).map(([e,t],s)=>({id:`${s}-${e}`,aliasName:e,targetModel:t})))},[y]);let S=()=>{if(!N)return;if(!N.aliasName||!N.targetModel)return void x.default.fromBackend("Please provide both alias name and target model");if(_.some(e=>e.id!==N.id&&e.aliasName===N.aliasName))return void x.default.fromBackend("An alias with this name already exists");let e=_.map(e=>e.id===N.id?N:e);j(e),k(null);let t={};e.forEach(e=>{t[e.aliasName]=e.targetModel}),f&&f(t),x.default.success("Alias updated successfully")},C=()=>{k(null)},T=_.reduce((e,t)=>(e[t.aliasName]=t.targetModel,e),{});return(0,t.jsxs)("div",{className:"mt-4",children:[(0,t.jsxs)("div",{className:"mb-6",children:[(0,t.jsx)(o.Text,{className:"text-sm font-medium text-gray-700 mb-2",children:"Add New Alias"}),(0,t.jsxs)("div",{className:"grid grid-cols-3 gap-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Alias Name"}),(0,t.jsx)("input",{type:"text",value:v.aliasName,onChange:e=>w({...v,aliasName:e.target.value}),placeholder:"e.g., gpt-4o",className:"w-full px-3 py-2 border border-gray-300 rounded-md text-sm"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Target Model"}),(0,t.jsx)(h.default,{accessToken:e,value:v.targetModel,placeholder:"Select target model",onChange:e=>w({...v,targetModel:e}),showLabel:!1})]}),(0,t.jsx)("div",{className:"flex items-end",children:(0,t.jsxs)("button",{onClick:()=>{if(!v.aliasName||!v.targetModel)return void x.default.fromBackend("Please provide both alias name and target model");if(_.some(e=>e.aliasName===v.aliasName))return void x.default.fromBackend("An alias with this name already exists");let e=[..._,{id:`${Date.now()}-${v.aliasName}`,aliasName:v.aliasName,targetModel:v.targetModel}];j(e),w({aliasName:"",targetModel:""});let t={};e.forEach(e=>{t[e.aliasName]=e.targetModel}),f&&f(t),x.default.success("Alias added successfully")},disabled:!v.aliasName||!v.targetModel,className:`flex items-center px-4 py-2 rounded-md text-sm ${!v.aliasName||!v.targetModel?"bg-gray-300 text-gray-500 cursor-not-allowed":"bg-green-600 text-white hover:bg-green-700"}`,children:[(0,t.jsx)(l.PlusCircleIcon,{className:"w-4 h-4 mr-1"}),"Add Alias"]})})]})]}),(0,t.jsx)(o.Text,{className:"text-sm font-medium text-gray-700 mb-2",children:"Manage Existing Aliases"}),(0,t.jsx)("div",{className:"rounded-lg custom-border relative mb-6",children:(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsxs)(d.Table,{className:"[&_td]:py-0.5 [&_th]:py-1",children:[(0,t.jsx)(c.TableHead,{children:(0,t.jsxs)(p.TableRow,{children:[(0,t.jsx)(u.TableHeaderCell,{className:"py-1 h-8",children:"Alias Name"}),(0,t.jsx)(u.TableHeaderCell,{className:"py-1 h-8",children:"Target Model"}),(0,t.jsx)(u.TableHeaderCell,{className:"py-1 h-8",children:"Actions"})]})}),(0,t.jsxs)(m.TableBody,{children:[_.map(s=>(0,t.jsx)(p.TableRow,{className:"h-8",children:N&&N.id===s.id?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(g.TableCell,{className:"py-0.5",children:(0,t.jsx)("input",{type:"text",value:N.aliasName,onChange:e=>k({...N,aliasName:e.target.value}),className:"w-full px-2 py-1 border border-gray-300 rounded-md text-sm"})}),(0,t.jsx)(g.TableCell,{className:"py-0.5",children:(0,t.jsx)(h.default,{accessToken:e,value:N.targetModel,onChange:e=>k({...N,targetModel:e}),showLabel:!1,style:{height:"32px"}})}),(0,t.jsx)(g.TableCell,{className:"py-0.5 whitespace-nowrap",children:(0,t.jsxs)("div",{className:"flex space-x-2",children:[(0,t.jsx)("button",{onClick:S,className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded-sm hover:bg-blue-100",children:"Save"}),(0,t.jsx)("button",{onClick:C,className:"text-xs bg-gray-50 text-gray-600 px-2 py-1 rounded-sm hover:bg-gray-100",children:"Cancel"})]})})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(g.TableCell,{className:"py-0.5 text-sm text-gray-900",children:s.aliasName}),(0,t.jsx)(g.TableCell,{className:"py-0.5 text-sm text-gray-500",children:s.targetModel}),(0,t.jsx)(g.TableCell,{className:"py-0.5 whitespace-nowrap",children:(0,t.jsxs)("div",{className:"flex space-x-2",children:[(0,t.jsx)("button",{onClick:()=>{k({...s})},className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded-sm hover:bg-blue-100",children:(0,t.jsx)(a.PencilIcon,{className:"w-3 h-3"})}),(0,t.jsx)("button",{onClick:()=>{var e;let t,l;return e=s.id,j(t=_.filter(t=>t.id!==e)),l={},void(t.forEach(e=>{l[e.aliasName]=e.targetModel}),f&&f(l),x.default.success("Alias deleted successfully"))},className:"text-xs bg-red-50 text-red-600 px-2 py-1 rounded-sm hover:bg-red-100",children:(0,t.jsx)(r.TrashIcon,{className:"w-3 h-3"})})]})})]})},s.id)),0===_.length&&(0,t.jsx)(p.TableRow,{children:(0,t.jsx)(g.TableCell,{colSpan:3,className:"py-0.5 text-sm text-gray-500 text-center",children:"No aliases added yet. Add a new alias above."})})]})]})})}),b&&(0,t.jsxs)(i.Card,{children:[(0,t.jsx)(n.Title,{className:"mb-4",children:"Configuration Example"}),(0,t.jsx)(o.Text,{className:"text-gray-600 mb-4",children:"Here's how your current aliases would look in the config:"}),(0,t.jsx)("div",{className:"bg-gray-100 rounded-lg p-4 font-mono text-sm",children:(0,t.jsxs)("div",{className:"text-gray-700",children:["model_aliases:",0===Object.keys(T).length?(0,t.jsxs)("span",{className:"text-gray-500",children:[(0,t.jsx)("br",{}),"  # No aliases configured yet"]}):Object.entries(T).map(([e,s])=>(0,t.jsxs)("span",{children:[(0,t.jsx)("br",{}),'  "',e,'": "',s,'"']},e))]})})]})]})}])},651904,e=>{"use strict";var t=e.i(843476),s=e.i(599724),l=e.i(266484);e.s(["default",0,function({value:e,onChange:a,premiumUser:r=!1,disabledCallbacks:i=[],onDisabledCallbacksChange:n}){return r?(0,t.jsx)(l.default,{value:e,onChange:a,disabledCallbacks:i,onDisabledCallbacksChange:n}):(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex flex-wrap gap-2 mb-3",children:[(0,t.jsx)("div",{className:"inline-flex items-center px-3 py-1.5 rounded-lg bg-green-50 border border-green-200 text-green-800 text-sm font-medium opacity-50",children:"✨ langfuse-logging"}),(0,t.jsx)("div",{className:"inline-flex items-center px-3 py-1.5 rounded-lg bg-green-50 border border-green-200 text-green-800 text-sm font-medium opacity-50",children:"✨ datadog-logging"})]}),(0,t.jsx)("div",{className:"p-3 bg-yellow-50 border border-yellow-200 rounded-lg",children:(0,t.jsxs)(s.Text,{className:"text-sm text-yellow-800",children:["Setting Key/Team logging settings is a LiteLLM Enterprise feature. Global Logging Settings are available for all free users. Get a trial key"," ",(0,t.jsx)("a",{href:"https://www.litellm.ai/#pricing",target:"_blank",rel:"noopener noreferrer",className:"underline",children:"here"}),"."]})})]})}])},575260,e=>{"use strict";var t=e.i(843476),s=e.i(199133),l=e.i(482725),a=e.i(56456);e.s(["default",0,({projects:e,value:r,onChange:i,disabled:n,loading:o,teamId:d})=>{let c=d?e?.filter(e=>e.team_id===d):e;return(0,t.jsx)(s.Select,{showSearch:!0,placeholder:"Search or select a project",value:r,onChange:i,disabled:n,loading:o,allowClear:!0,notFoundContent:o?(0,t.jsx)(l.Spin,{indicator:(0,t.jsx)(a.LoadingOutlined,{spin:!0}),size:"small"}):void 0,filterOption:(e,t)=>{if(!t)return!1;let s=c?.find(e=>e.project_id===t.key);if(!s)return!1;let l=e.toLowerCase().trim(),a=(s.project_alias||"").toLowerCase(),r=(s.project_id||"").toLowerCase();return a.includes(l)||r.includes(l)},optionFilterProp:"children",children:!o&&c?.map(e=>(0,t.jsxs)(s.Select.Option,{value:e.project_id,children:[(0,t.jsx)("span",{className:"font-medium",children:e.project_alias||e.project_id})," ",(0,t.jsxs)("span",{className:"text-gray-500",children:["(",e.project_id,")"]})]},e.project_id))})}])},364769,e=>{"use strict";var t=e.i(843476),s=e.i(271645),l=e.i(237016),a=e.i(464571),r=e.i(888259);e.s(["default",0,({apiKey:e})=>{let[i,n]=(0,s.useState)(!1);return(0,t.jsxs)("div",{children:[(0,t.jsxs)("p",{className:"mb-2",children:["Please save this secret key somewhere safe and accessible. For security reasons,"," ",(0,t.jsx)("b",{children:"you will not be able to view it again"})," through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]}),(0,t.jsx)("p",{className:"text-sm text-gray-600 mt-3 mb-1",children:"Virtual Key:"}),(0,t.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,t.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal",margin:0},children:e})}),(0,t.jsx)(l.CopyToClipboard,{text:e,onCopy:()=>{n(!0),r.default.success("Key copied to clipboard"),setTimeout(()=>n(!1),2e3)},children:(0,t.jsx)(a.Button,{type:"primary",style:{marginTop:12},children:i?"Copied!":"Copy Virtual Key"})})]})}])},702597,e=>{"use strict";var t=e.i(843476),s=e.i(207082),l=e.i(109799),a=e.i(510674),r=e.i(109034),i=e.i(292639),n=e.i(135214),o=e.i(500330),d=e.i(827252),c=e.i(912598),u=e.i(677667),m=e.i(130643),p=e.i(898667),g=e.i(994388),h=e.i(309426),x=e.i(350967),y=e.i(599724),f=e.i(779241),b=e.i(629569),_=e.i(464571),j=e.i(808613),v=e.i(311451),w=e.i(212931),N=e.i(91739),k=e.i(199133),S=e.i(790848),C=e.i(262218),T=e.i(592968),I=e.i(898586),A=e.i(374009),L=e.i(271645),F=e.i(708347),M=e.i(552130),O=e.i(557662),E=e.i(9314),P=e.i(860585),B=e.i(82946),$=e.i(392110),R=e.i(533882),D=e.i(844565),V=e.i(651904),z=e.i(939510),U=e.i(460285),G=e.i(663435),K=e.i(363256),q=e.i(575260),W=e.i(371455),H=e.i(128233),Q=e.i(319312),J=e.i(355619),Y=e.i(75921),X=e.i(234713),Z=e.i(390605),ee=e.i(727749),et=e.i(602869),es=e.i(364769),el=e.i(435451),ea=e.i(916940);let{Option:er}=k.Select,ei=async(e,t,s,l)=>{try{if(null===e||null===t)return[];if(null!==s)return(await (0,et.modelAvailableCall)(s,e,t,!0,l,!0)).data.map(e=>e.id);return[]}catch(e){return console.error("Error fetching user models:",e),[]}},en=async(e,t,s,l)=>{try{if(null===e||null===t)return;if(null!==s){let a=(await (0,et.modelAvailableCall)(s,e,t)).data.map(e=>e.id);l(a)}}catch(e){console.error("Error fetching user models:",e)}};e.s(["default",0,({team:e,teams:eo,data:ed,addKey:ec,autoOpenCreate:eu,prefillData:em})=>{let{accessToken:ep,userId:eg,userRole:eh,premiumUser:ex}=(0,n.default)(),ey=ex||null!=eh&&F.rolesWithWriteAccess.includes(eh),{data:ef,isLoading:eb}=(0,l.useOrganizations)(),{data:e_,isLoading:ej}=(0,a.useProjects)(),{data:ev}=(0,i.useUISettings)(),{data:ew}=(0,r.useTags)(),eN=!!ev?.values?.enable_projects_ui,ek=!!ev?.values?.disable_custom_api_keys,eS=ew?Object.values(ew).map(e=>({value:e.name,label:e.name})):[],eC=(0,c.useQueryClient)(),[eT]=j.Form.useForm(),[eI,eA]=(0,L.useState)(!1),[eL,eF]=(0,L.useState)(null),[eM,eO]=(0,L.useState)(null),[eE,eP]=(0,L.useState)([]),[eB,e$]=(0,L.useState)([]),[eR,eD]=(0,L.useState)("you"),[eV,ez]=(0,L.useState)(!1),[eU,eG]=(0,L.useState)(null),[eK,eq]=(0,L.useState)([]),[eW,eH]=(0,L.useState)([]),[eQ,eJ]=(0,L.useState)([]),[eY,eX]=(0,L.useState)([]),[eZ,e0]=(0,L.useState)(e),[e1,e2]=(0,L.useState)(null),[e4,e3]=(0,L.useState)(null),[e5,e6]=(0,L.useState)(!1),[e7,e9]=(0,L.useState)(null),[e8,te]=(0,L.useState)({}),[tt,ts]=(0,L.useState)([]),[tl,ta]=(0,L.useState)(!1),[tr,ti]=(0,L.useState)([]),[tn,to]=(0,L.useState)([]),[td,tc]=(0,L.useState)("llm_api"),[tu,tm]=(0,L.useState)({}),[tp,tg]=(0,L.useState)(!1),[th,tx]=(0,L.useState)("30d"),[ty,tf]=(0,L.useState)(null),[tb,t_]=(0,L.useState)([]),[tj,tv]=(0,L.useState)({}),[tw,tN]=(0,L.useState)(0),[tk,tS]=(0,L.useState)(0),[tC,tT]=(0,L.useState)([]),[tI,tA]=(0,L.useState)(null),tL=()=>{eA(!1),eT.resetFields(),eX([]),to([]),tc("llm_api"),tm({}),tg(!1),tx("30d"),tf(null),tS(e=>e+1),tA(null),e2(null),e3(null),t_([]),tv({}),tN(e=>e+1)},tF=()=>{eA(!1),eF(null),e0(null),eT.resetFields(),eX([]),to([]),tc("llm_api"),tm({}),tg(!1),tx("30d"),tf(null),tS(e=>e+1),tA(null),e2(null),e3(null),t_([]),tv({}),tN(e=>e+1)};(0,L.useEffect)(()=>{eg&&eh&&ep&&en(eg,eh,ep,eP)},[ep,eg,eh]),(0,L.useEffect)(()=>{ep&&(0,et.getAgentsList)(ep).then(e=>tT(e?.agents||[])).catch(()=>tT([]))},[ep]),(0,L.useEffect)(()=>{let e=async()=>{try{let e=(await (0,et.getPoliciesList)(ep)).policies.map(e=>e.policy_name);eH(e)}catch(e){console.error("Failed to fetch policies:",e)}},t=async()=>{try{let e=await (0,et.getPromptsList)(ep);eJ(e.prompts.map(e=>e.prompt_id))}catch(e){console.error("Failed to fetch prompts:",e)}};(async()=>{try{let e=(await (0,et.getGuardrailsList)(ep)).guardrails.map(e=>e.guardrail_name);eq(e)}catch(e){console.error("Failed to fetch guardrails:",e)}})(),e(),t()},[ep]),(0,L.useEffect)(()=>{(async()=>{try{if(ep){let e=sessionStorage.getItem("possibleUserRoles");if(e)te(JSON.parse(e));else{let e=await (0,et.getPossibleUserRoles)(ep);sessionStorage.setItem("possibleUserRoles",JSON.stringify(e)),te(e)}}}catch(e){console.error("Error fetching possible user roles:",e)}})()},[ep]),(0,L.useEffect)(()=>{if(eu&&!eV&&eo&&eh&&F.rolesWithWriteAccess.includes(eh)&&(eA(!0),ez(!0),em)){if(em.owned_by&&("another_user"===em.owned_by&&"Admin"!==eh?eD("you"):eD(em.owned_by)),em.team_id){let e=eo?.find(e=>e.team_id===em.team_id)||null;e&&(e0(e),eT.setFieldsValue({team_id:em.team_id}))}em.key_alias&&eT.setFieldsValue({key_alias:em.key_alias}),em.models&&em.models.length>0&&eG(em.models),em.key_type&&(tc(em.key_type),eT.setFieldsValue({key_type:em.key_type}))}},[eu,em,eo,eV,eT,eh]);let tM=eB.includes("no-default-models")&&!eZ,tO=async e=>{try{let t,l=e?.key_alias??"",a=e?.team_id??null;if((ed?.filter(e=>e.team_id===a).map(e=>e.key_alias)??[]).includes(l))throw Error(`Key alias ${l} already exists for team with ID ${a}, please provide another key alias`);if(ee.default.info("Making API Call"),eA(!0),"you"===eR)e.user_id=eg;else if("agent"===eR){if(!tI)return void ee.default.fromBackend("Please select an agent");e.agent_id=tI}let r={};try{r=JSON.parse(e.metadata||"{}")}catch(e){console.error("Error parsing metadata:",e)}if("service_account"===eR&&(r.service_account_id=e.key_alias),eY.length>0&&(r={...r,logging:eY.filter(e=>e.callback_name)}),tn.length>0){let e=(0,O.mapDisplayToInternalNames)(tn);r={...r,litellm_disabled_callbacks:e}}if(tp&&(e.auto_rotate=!0,e.rotation_interval=th),e.duration&&""!==e.duration.trim()||(e.duration=null),e.metadata=JSON.stringify(r),e.disable_global_guardrails||delete e.disable_global_guardrails,e.allowed_vector_store_ids&&e.allowed_vector_store_ids.length>0&&(e.object_permission={vector_stores:e.allowed_vector_store_ids},delete e.allowed_vector_store_ids),e.allowed_mcp_servers_and_groups&&(e.allowed_mcp_servers_and_groups.servers?.length>0||e.allowed_mcp_servers_and_groups.accessGroups?.length>0)){e.object_permission||(e.object_permission={});let{servers:t,accessGroups:s}=e.allowed_mcp_servers_and_groups;t&&t.length>0&&(e.object_permission.mcp_servers=t),s&&s.length>0&&(e.object_permission.mcp_access_groups=s),delete e.allowed_mcp_servers_and_groups}let i=e.mcp_tool_permissions||{};if(Object.keys(i).length>0&&(e.object_permission||(e.object_permission={}),e.object_permission.mcp_tool_permissions=i),delete e.mcp_tool_permissions,e.allowed_mcp_access_groups&&e.allowed_mcp_access_groups.length>0&&(e.object_permission||(e.object_permission={}),e.object_permission.mcp_access_groups=e.allowed_mcp_access_groups,delete e.allowed_mcp_access_groups),e.allowed_agents_and_groups&&(e.allowed_agents_and_groups.agents?.length>0||e.allowed_agents_and_groups.accessGroups?.length>0)){e.object_permission||(e.object_permission={});let{agents:t,accessGroups:s}=e.allowed_agents_and_groups;t&&t.length>0&&(e.object_permission.agents=t),s&&s.length>0&&(e.object_permission.agent_access_groups=s),delete e.allowed_agents_and_groups}Object.keys(tu).length>0&&(e.aliases=JSON.stringify(tu)),ty?.router_settings&&Object.values(ty.router_settings).some(e=>null!=e&&""!==e)&&(e.router_settings=ty.router_settings);let n=tb.filter(e=>e.budget_duration&&null!==e.max_budget&&void 0!==e.max_budget);n.length>0&&(e.budget_limits=n),Object.keys(tj).length>0&&(e.budget_fallbacks=tj),t="service_account"===eR?await (0,et.keyCreateServiceAccountCall)(ep,e):await (0,et.keyCreateCall)(ep,eg,e),ec(t),eC.invalidateQueries({queryKey:s.keyKeys.lists()}),eF(t.key),eO(t.soft_budget),ee.default.success("Virtual Key Created"),eT.resetFields(),t_([]),tv({}),tN(e=>e+1),localStorage.removeItem("userData"+eg)}catch(t){let e=(e=>{let t;if(!(t=!e||"object"!=typeof e||e instanceof Error?String(e):JSON.stringify(e)).includes("/key/generate")&&!t.includes("KeyManagementRoutes.KEY_GENERATE"))return`Error creating the key: ${e}`;let s=t;try{if(!e||"object"!=typeof e||e instanceof Error){let e=t.match(/\{[\s\S]*\}/);if(e){let t=JSON.parse(e[0]),l=t?.error||t;l?.message&&(s=l.message)}}else{let t=e?.error||e;t?.message&&(s=t.message)}}catch(e){}return t.includes("team_member_permission_error")||s.includes("Team member does not have permissions")?"Team member does not have permission to generate key for this team. Ask your proxy admin to configure the team member permission settings.":`Error creating the key: ${e}`})(t);ee.default.fromBackend(e)}};(0,L.useEffect)(()=>{if(e4){let e=e_?.find(e=>e.project_id===e4);e$(e?.models??[]),eT.setFieldValue("models",[]);return}eg&&eh&&ep&&ei(eg,eh,ep,eZ?.team_id??null).then(e=>{e$(Array.from(new Set([...eZ?.models??[],...e])))}),eU||eT.setFieldValue("models",[]),eT.setFieldValue("allowed_mcp_servers_and_groups",{servers:[],accessGroups:[]})},[eZ,e4,ep,eg,eh,eT]),(0,L.useEffect)(()=>{if(!eU||0===eU.length||!eB||0===eB.length)return;let e=eU.filter(e=>eB.includes(e));e.length>0&&eT.setFieldsValue({models:e}),eG(null)},[eU,eB,eT]),(0,L.useEffect)(()=>{if(!e4||!eo)return;let e=e_?.find(e=>e.project_id===e4);if(!e?.team_id||eZ?.team_id===e.team_id)return;let t=eo.find(t=>t.team_id===e.team_id)||null;t&&(e0(t),eT.setFieldValue("team_id",t.team_id))},[eo,e4,e_]);let tE=async e=>{if(!e)return void ts([]);ta(!0);try{let t=new URLSearchParams;if(t.append("user_email",e),null==ep)return;let s=(await (0,et.userFilterUICall)(ep,t)).map(e=>({label:`${e.user_email} (${e.user_id})`,value:e.user_id,user:e}));ts(s)}catch(e){console.error("Error fetching users:",e),ee.default.fromBackend("Failed to search for users")}finally{ta(!1)}},tP=(0,L.useCallback)((0,A.default)(e=>tE(e),300),[ep]);return(0,t.jsxs)("div",{children:[eh&&F.rolesWithWriteAccess.includes(eh)&&(0,t.jsx)(g.Button,{className:"mx-auto",onClick:()=>eA(!0),"data-testid":"create-key-button",children:"+ Create New Key"}),(0,t.jsx)(w.Modal,{open:eI,width:1e3,footer:null,onOk:tL,onCancel:tF,children:(0,t.jsxs)(j.Form,{form:eT,onFinish:tO,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,t.jsxs)("div",{className:"mb-8",children:[(0,t.jsx)(b.Title,{className:"mb-4",children:"Key Ownership"}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Owned By"," ",(0,t.jsx)(T.Tooltip,{title:"Select who will own this Virtual Key",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),className:"mb-4",children:(0,t.jsxs)(N.Radio.Group,{onChange:e=>eD(e.target.value),value:eR,children:[(0,t.jsx)(N.Radio,{value:"you",children:"You"}),(0,t.jsx)(N.Radio,{value:"service_account",children:"Service Account"}),"Admin"===eh&&(0,t.jsx)(N.Radio,{value:"another_user",children:"Another User"}),(0,t.jsxs)(N.Radio,{value:"agent",children:["Agent ",(0,t.jsx)(C.Tag,{color:"purple",children:"New"})]})]})}),"another_user"===eR&&(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["User ID"," ",(0,t.jsx)(T.Tooltip,{title:"The user who will own this key and be responsible for its usage",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"user_id",className:"mt-4",rules:[{required:"another_user"===eR,message:"Please input the user ID of the user you are assigning the key to"}],children:(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{style:{display:"flex",marginBottom:"8px"},children:[(0,t.jsx)(k.Select,{showSearch:!0,placeholder:"Type email to search for users",filterOption:!1,onSearch:e=>{tP(e)},onSelect:(e,t)=>{let s;return s=t.user,void eT.setFieldsValue({user_id:s.user_id})},options:tt,loading:tl,allowClear:!0,style:{width:"100%"},notFoundContent:tl?"Searching...":"No users found"}),(0,t.jsx)(_.Button,{onClick:()=>e6(!0),style:{marginLeft:"8px"},children:"Create User"})]}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Search by email to find users"})]})}),"agent"===eR&&(0,t.jsxs)("div",{className:"mt-4 p-4 bg-purple-50 border border-purple-200 rounded-md",children:[(0,t.jsx)("div",{className:"mb-3",children:(0,t.jsxs)("span",{className:"text-sm font-medium text-gray-700",children:["Select Agent ",(0,t.jsx)("span",{className:"text-red-500",children:"*"})]})}),(0,t.jsx)(k.Select,{showSearch:!0,placeholder:"Select an agent",style:{width:"100%"},value:tI,onChange:e=>tA(e),filterOption:(e,t)=>t?.label?.toLowerCase().includes(e.toLowerCase()),options:tC.map(e=>({label:e.agent_name||e.agent_id,value:e.agent_id}))}),(0,t.jsx)("div",{className:"text-xs text-gray-500 mt-2",children:"This key will be used by the selected agent to make requests to LiteLLM"})]}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Organization"," ",(0,t.jsx)(T.Tooltip,{title:"The organization this key belongs to. Selecting an organization filters the available teams.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"organization_id",className:"mt-4",children:(0,t.jsx)(K.default,{organizations:ef,loading:eb,disabled:"Admin"!==eh,onChange:e=>{e2(e||null),e0(null),e3(null),eT.setFieldValue("team_id",void 0),eT.setFieldValue("project_id",void 0)}})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Team"," ",(0,t.jsx)(T.Tooltip,{title:"The team this key belongs to, which determines available models and budget limits",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"team_id",initialValue:e?e.team_id:null,className:"mt-4",rules:[{required:"service_account"===eR,message:"Please select a team for the service account"}],help:"service_account"===eR?"required":"",children:(0,t.jsx)(G.default,{disabled:null!==e4,organizationId:e1,onTeamSelect:e=>{e0(e),e3(null),eT.setFieldValue("project_id",void 0),e?.organization_id?(e2(e.organization_id),eT.setFieldValue("organization_id",e.organization_id)):e||(e2(null),eT.setFieldValue("organization_id",void 0))}})}),eN&&(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Project"," ",(0,t.jsx)(T.Tooltip,{title:"Assign this key to a project. Selecting a project will lock the team to the project's team.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"project_id",className:"mt-4",children:(0,t.jsx)(q.default,{projects:e_,teamId:eZ?.team_id,loading:ej||!eo,onChange:e=>{if(!e){e3(null),e0(null),eT.setFieldValue("team_id",void 0);return}e3(e)}})})]}),tM&&(0,t.jsx)("div",{className:"mb-8 p-4 bg-blue-50 border border-blue-200 rounded-md",children:(0,t.jsx)(y.Text,{className:"text-blue-800 text-sm",children:"Please select a team to continue configuring your Virtual Key. If you do not see any teams, please contact your Proxy Admin to either provide you with access to models or to add you to a team."})}),!tM&&(0,t.jsxs)("div",{className:"mb-8",children:[(0,t.jsx)(b.Title,{className:"mb-4",children:"Key Details"}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["you"===eR||"another_user"===eR?"Key Name":"Service Account ID"," ",(0,t.jsx)(T.Tooltip,{title:"you"===eR||"another_user"===eR?"A descriptive name to identify this key":"Unique identifier for this service account",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"key_alias",rules:[{required:!0,message:`Please input a ${"you"===eR?"key name":"service account ID"}`}],help:"required",children:(0,t.jsx)(f.TextInput,{placeholder:""})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Models"," ",(0,t.jsx)(T.Tooltip,{title:"Select which models this key can access. Choose 'All Team Models' to grant access to all models available to the team. Leave empty to allow access to all models.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"models",rules:[],help:"management"===td||"read_only"===td?"Models field is disabled for this key type":"optional - leave empty to allow access to all models",className:"mt-4",children:(0,t.jsxs)(k.Select,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},disabled:"management"===td||"read_only"===td,onChange:e=>{e.includes("all-team-models")&&eT.setFieldsValue({models:["all-team-models"]})},children:[!e4&&(0,t.jsx)(er,{value:"all-team-models",children:"All Team Models"},"all-team-models"),eB.map(e=>(0,t.jsx)(er,{value:e,children:(0,J.getModelDisplayName)(e)},e))]})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Key Type"," ",(0,t.jsx)(T.Tooltip,{title:"Select the type of key to determine what routes and operations this key can access",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"key_type",initialValue:"llm_api",className:"mt-4",children:(0,t.jsxs)(k.Select,{defaultValue:"llm_api",placeholder:"Select key type",style:{width:"100%"},optionLabelProp:"label",onChange:e=>{tc(e),("management"===e||"read_only"===e)&&eT.setFieldsValue({models:[]})},children:[(0,t.jsx)(er,{value:"llm_api",label:"AI APIs",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)(I.Typography.Text,{strong:!0,children:"AI APIs"}),(0,t.jsx)(I.Typography.Paragraph,{type:"secondary",style:{fontSize:11,margin:"2px 0 0"},children:"Can call only AI API routes (chat/completions, embeddings, etc.)"})]})}),(0,t.jsx)(er,{value:"management",label:"Management",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)(I.Typography.Text,{strong:!0,children:"Management"}),(0,t.jsx)(I.Typography.Paragraph,{type:"secondary",style:{fontSize:11,margin:"2px 0 0"},children:"Can call only management routes (user/team/key management)"})]})}),(0,t.jsx)(er,{value:"default",label:"Full Access",children:(0,t.jsxs)("div",{style:{padding:"4px 0"},children:[(0,t.jsx)(I.Typography.Text,{strong:!0,children:"Full Access"}),(0,t.jsx)(I.Typography.Paragraph,{type:"secondary",style:{fontSize:11,margin:"2px 0 0"},children:"Can call all routes (AI APIs, Management, and read-only)"})]})})]})})]}),!tM&&(0,t.jsx)("div",{className:"mb-8",children:(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)(b.Title,{className:"m-0",children:"Optional Settings"})}),(0,t.jsxs)(m.AccordionBody,{children:[(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Max Budget (USD)"," ",(0,t.jsx)(T.Tooltip,{title:"Maximum amount in USD this key can spend. When reached, the key will be blocked from making further requests",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"max_budget",help:`Budget cannot exceed team max budget: $${e?.max_budget!==null&&e?.max_budget!==void 0?e?.max_budget:"unlimited"}`,rules:[{validator:async(t,s)=>{if(s&&e&&null!==e.max_budget&&s>e.max_budget)throw Error(`Budget cannot exceed team max budget: $${(0,o.formatNumberWithCommas)(e.max_budget,4)}`)}}],children:(0,t.jsx)(el.default,{step:.01,precision:2,width:200})}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Reset Budget"," ",(0,t.jsx)(T.Tooltip,{title:"How often the budget should reset. For example, setting 'daily' will reset the budget every 24 hours",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"budget_duration",help:`Team Reset Budget: ${e?.budget_duration!==null&&e?.budget_duration!==void 0?e?.budget_duration:"None"}`,children:(0,t.jsx)(P.default,{onChange:e=>eT.setFieldValue("budget_duration",e)})}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Budget Windows"," ",(0,t.jsx)(T.Tooltip,{title:"Set multiple independent budget windows (e.g., hourly $10 AND monthly $200). Each window tracks spend separately and resets on its own schedule.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),children:(0,t.jsx)(Q.BudgetWindowsEditor,{value:tb,onChange:t_})}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Budget Fallbacks"," ",(0,t.jsx)(T.Tooltip,{title:"When a model exceeds its per-model budget (model_max_budget), requests automatically reroute to fallback models instead of failing. Configure per-model budgets in Advanced Settings.",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),children:(0,t.jsx)(H.BudgetFallbacksEditor,{value:tj,onChange:tv,availableModels:eB},tw)}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Tokens per minute Limit (TPM)"," ",(0,t.jsx)(T.Tooltip,{title:"Maximum number of tokens this key can process per minute. Helps control usage and costs",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"tpm_limit",help:`TPM cannot exceed team TPM limit: ${e?.tpm_limit!==null&&e?.tpm_limit!==void 0?e?.tpm_limit:"unlimited"}`,rules:[{validator:async(t,s)=>{if(s&&e&&null!==e.tpm_limit&&s>e.tpm_limit)throw Error(`TPM limit cannot exceed team TPM limit: ${e.tpm_limit}`)}}],children:(0,t.jsx)(el.default,{step:1,width:400})}),(0,t.jsx)(z.default,{type:"tpm",name:"tpm_limit_type",className:"mt-4",initialValue:null,form:eT,showDetailedDescriptions:!0}),(0,t.jsx)(j.Form.Item,{className:"mt-4",label:(0,t.jsxs)("span",{children:["Requests per minute Limit (RPM)"," ",(0,t.jsx)(T.Tooltip,{title:"Maximum number of API requests this key can make per minute. Helps prevent abuse and manage load",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"rpm_limit",help:`RPM cannot exceed team RPM limit: ${e?.rpm_limit!==null&&e?.rpm_limit!==void 0?e?.rpm_limit:"unlimited"}`,rules:[{validator:async(t,s)=>{if(s&&e&&null!==e.rpm_limit&&s>e.rpm_limit)throw Error(`RPM limit cannot exceed team RPM limit: ${e.rpm_limit}`)}}],children:(0,t.jsx)(el.default,{step:1,width:400})}),(0,t.jsx)(z.default,{type:"rpm",name:"rpm_limit_type",className:"mt-4",initialValue:null,form:eT,showDetailedDescriptions:!0}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Guardrails"," ",(0,t.jsx)(T.Tooltip,{title:"Apply safety guardrails to this key to filter content or enforce policies",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"guardrails",className:"mt-4",help:ey?"Select existing guardrails or enter new ones":"Premium feature - Upgrade to set guardrails by key",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},disabled:!ey,placeholder:ey?"Select or enter guardrails":"Premium feature - Upgrade to set guardrails by key",options:eK.map(e=>({value:e,label:e}))})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Disable Global Guardrails"," ",(0,t.jsx)(T.Tooltip,{title:"When enabled, this key will bypass any guardrails configured to run on every request (global guardrails)",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"disable_global_guardrails",className:"mt-4",valuePropName:"checked",help:ey?"Bypass global guardrails for this key":"Premium feature - Upgrade to disable global guardrails by key",children:(0,t.jsx)(S.Switch,{disabled:!ey,checkedChildren:"Yes",unCheckedChildren:"No"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Policies"," ",(0,t.jsx)(T.Tooltip,{title:"Apply policies to this key to control guardrails and other settings",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/guardrail_policies",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"policies",className:"mt-4",help:ex?"Select existing policies or enter new ones":"Premium feature - Upgrade to set policies by key",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},disabled:!ex,placeholder:ex?"Select or enter policies":"Premium feature - Upgrade to set policies by key",options:eW.map(e=>({value:e,label:e}))})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Prompts"," ",(0,t.jsx)(T.Tooltip,{title:"Allow this key to use specific prompt templates",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/prompt_management",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"prompts",className:"mt-4",help:ex?"Select existing prompts or enter new ones":"Premium feature - Upgrade to set prompts by key",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},disabled:!ex,placeholder:ex?"Select or enter prompts":"Premium feature - Upgrade to set prompts by key",options:eQ.map(e=>({value:e,label:e}))})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Access Groups"," ",(0,t.jsx)(T.Tooltip,{title:"Assign access groups to this key. Access groups control which models, MCP servers, and agents this key can use",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"access_group_ids",className:"mt-4",help:"Select access groups to assign to this key",children:(0,t.jsx)(E.default,{placeholder:"Select access groups (optional)"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Pass Through Routes"," ",(0,t.jsx)(T.Tooltip,{title:"Allow this key to use specific pass through routes",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/pass_through",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"allowed_passthrough_routes",className:"mt-4",help:ex?"Select existing pass through routes or enter new ones":"Premium feature - Upgrade to set pass through routes by key",children:(0,t.jsx)(D.default,{onChange:e=>eT.setFieldValue("allowed_passthrough_routes",e),value:eT.getFieldValue("allowed_passthrough_routes"),accessToken:ep,placeholder:ex?"Select or enter pass through routes":"Premium feature - Upgrade to set pass through routes by key",disabled:!ex,teamId:eZ?eZ.team_id:null})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Vector Stores"," ",(0,t.jsx)(T.Tooltip,{title:"Select which vector stores this key can access. If none selected, the key will have access to all available vector stores",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"allowed_vector_store_ids",className:"mt-4",help:"Select vector stores this key can access. Leave empty for access to all vector stores",children:(0,t.jsx)(ea.default,{onChange:e=>eT.setFieldValue("allowed_vector_store_ids",e),value:eT.getFieldValue("allowed_vector_store_ids"),accessToken:ep,placeholder:"Select vector stores (optional)"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Metadata"," ",(0,t.jsx)(T.Tooltip,{title:"JSON object with additional information about this key. Used for tracking or custom logic",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"metadata",className:"mt-4",children:(0,t.jsx)(v.Input.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Tags"," ",(0,t.jsx)(T.Tooltip,{title:"Tags for tracking spend and/or doing tag-based routing. Used for analytics and filtering",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"tags",className:"mt-4",help:"Tags for tracking spend and/or doing tag-based routing.",children:(0,t.jsx)(k.Select,{mode:"tags",style:{width:"100%"},placeholder:"Select or enter tags",tokenSeparators:[","],options:eS})}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"MCP Settings"})}),(0,t.jsxs)(m.AccordionBody,{children:[(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed MCP Servers"," ",(0,t.jsx)(T.Tooltip,{title:"Select which MCP servers or access groups this key can access",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"allowed_mcp_servers_and_groups",help:"Select MCP servers or access groups this key can access",children:(0,t.jsx)(Y.default,{onChange:e=>eT.setFieldValue("allowed_mcp_servers_and_groups",e),value:eT.getFieldValue("allowed_mcp_servers_and_groups"),accessToken:ep,teamId:eZ?.team_id??null,placeholder:"Select MCP servers or access groups (optional)",allowNoMcpServers:!0})}),(0,t.jsx)(j.Form.Item,{name:"mcp_tool_permissions",initialValue:{},hidden:!0,children:(0,t.jsx)(v.Input,{type:"hidden"})}),(0,t.jsx)(j.Form.Item,{noStyle:!0,shouldUpdate:(e,t)=>e.allowed_mcp_servers_and_groups!==t.allowed_mcp_servers_and_groups||e.mcp_tool_permissions!==t.mcp_tool_permissions,children:()=>(0,t.jsx)("div",{className:"mt-6",children:(0,t.jsx)(Z.default,{accessToken:ep,selectedServers:(eT.getFieldValue("allowed_mcp_servers_and_groups")?.servers||[]).filter(e=>e!==X.NO_MCP_SERVERS_SENTINEL),toolPermissions:eT.getFieldValue("mcp_tool_permissions")||{},onChange:e=>eT.setFieldsValue({mcp_tool_permissions:e})})})})]})]}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Agent Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Allowed Agents"," ",(0,t.jsx)(T.Tooltip,{title:"Select which agents or access groups this key can access",children:(0,t.jsx)(d.InfoCircleOutlined,{style:{marginLeft:"4px"}})})]}),name:"allowed_agents_and_groups",help:"Select agents or access groups this key can access",children:(0,t.jsx)(M.default,{onChange:e=>eT.setFieldValue("allowed_agents_and_groups",e),value:eT.getFieldValue("allowed_agents_and_groups"),accessToken:ep,placeholder:"Select agents or access groups (optional)"})})})]}),ex?(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Logging Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(V.default,{value:eY,onChange:eX,premiumUser:!0,disabledCallbacks:tn,onDisabledCallbacksChange:to})})})]}):(0,t.jsx)(T.Tooltip,{title:(0,t.jsxs)("span",{children:["Key-level logging settings is an enterprise feature, get in touch -",(0,t.jsx)("a",{href:"https://www.litellm.ai/enterprise",target:"_blank",children:"https://www.litellm.ai/enterprise"})]}),placement:"top",children:(0,t.jsxs)("div",{style:{position:"relative"},children:[(0,t.jsx)("div",{style:{opacity:.5},children:(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Logging Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(V.default,{value:eY,onChange:eX,premiumUser:!1,disabledCallbacks:tn,onDisabledCallbacksChange:to})})})]})}),(0,t.jsx)("div",{style:{position:"absolute",inset:0,cursor:"not-allowed"}})]})}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Router Settings"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4 w-full",children:(0,t.jsx)(U.default,{accessToken:ep||"",value:ty||void 0,onChange:tf,modelData:eE.length>0?{data:eE.map(e=>({model_name:e}))}:void 0},tk)})})]},`router-settings-accordion-${tk}`),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Model Aliases"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsxs)("div",{className:"mt-4",children:[(0,t.jsx)(y.Text,{className:"text-sm text-gray-600 mb-4",children:"Create custom aliases for models that can be used in API calls. This allows you to create shortcuts for specific models."}),(0,t.jsx)(R.default,{accessToken:ep,initialModelAliases:tu,onAliasUpdate:tm,showExampleConfig:!1})]})})]}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsx)("b",{children:"Key Lifecycle"})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)($.default,{form:eT,autoRotationEnabled:tp,onAutoRotationChange:tg,rotationInterval:th,onRotationIntervalChange:tx,isCreateMode:!0})})}),(0,t.jsx)(j.Form.Item,{name:"duration",hidden:!0,initialValue:null,children:(0,t.jsx)(v.Input,{})})]}),(0,t.jsxs)(u.Accordion,{className:"mt-4 mb-4",children:[(0,t.jsx)(p.AccordionHeader,{children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("b",{children:"Advanced Settings"}),(0,t.jsx)(T.Tooltip,{title:(0,t.jsxs)("span",{children:["Learn more about advanced settings in our"," ",(0,t.jsx)("a",{href:et.proxyBaseUrl?`${et.proxyBaseUrl}/#/key%20management/generate_key_fn_key_generate_post`:"/#/key%20management/generate_key_fn_key_generate_post",target:"_blank",rel:"noopener noreferrer",className:"text-blue-400 hover:text-blue-300",children:"documentation"})]}),children:(0,t.jsx)(d.InfoCircleOutlined,{className:"text-gray-400 hover:text-gray-300 cursor-help"})})]})}),(0,t.jsx)(m.AccordionBody,{children:(0,t.jsx)(B.default,{schemaComponent:"GenerateKeyRequest",form:eT,excludedFields:["key_alias","team_id","organization_id","models","duration","metadata","tags","guardrails","max_budget","budget_duration","tpm_limit","rpm_limit",...ek?["key"]:[]]})})]})]})]})}),(0,t.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,t.jsx)(_.Button,{htmlType:"submit",disabled:tM,style:{opacity:tM?.5:1},children:"Create Key"})})]})}),e5&&(0,t.jsx)(w.Modal,{title:"Create New User",open:e5,onCancel:()=>e6(!1),footer:null,width:800,children:(0,t.jsx)(W.CreateUserButton,{userID:eg,accessToken:ep,teams:eo,possibleUIRoles:e8,onUserCreated:e=>{e9(e),eT.setFieldsValue({user_id:e}),e6(!1)},isEmbedded:!0})}),eL&&(0,t.jsx)(w.Modal,{open:eI,onOk:tL,onCancel:tF,footer:null,children:(0,t.jsxs)(x.Grid,{numItems:1,className:"gap-2 w-full",children:[(0,t.jsx)(b.Title,{children:"Save your Key"}),(0,t.jsx)(h.Col,{numColSpan:1,children:null!=eL?(0,t.jsx)(es.default,{apiKey:eL}):(0,t.jsx)(y.Text,{children:"Key being created, this might take 30s"})})]})})]})},"fetchTeamModels",0,ei,"fetchUserModels",0,en],702597)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/02jakvkccxpfw.js b/litellm/proxy/_experimental/out/_next/static/chunks/02jakvkccxpfw.js new file mode 100644 index 00000000000..81de72e6c80 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/02jakvkccxpfw.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,916925,e=>{"use strict";var t,a=e.i(555987),l=((t={}).A2A_Agent="A2A Agent",t.AI21="Ai21",t.AI21_CHAT="Ai21 Chat",t.AIML="AI/ML API",t.AIOHTTP_OPENAI="Aiohttp Openai",t.Anthropic="Anthropic",t.ANTHROPIC_TEXT="Anthropic Text",t.AssemblyAI="AssemblyAI",t.AUTO_ROUTER="Auto Router",t.Bedrock="Amazon Bedrock",t.BedrockMantle="Amazon Bedrock Mantle",t.SageMaker="AWS SageMaker",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Foundry (Studio)",t.AZURE_TEXT="Azure Text",t.BASETEN="Baseten",t.BYTEZ="Bytez",t.Cerebras="Cerebras",t.CLARIFAI="Clarifai",t.CLOUDFLARE="Cloudflare",t.CODESTRAL="Codestral",t.Cohere="Cohere",t.COHERE_CHAT="Cohere Chat",t.COMETAPI="Cometapi",t.COMPACTIFAI="Compactifai",t.Cursor="Cursor",t.Dashscope="Dashscope",t.Databricks="Databricks (Qwen API)",t.DATAROBOT="Datarobot",t.DeepInfra="DeepInfra",t.Deepgram="Deepgram",t.Deepseek="Deepseek",t.DOCKER_MODEL_RUNNER="Docker Model Runner",t.DOTPROMPT="Dotprompt",t.ElevenLabs="ElevenLabs",t.EMPOWER="Empower",t.FalAI="Fal AI",t.FEATHERLESS_AI="Featherless Ai",t.FireworksAI="Fireworks AI",t.FRIENDLIAI="Friendliai",t.GALADRIEL="Galadriel",t.GITHUB_COPILOT="Github Copilot",t.Google_AI_Studio="Google AI Studio",t.GradientAI="GradientAI",t.Groq="Groq",t.HEROKU="Heroku",t.Hosted_Vllm="vllm",t.HUGGINGFACE="Huggingface",t.HYPERBOLIC="Hyperbolic",t.Infinity="Infinity",t.JinaAI="Jina AI",t.LAMBDA_AI="Lambda Ai",t.LEMONADE="Lemonade",t.LLAMAFILE="Llamafile",t.LM_STUDIO="Lm Studio",t.LLAMA="Meta Llama",t.MARITALK="Maritalk",t.MiniMax="MiniMax",t.MistralAI="Mistral AI",t.MOONSHOT="Moonshot",t.MORPH="Morph",t.NEBIUS="Nebius",t.NLP_CLOUD="Nlp Cloud",t.NOVITA="Novita",t.NSCALE="Nscale",t.NVIDIA_NIM="Nvidia Nim",t.Ollama="Ollama",t.OLLAMA_CHAT="Ollama Chat",t.OOBABOOGA="Oobabooga",t.OpenAI="OpenAI",t.OPENAI_LIKE="Openai Like",t.OpenAI_Compatible="OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)",t.OpenAI_Text="OpenAI Text Completion",t.OpenAI_Text_Compatible="OpenAI-Compatible Completions (legacy /v1/completions)",t.Openrouter="Openrouter",t.Oracle="Oracle Cloud Infrastructure (OCI)",t.OVHCLOUD="Ovhcloud",t.Perplexity="Perplexity",t.PETALS="Petals",t.PG_VECTOR="Pg Vector",t.PREDIBASE="Predibase",t.RECRAFT="Recraft",t.REPLICATE="Replicate",t.RunwayML="RunwayML",t.SAGEMAKER_LEGACY="Sagemaker",t.Sambanova="Sambanova",t.SAP="SAP Generative AI Hub",t.Snowflake="Snowflake",t.Soniox="Soniox",t.TEXT_COMPLETION_CODESTRAL="Text-Completion-Codestral",t.TogetherAI="TogetherAI",t.TOPAZ="Topaz",t.Triton="Triton",t.V0="V0",t.VERCEL_AI_GATEWAY="Vercel Ai Gateway",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.VERTEX_AI_BETA="Vertex Ai Beta",t.VLLM="Vllm",t.VolcEngine="VolcEngine",t.Voyage="Voyage AI",t.WANDB="Wandb",t.WATSONX="Watsonx",t.WATSONX_TEXT="Watsonx Text",t.xAI="xAI",t.XINFERENCE="Xinference",t.ZAI="Z.AI (Zhipu AI)",t);let n={A2A_Agent:"a2a_agent",AI21:"ai21",AI21_CHAT:"ai21_chat",AIML:"aiml",AIOHTTP_OPENAI:"aiohttp_openai",Anthropic:"anthropic",ANTHROPIC_TEXT:"anthropic_text",AssemblyAI:"assemblyai",AUTO_ROUTER:"auto_router",Azure:"azure",Azure_AI_Studio:"azure_ai",AZURE_TEXT:"azure_text",BASETEN:"baseten",Bedrock:"bedrock",BedrockMantle:"bedrock_mantle",BYTEZ:"bytez",Cerebras:"cerebras",CLARIFAI:"clarifai",CLOUDFLARE:"cloudflare",CODESTRAL:"codestral",Cohere:"cohere",COHERE_CHAT:"cohere_chat",COMETAPI:"cometapi",COMPACTIFAI:"compactifai",Cursor:"cursor",Dashscope:"dashscope",Databricks:"databricks",DATAROBOT:"datarobot",DeepInfra:"deepinfra",Deepgram:"deepgram",Deepseek:"deepseek",DOCKER_MODEL_RUNNER:"docker_model_runner",DOTPROMPT:"dotprompt",ElevenLabs:"elevenlabs",EMPOWER:"empower",FalAI:"fal_ai",FEATHERLESS_AI:"featherless_ai",FireworksAI:"fireworks_ai",FRIENDLIAI:"friendliai",GALADRIEL:"galadriel",GITHUB_COPILOT:"github_copilot",Google_AI_Studio:"gemini",GradientAI:"gradient_ai",Groq:"groq",HEROKU:"heroku",Hosted_Vllm:"hosted_vllm",HUGGINGFACE:"huggingface",HYPERBOLIC:"hyperbolic",Infinity:"infinity",JinaAI:"jina_ai",LAMBDA_AI:"lambda_ai",LEMONADE:"lemonade",LLAMAFILE:"llamafile",LLAMA:"meta_llama",LM_STUDIO:"lm_studio",MARITALK:"maritalk",MiniMax:"minimax",MistralAI:"mistral",MOONSHOT:"moonshot",MORPH:"morph",NEBIUS:"nebius",NLP_CLOUD:"nlp_cloud",NOVITA:"novita",NSCALE:"nscale",NVIDIA_NIM:"nvidia_nim",Ollama:"ollama",OLLAMA_CHAT:"ollama_chat",OOBABOOGA:"oobabooga",OpenAI:"openai",OPENAI_LIKE:"openai_like",OpenAI_Compatible:"openai",OpenAI_Text:"text-completion-openai",OpenAI_Text_Compatible:"text-completion-openai",Openrouter:"openrouter",Oracle:"oci",OVHCLOUD:"ovhcloud",Perplexity:"perplexity",PETALS:"petals",PG_VECTOR:"pg_vector",PREDIBASE:"predibase",RECRAFT:"recraft",REPLICATE:"replicate",RunwayML:"runwayml",SAGEMAKER_LEGACY:"sagemaker",SageMaker:"sagemaker_chat",Sambanova:"sambanova",SAP:"sap",Snowflake:"snowflake",Soniox:"soniox",TEXT_COMPLETION_CODESTRAL:"text-completion-codestral",TogetherAI:"together_ai",TOPAZ:"topaz",Triton:"triton",V0:"v0",VERCEL_AI_GATEWAY:"vercel_ai_gateway",Vertex_AI:"vertex_ai",VERTEX_AI_BETA:"vertex_ai_beta",VLLM:"vllm",VolcEngine:"volcengine",Voyage:"voyage",WANDB:"wandb",WATSONX:"watsonx",WATSONX_TEXT:"watsonx_text",xAI:"xai",XINFERENCE:"xinference",ZAI:"zai"},r=new Set(["bedrock_mantle"]),o="/ui/assets/logos/",i={"A2A Agent":`${o}a2a_agent.png`,Ai21:`${o}ai21.svg`,"Ai21 Chat":`${o}ai21.svg`,"AI/ML API":`${o}aiml_api.svg`,"Aiohttp Openai":`${o}openai_small.svg`,Anthropic:`${o}anthropic.svg`,"Anthropic Text":`${o}anthropic.svg`,AssemblyAI:`${o}assemblyai_small.png`,Azure:`${o}microsoft_azure.svg`,"Azure AI Foundry (Studio)":`${o}microsoft_azure.svg`,"Azure Text":`${o}microsoft_azure.svg`,Baseten:`${o}baseten.svg`,"Amazon Bedrock":`${o}bedrock.svg`,"Amazon Bedrock Mantle":`${o}bedrock.svg`,"AWS SageMaker":`${o}bedrock.svg`,Cerebras:`${o}cerebras.svg`,Cloudflare:`${o}cloudflare.svg`,Codestral:`${o}mistral.svg`,Cohere:`${o}cohere.svg`,"Cohere Chat":`${o}cohere.svg`,Cometapi:`${o}cometapi.svg`,Cursor:`${o}cursor.svg`,"Databricks (Qwen API)":`${o}databricks.svg`,Dashscope:`${o}dashscope.svg`,Deepseek:`${o}deepseek.svg`,Deepgram:`${o}deepgram.png`,DeepInfra:`${o}deepinfra.png`,ElevenLabs:`${o}elevenlabs.png`,"Fal AI":`${o}fal_ai.jpg`,"Featherless Ai":`${o}featherless.svg`,"Fireworks AI":`${o}fireworks.svg`,Friendliai:`${o}friendli.svg`,"Github Copilot":`${o}github_copilot.svg`,"Google AI Studio":`${o}google.svg`,GradientAI:`${o}gradientai.svg`,Groq:`${o}groq.svg`,vllm:`${o}vllm.png`,Huggingface:`${o}huggingface.svg`,Hyperbolic:`${o}hyperbolic.svg`,Infinity:`${o}infinity.png`,"Jina AI":`${o}jina.png`,"Lambda Ai":`${o}lambda.svg`,"Lm Studio":`${o}lmstudio.svg`,"Meta Llama":`${o}meta_llama.svg`,MiniMax:`${o}minimax.svg`,"Mistral AI":`${o}mistral.svg`,Moonshot:`${o}moonshot.svg`,Morph:`${o}morph.svg`,Nebius:`${o}nebius.svg`,Novita:`${o}novita.svg`,"Nvidia Nim":`${o}nvidia_nim.svg`,Ollama:`${o}ollama.svg`,"Ollama Chat":`${o}ollama.svg`,Oobabooga:`${o}openai_small.svg`,OpenAI:`${o}openai_small.svg`,"Openai Like":`${o}openai_small.svg`,"OpenAI Text Completion":`${o}openai_small.svg`,"OpenAI-Compatible Completions (legacy /v1/completions)":`${o}openai_small.svg`,"OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)":`${o}openai_small.svg`,Openrouter:`${o}openrouter.svg`,"Oracle Cloud Infrastructure (OCI)":`${o}oracle.svg`,Perplexity:`${o}perplexity-ai.svg`,Recraft:`${o}recraft.svg`,Replicate:`${o}replicate.svg`,RunwayML:`${o}runwayml.png`,Sagemaker:`${o}bedrock.svg`,Sambanova:`${o}sambanova.svg`,"SAP Generative AI Hub":`${o}sap.png`,Snowflake:`${o}snowflake.svg`,Soniox:`${o}soniox.svg`,"Text-Completion-Codestral":`${o}mistral.svg`,TogetherAI:`${o}togetherai.svg`,Topaz:`${o}topaz.svg`,Triton:`${o}nvidia_triton.png`,V0:`${o}v0.svg`,"Vercel Ai Gateway":`${o}vercel.svg`,"Vertex AI (Anthropic, Gemini, etc.)":`${o}google.svg`,"Vertex Ai Beta":`${o}google.svg`,Vllm:`${o}vllm.png`,VolcEngine:`${o}volcengine.png`,"Voyage AI":`${o}voyage.webp`,Watsonx:`${o}watsonx.svg`,"Watsonx Text":`${o}watsonx.svg`,xAI:`${o}xai.svg`,Xinference:`${o}xinference.svg`};e.s(["Providers",()=>l,"getPlaceholder",0,e=>{if("AI/ML API"===e)return"aiml/flux-pro/v1.1";if("Vertex AI (Anthropic, Gemini, etc.)"===e)return"gemini-pro";if("Anthropic"==e)return"claude-3-opus";if("Amazon Bedrock"==e)return"claude-3-opus";if("AWS SageMaker"==e)return"sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b";else if("Google AI Studio"==e)return"gemini-pro";else if("Azure AI Foundry (Studio)"==e)return"azure_ai/command-r-plus";else if("Azure"==e)return"my-deployment";else if("Oracle Cloud Infrastructure (OCI)"==e)return"oci/xai.grok-4";else if("Snowflake"==e)return"snowflake/mistral-7b";else if("Voyage AI"==e)return"voyage/";else if("Jina AI"==e)return"jina_ai/";else if("VolcEngine"==e)return"volcengine/";else if("DeepInfra"==e)return"deepinfra/";else if("Fal AI"==e)return"fal_ai/fal-ai/flux-pro/v1.1-ultra";else if("RunwayML"==e)return"runwayml/gen4_turbo";else if("Watsonx"===e)return"watsonx/ibm/granite-3-3-8b-instruct";else if("Cursor"===e)return"cursor/claude-4-sonnet";else if("Z.AI (Zhipu AI)"===e)return"zai/glm-4.5";else return"gpt-3.5-turbo"},"getProviderLogoAndName",0,e=>{if(!e)return{logo:"",displayName:"-"};if("gemini"===e.toLowerCase()){let e="Google AI Studio";return{logo:(0,a.resolveLogoSrc)(i[e])??"",displayName:e}}let t=Object.keys(n).find(t=>n[t].toLowerCase()===e.toLowerCase())??Object.keys(n).find(t=>t.toLowerCase()===e.toLowerCase());if(!t)return{logo:"",displayName:e};let r=l[t];return{logo:(0,a.resolveLogoSrc)(i[r])??"",displayName:r}},"getProviderModels",0,(e,t)=>{let a=n[e],l=[];return e&&"object"==typeof t&&(Object.entries(t).forEach(([e,t])=>{if(null!==t&&"object"==typeof t&&"litellm_provider"in t){let n=t.litellm_provider,o="string"==typeof n&&(n.startsWith(`${a}_`)||n.startsWith(`${a}-`));(n===a||o&&!r.has(n))&&l.push(e)}}),"Cohere"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"cohere_chat"===t.litellm_provider&&l.push(e)}),"AWS SageMaker"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"sagemaker_chat"===t.litellm_provider&&l.push(e)})),l},"providerLogoMap",0,i,"provider_map",0,n])},91979,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let l={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M909.1 209.3l-56.4 44.1C775.8 155.1 656.2 92 521.9 92 290 92 102.3 279.5 102 511.5 101.7 743.7 289.8 932 521.9 932c181.3 0 335.8-115 394.6-276.1 1.5-4.2-.7-8.9-4.9-10.3l-56.7-19.5a8 8 0 00-10.1 4.8c-1.8 5-3.8 10-5.9 14.9-17.3 41-42.1 77.8-73.7 109.4A344.77 344.77 0 01655.9 829c-42.3 17.9-87.4 27-133.8 27-46.5 0-91.5-9.1-133.8-27A341.5 341.5 0 01279 755.2a342.16 342.16 0 01-73.7-109.4c-17.9-42.4-27-87.4-27-133.9s9.1-91.5 27-133.9c17.3-41 42.1-77.8 73.7-109.4 31.6-31.6 68.4-56.4 109.3-73.8 42.3-17.9 87.4-27 133.8-27 46.5 0 91.5 9.1 133.8 27a341.5 341.5 0 01109.3 73.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 003 14.1l175.6 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c-.1-6.6-7.8-10.3-13-6.2z"}}]},name:"reload",theme:"outlined"};var n=e.i(9583),r=a.forwardRef(function(e,r){return a.createElement(n.default,(0,t.default)({},e,{ref:r,icon:l}))});e.s(["ReloadOutlined",0,r],91979)},608856,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),l=e.i(209428),n=e.i(392221),r=e.i(951160),o=e.i(174428),i=t.createContext(null),s=t.createContext({}),c=e.i(211577),u=e.i(931067),d=e.i(361275),m=e.i(404948),p=e.i(244009),f=e.i(703923),g=e.i(611935),h=["prefixCls","className","containerRef"];let v=function(e){var l=e.prefixCls,n=e.className,r=e.containerRef,o=(0,f.default)(e,h),i=t.useContext(s).panel,c=(0,g.useComposeRef)(i,r);return t.createElement("div",(0,u.default)({className:(0,a.default)("".concat(l,"-content"),n),role:"dialog",ref:c},(0,p.default)(e,{aria:!0}),{"aria-modal":"true"},o))};var A=e.i(883110);function b(e){return"string"==typeof e&&String(Number(e))===e?((0,A.default)(!1,"Invalid value type of `width` or `height` which should be number type instead."),Number(e)):e}var y={width:0,height:0,overflow:"hidden",outline:"none",position:"absolute"},x=t.forwardRef(function(e,r){var o,s,f,g=e.prefixCls,h=e.open,A=e.placement,x=e.inline,C=e.push,I=e.forceRender,w=e.autoFocus,O=e.keyboard,E=e.classNames,S=e.rootClassName,k=e.rootStyle,_=e.zIndex,L=e.className,$=e.id,T=e.style,M=e.motion,N=e.width,R=e.height,j=e.children,D=e.mask,P=e.maskClosable,z=e.maskMotion,H=e.maskClassName,B=e.maskStyle,F=e.afterOpenChange,V=e.onClose,G=e.onMouseEnter,K=e.onMouseOver,U=e.onMouseLeave,W=e.onClick,X=e.onKeyDown,q=e.onKeyUp,Q=e.styles,Y=e.drawerRender,Z=t.useRef(),J=t.useRef(),ee=t.useRef();t.useImperativeHandle(r,function(){return Z.current}),t.useEffect(function(){if(h&&w){var e;null==(e=Z.current)||e.focus({preventScroll:!0})}},[h]);var et=t.useState(!1),ea=(0,n.default)(et,2),el=ea[0],en=ea[1],er=t.useContext(i),eo=null!=(o=null!=(s=null==(f="boolean"==typeof C?C?{}:{distance:0}:C||{})?void 0:f.distance)?s:null==er?void 0:er.pushDistance)?o:180,ei=t.useMemo(function(){return{pushDistance:eo,push:function(){en(!0)},pull:function(){en(!1)}}},[eo]);t.useEffect(function(){var e,t;h?null==er||null==(e=er.push)||e.call(er):null==er||null==(t=er.pull)||t.call(er)},[h]),t.useEffect(function(){return function(){var e;null==er||null==(e=er.pull)||e.call(er)}},[]);var es=t.createElement(d.default,(0,u.default)({key:"mask"},z,{visible:D&&h}),function(e,n){var r=e.className,o=e.style;return t.createElement("div",{className:(0,a.default)("".concat(g,"-mask"),r,null==E?void 0:E.mask,H),style:(0,l.default)((0,l.default)((0,l.default)({},o),B),null==Q?void 0:Q.mask),onClick:P&&h?V:void 0,ref:n})}),ec="function"==typeof M?M(A):M,eu={};if(el&&eo)switch(A){case"top":eu.transform="translateY(".concat(eo,"px)");break;case"bottom":eu.transform="translateY(".concat(-eo,"px)");break;case"left":eu.transform="translateX(".concat(eo,"px)");break;default:eu.transform="translateX(".concat(-eo,"px)")}"left"===A||"right"===A?eu.width=b(N):eu.height=b(R);var ed={onMouseEnter:G,onMouseOver:K,onMouseLeave:U,onClick:W,onKeyDown:X,onKeyUp:q},em=t.createElement(d.default,(0,u.default)({key:"panel"},ec,{visible:h,forceRender:I,onVisibleChanged:function(e){null==F||F(e)},removeOnLeave:!1,leavedClassName:"".concat(g,"-content-wrapper-hidden")}),function(n,r){var o=n.className,i=n.style,s=t.createElement(v,(0,u.default)({id:$,containerRef:r,prefixCls:g,className:(0,a.default)(L,null==E?void 0:E.content),style:(0,l.default)((0,l.default)({},T),null==Q?void 0:Q.content)},(0,p.default)(e,{aria:!0}),ed),j);return t.createElement("div",(0,u.default)({className:(0,a.default)("".concat(g,"-content-wrapper"),null==E?void 0:E.wrapper,o),style:(0,l.default)((0,l.default)((0,l.default)({},eu),i),null==Q?void 0:Q.wrapper)},(0,p.default)(e,{data:!0})),Y?Y(s):s)}),ep=(0,l.default)({},k);return _&&(ep.zIndex=_),t.createElement(i.Provider,{value:ei},t.createElement("div",{className:(0,a.default)(g,"".concat(g,"-").concat(A),S,(0,c.default)((0,c.default)({},"".concat(g,"-open"),h),"".concat(g,"-inline"),x)),style:ep,tabIndex:-1,ref:Z,onKeyDown:function(e){var t,a,l=e.keyCode,n=e.shiftKey;switch(l){case m.default.TAB:l===m.default.TAB&&(n||document.activeElement!==ee.current?n&&document.activeElement===J.current&&(null==(a=ee.current)||a.focus({preventScroll:!0})):null==(t=J.current)||t.focus({preventScroll:!0}));break;case m.default.ESC:V&&O&&(e.stopPropagation(),V(e))}}},es,t.createElement("div",{tabIndex:0,ref:J,style:y,"aria-hidden":"true","data-sentinel":"start"}),em,t.createElement("div",{tabIndex:0,ref:ee,style:y,"aria-hidden":"true","data-sentinel":"end"})))});let C=function(e){var a=e.open,i=e.prefixCls,c=e.placement,u=e.autoFocus,d=e.keyboard,m=e.width,p=e.mask,f=void 0===p||p,g=e.maskClosable,h=e.getContainer,v=e.forceRender,A=e.afterOpenChange,b=e.destroyOnClose,y=e.onMouseEnter,C=e.onMouseOver,I=e.onMouseLeave,w=e.onClick,O=e.onKeyDown,E=e.onKeyUp,S=e.panelRef,k=t.useState(!1),_=(0,n.default)(k,2),L=_[0],$=_[1],T=t.useState(!1),M=(0,n.default)(T,2),N=M[0],R=M[1];(0,o.default)(function(){R(!0)},[]);var j=!!N&&void 0!==a&&a,D=t.useRef(),P=t.useRef();(0,o.default)(function(){j&&(P.current=document.activeElement)},[j]);var z=t.useMemo(function(){return{panel:S}},[S]);if(!v&&!L&&!j&&b)return null;var H=(0,l.default)((0,l.default)({},e),{},{open:j,prefixCls:void 0===i?"rc-drawer":i,placement:void 0===c?"right":c,autoFocus:void 0===u||u,keyboard:void 0===d||d,width:void 0===m?378:m,mask:f,maskClosable:void 0===g||g,inline:!1===h,afterOpenChange:function(e){var t,a;$(e),null==A||A(e),e||!P.current||null!=(t=D.current)&&t.contains(P.current)||null==(a=P.current)||a.focus({preventScroll:!0})},ref:D},{onMouseEnter:y,onMouseOver:C,onMouseLeave:I,onClick:w,onKeyDown:O,onKeyUp:E});return t.createElement(s.Provider,{value:z},t.createElement(r.default,{open:j||v||L,autoDestroy:!1,getContainer:h,autoLock:f&&(j||L)},t.createElement(x,H)))};var I=e.i(981444),w=e.i(617206),O=e.i(122767),E=e.i(613541),S=e.i(340010),k=e.i(242064),_=e.i(922611),L=e.i(563113),$=e.i(185793);let T=e=>{var l,n,r,o;let i,{prefixCls:s,ariaId:c,title:u,footer:d,extra:m,closable:p,loading:f,onClose:g,headerStyle:h,bodyStyle:v,footerStyle:A,children:b,classNames:y,styles:x}=e,C=(0,k.useComponentConfig)("drawer");i=!1===p?void 0:void 0===p||!0===p?"start":(null==p?void 0:p.placement)==="end"?"end":"start";let I=t.useCallback(e=>t.createElement("button",{type:"button",onClick:g,className:(0,a.default)(`${s}-close`,{[`${s}-close-${i}`]:"end"===i})},e),[g,s,i]),[w,O]=(0,L.useClosable)((0,L.pickClosable)(e),(0,L.pickClosable)(C),{closable:!0,closeIconRender:I});return t.createElement(t.Fragment,null,u||w?t.createElement("div",{style:Object.assign(Object.assign(Object.assign({},null==(r=C.styles)?void 0:r.header),h),null==x?void 0:x.header),className:(0,a.default)(`${s}-header`,{[`${s}-header-close-only`]:w&&!u&&!m},null==(o=C.classNames)?void 0:o.header,null==y?void 0:y.header)},t.createElement("div",{className:`${s}-header-title`},"start"===i&&O,u&&t.createElement("div",{className:`${s}-title`,id:c},u)),m&&t.createElement("div",{className:`${s}-extra`},m),"end"===i&&O):null,t.createElement("div",{className:(0,a.default)(`${s}-body`,null==y?void 0:y.body,null==(l=C.classNames)?void 0:l.body),style:Object.assign(Object.assign(Object.assign({},null==(n=C.styles)?void 0:n.body),v),null==x?void 0:x.body)},f?t.createElement($.default,{active:!0,title:!1,paragraph:{rows:5},className:`${s}-body-skeleton`}):b),(()=>{var e,l;if(!d)return null;let n=`${s}-footer`;return t.createElement("div",{className:(0,a.default)(n,null==(e=C.classNames)?void 0:e.footer,null==y?void 0:y.footer),style:Object.assign(Object.assign(Object.assign({},null==(l=C.styles)?void 0:l.footer),A),null==x?void 0:x.footer)},d)})())};e.i(296059);var M=e.i(915654),N=e.i(183293),R=e.i(246422),j=e.i(838378);let D=(e,t)=>({"&-enter, &-appear":Object.assign(Object.assign({},e),{"&-active":t}),"&-leave":Object.assign(Object.assign({},t),{"&-active":e})}),P=(e,t)=>Object.assign({"&-enter, &-appear, &-leave":{"&-start":{transition:"none"},"&-active":{transition:`all ${t}`}}},D({opacity:e},{opacity:1})),z=(0,R.genStyleHooks)("Drawer",e=>{let t=(0,j.mergeToken)(e,{});return[(e=>{let{borderRadiusSM:t,componentCls:a,zIndexPopup:l,colorBgMask:n,colorBgElevated:r,motionDurationSlow:o,motionDurationMid:i,paddingXS:s,padding:c,paddingLG:u,fontSizeLG:d,lineHeightLG:m,lineWidth:p,lineType:f,colorSplit:g,marginXS:h,colorIcon:v,colorIconHover:A,colorBgTextHover:b,colorBgTextActive:y,colorText:x,fontWeightStrong:C,footerPaddingBlock:I,footerPaddingInline:w,calc:O}=e,E=`${a}-content-wrapper`;return{[a]:{position:"fixed",inset:0,zIndex:l,pointerEvents:"none",color:x,"&-pure":{position:"relative",background:r,display:"flex",flexDirection:"column",[`&${a}-left`]:{boxShadow:e.boxShadowDrawerLeft},[`&${a}-right`]:{boxShadow:e.boxShadowDrawerRight},[`&${a}-top`]:{boxShadow:e.boxShadowDrawerUp},[`&${a}-bottom`]:{boxShadow:e.boxShadowDrawerDown}},"&-inline":{position:"absolute"},[`${a}-mask`]:{position:"absolute",inset:0,zIndex:l,background:n,pointerEvents:"auto"},[E]:{position:"absolute",zIndex:l,maxWidth:"100vw",transition:`all ${o}`,"&-hidden":{display:"none"}},[`&-left > ${E}`]:{top:0,bottom:0,left:{_skip_check_:!0,value:0},boxShadow:e.boxShadowDrawerLeft},[`&-right > ${E}`]:{top:0,right:{_skip_check_:!0,value:0},bottom:0,boxShadow:e.boxShadowDrawerRight},[`&-top > ${E}`]:{top:0,insetInline:0,boxShadow:e.boxShadowDrawerUp},[`&-bottom > ${E}`]:{bottom:0,insetInline:0,boxShadow:e.boxShadowDrawerDown},[`${a}-content`]:{display:"flex",flexDirection:"column",width:"100%",height:"100%",overflow:"auto",background:r,pointerEvents:"auto"},[`${a}-header`]:{display:"flex",flex:0,alignItems:"center",padding:`${(0,M.unit)(c)} ${(0,M.unit)(u)}`,fontSize:d,lineHeight:m,borderBottom:`${(0,M.unit)(p)} ${f} ${g}`,"&-title":{display:"flex",flex:1,alignItems:"center",minWidth:0,minHeight:0}},[`${a}-extra`]:{flex:"none"},[`${a}-close`]:Object.assign({display:"inline-flex",width:O(d).add(s).equal(),height:O(d).add(s).equal(),borderRadius:t,justifyContent:"center",alignItems:"center",color:v,fontWeight:C,fontSize:d,fontStyle:"normal",lineHeight:1,textAlign:"center",textTransform:"none",textDecoration:"none",background:"transparent",border:0,cursor:"pointer",transition:`all ${i}`,textRendering:"auto",[`&${a}-close-end`]:{marginInlineStart:h},[`&:not(${a}-close-end)`]:{marginInlineEnd:h},"&:hover":{color:A,backgroundColor:b,textDecoration:"none"},"&:active":{backgroundColor:y}},(0,N.genFocusStyle)(e)),[`${a}-title`]:{flex:1,margin:0,fontWeight:e.fontWeightStrong,fontSize:d,lineHeight:m},[`${a}-body`]:{flex:1,minWidth:0,minHeight:0,padding:u,overflow:"auto",[`${a}-body-skeleton`]:{width:"100%",height:"100%",display:"flex",justifyContent:"center"}},[`${a}-footer`]:{flexShrink:0,padding:`${(0,M.unit)(I)} ${(0,M.unit)(w)}`,borderTop:`${(0,M.unit)(p)} ${f} ${g}`},"&-rtl":{direction:"rtl"}}}})(t),(e=>{let{componentCls:t,motionDurationSlow:a}=e;return{[t]:{[`${t}-mask-motion`]:P(0,a),[`${t}-panel-motion`]:["left","right","top","bottom"].reduce((e,t)=>{let l;return Object.assign(Object.assign({},e),{[`&-${t}`]:[P(.7,a),D({transform:(l="100%",({left:`translateX(-${l})`,right:`translateX(${l})`,top:`translateY(-${l})`,bottom:`translateY(${l})`})[t])},{transform:"none"})]})},{})}}})(t)]},e=>({zIndexPopup:e.zIndexPopupBase,footerPaddingBlock:e.paddingXS,footerPaddingInline:e.padding}));var H=function(e,t){var a={};for(var l in e)Object.prototype.hasOwnProperty.call(e,l)&&0>t.indexOf(l)&&(a[l]=e[l]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var n=0,l=Object.getOwnPropertySymbols(e);nt.indexOf(l[n])&&Object.prototype.propertyIsEnumerable.call(e,l[n])&&(a[l[n]]=e[l[n]]);return a};let B={distance:180},F=e=>{let{rootClassName:l,width:n,height:r,size:o="default",mask:i=!0,push:s=B,open:c,afterOpenChange:u,onClose:d,prefixCls:m,getContainer:p,panelRef:f=null,style:h,className:v,"aria-labelledby":A,visible:b,afterVisibleChange:y,maskStyle:x,drawerStyle:L,contentWrapperStyle:$,destroyOnClose:M,destroyOnHidden:N}=e,R=H(e,["rootClassName","width","height","size","mask","push","open","afterOpenChange","onClose","prefixCls","getContainer","panelRef","style","className","aria-labelledby","visible","afterVisibleChange","maskStyle","drawerStyle","contentWrapperStyle","destroyOnClose","destroyOnHidden"]),j=(0,I.default)(),D=R.title?j:void 0,{getPopupContainer:P,getPrefixCls:F,direction:V,className:G,style:K,classNames:U,styles:W}=(0,k.useComponentConfig)("drawer"),X=F("drawer",m),[q,Q,Y]=z(X),Z=void 0===p&&P?()=>P(document.body):p,J=(0,a.default)({"no-mask":!i,[`${X}-rtl`]:"rtl"===V},l,Q,Y),ee=t.useMemo(()=>null!=n?n:"large"===o?736:378,[n,o]),et=t.useMemo(()=>null!=r?r:"large"===o?736:378,[r,o]),ea={motionName:(0,E.getTransitionName)(X,"mask-motion"),motionAppear:!0,motionEnter:!0,motionLeave:!0,motionDeadline:500},el=(0,_.usePanelRef)(),en=(0,g.composeRef)(f,el),[er,eo]=(0,O.useZIndex)("Drawer",R.zIndex),{classNames:ei={},styles:es={}}=R;return q(t.createElement(w.default,{form:!0,space:!0},t.createElement(S.default.Provider,{value:eo},t.createElement(C,Object.assign({prefixCls:X,onClose:d,maskMotion:ea,motion:e=>({motionName:(0,E.getTransitionName)(X,`panel-motion-${e}`),motionAppear:!0,motionEnter:!0,motionLeave:!0,motionDeadline:500})},R,{classNames:{mask:(0,a.default)(ei.mask,U.mask),content:(0,a.default)(ei.content,U.content),wrapper:(0,a.default)(ei.wrapper,U.wrapper)},styles:{mask:Object.assign(Object.assign(Object.assign({},es.mask),x),W.mask),content:Object.assign(Object.assign(Object.assign({},es.content),L),W.content),wrapper:Object.assign(Object.assign(Object.assign({},es.wrapper),$),W.wrapper)},open:null!=c?c:b,mask:i,push:s,width:ee,height:et,style:Object.assign(Object.assign({},K),h),className:(0,a.default)(G,v),rootClassName:J,getContainer:Z,afterOpenChange:null!=u?u:y,panelRef:en,zIndex:er,"aria-labelledby":null!=A?A:D,destroyOnClose:null!=N?N:M}),t.createElement(T,Object.assign({prefixCls:X},R,{ariaId:D,onClose:d}))))))};F._InternalPanelDoNotUseOrYouWillBeFired=e=>{let{prefixCls:l,style:n,className:r,placement:o="right"}=e,i=H(e,["prefixCls","style","className","placement"]),{getPrefixCls:s}=t.useContext(k.ConfigContext),c=s("drawer",l),[u,d,m]=z(c),p=(0,a.default)(c,`${c}-pure`,`${c}-${o}`,d,m,r);return u(t.createElement("div",{className:p,style:n},t.createElement(T,Object.assign({prefixCls:c},i))))},e.s(["Drawer",0,F],608856)},195116,e=>{"use strict";let t=(0,e.i(475254).default)("wrench",[["path",{d:"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z",key:"cbrjhi"}]]);e.s(["Wrench",0,t],195116)},149121,e=>{"use strict";var t=e.i(843476),a=e.i(271645),l=e.i(152990),n=e.i(682830),r=e.i(269200),o=e.i(427612),i=e.i(64848),s=e.i(942232),c=e.i(496020),u=e.i(977572);e.s(["DataTable",0,function({data:e=[],columns:d,onRowClick:m,renderSubComponent:p,renderChildRows:f,getRowCanExpand:g,isLoading:h=!1,loadingMessage:v="🚅 Loading logs...",noDataMessage:A="No logs found",enableSorting:b=!1}){let y=!!(p||f)&&!!g,x=d.some(e=>void 0!==e.size),[C,I]=(0,a.useState)([]),w=(0,l.useReactTable)({data:e,columns:d,...b&&{state:{sorting:C},onSortingChange:I,enableSortingRemoval:!1},...y&&{getRowCanExpand:g},getRowId:(e,t)=>e?.request_id??String(t),getCoreRowModel:(0,n.getCoreRowModel)(),...b&&{getSortedRowModel:(0,n.getSortedRowModel)()},...y&&{getExpandedRowModel:(0,n.getExpandedRowModel)()}}),O=x?{minWidth:w.getCenterTotalSize()}:{minWidth:"400px"};return(0,t.jsx)("div",{className:"rounded-lg custom-border overflow-x-auto w-full max-w-full box-border",children:(0,t.jsxs)(r.Table,{className:x?"[&_td]:py-0.5 [&_th]:py-1 [&_table]:table-fixed":"[&_td]:py-0.5 [&_th]:py-1 table-fixed w-full box-border",style:O,children:[(0,t.jsx)(o.TableHead,{children:w.getHeaderGroups().map(e=>(0,t.jsx)(c.TableRow,{children:e.headers.map(e=>{let a=b&&e.column.getCanSort(),n=e.column.getIsSorted();return(0,t.jsx)(i.TableHeaderCell,{className:`py-1 h-8 ${a?"cursor-pointer select-none hover:bg-gray-50":""}`,style:x?{width:e.getSize()}:void 0,onClick:a?e.column.getToggleSortingHandler():void 0,children:e.isPlaceholder?null:(0,t.jsxs)("div",{className:"flex items-center gap-1",children:[(0,l.flexRender)(e.column.columnDef.header,e.getContext()),a&&(0,t.jsx)("span",{className:"text-gray-400",children:"asc"===n?"↑":"desc"===n?"↓":"⇅"})]})},e.id)})},e.id))}),(0,t.jsx)(s.TableBody,{children:h?(0,t.jsx)(c.TableRow,{children:(0,t.jsx)(u.TableCell,{colSpan:d.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:v})})})}):w.getRowModel().rows.length>0?w.getRowModel().rows.map(e=>(0,t.jsxs)(a.Fragment,{children:[(0,t.jsx)(c.TableRow,{className:`h-8 ${m?"cursor-pointer hover:bg-gray-50":""}`,onClick:()=>m?.(e.original),children:e.getVisibleCells().map(e=>(0,t.jsx)(u.TableCell,{className:"py-0.5 max-h-8 overflow-hidden text-ellipsis whitespace-nowrap",style:x?{width:e.column.getSize()}:void 0,children:(0,l.flexRender)(e.column.columnDef.cell,e.getContext())},e.id))}),y&&e.getIsExpanded()&&f&&f({row:e}),y&&e.getIsExpanded()&&p&&!f&&(0,t.jsx)(c.TableRow,{children:(0,t.jsx)(u.TableCell,{colSpan:e.getVisibleCells().length,className:"p-0",children:(0,t.jsx)("div",{className:"w-full max-w-full overflow-hidden box-border",children:p({row:e})})})})]},e.id)):(0,t.jsx)(c.TableRow,{children:(0,t.jsx)(u.TableCell,{colSpan:d.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:A})})})})})]})})}])},95684,e=>{"use strict";var t=e.i(165370);e.s(["Pagination",()=>t.default])},836991,e=>{"use strict";var t=e.i(271645);let a=t.forwardRef(function(e,a){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:a},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"}))});e.s(["XIcon",0,a],836991)},446891,e=>{"use strict";var t=e.i(843476),a=e.i(464571),l=e.i(326373),n=e.i(94629),r=e.i(360820),o=e.i(871943),i=e.i(836991);e.s(["TableHeaderSortDropdown",0,({sortState:e,onSortChange:s})=>{let c=[{key:"asc",label:"Ascending",icon:(0,t.jsx)(r.ChevronUpIcon,{className:"h-4 w-4"})},{key:"desc",label:"Descending",icon:(0,t.jsx)(o.ChevronDownIcon,{className:"h-4 w-4"})},{key:"reset",label:"Reset",icon:(0,t.jsx)(i.XIcon,{className:"h-4 w-4"})}];return(0,t.jsx)(l.Dropdown,{menu:{items:c,onClick:({key:e})=>{"asc"===e?s("asc"):"desc"===e?s("desc"):"reset"===e&&s(!1)},selectable:!0,selectedKeys:e?[e]:[]},trigger:["click"],autoAdjustOverflow:!0,children:(0,t.jsx)(a.Button,{type:"text",onClick:e=>e.stopPropagation(),icon:"asc"===e?(0,t.jsx)(r.ChevronUpIcon,{className:"h-4 w-4"}):"desc"===e?(0,t.jsx)(o.ChevronDownIcon,{className:"h-4 w-4"}):(0,t.jsx)(n.SwitchVerticalIcon,{className:"h-4 w-4"}),className:e?"text-blue-500 hover:text-blue-600":"text-gray-400 hover:text-blue-500"})})}])},362024,e=>{"use strict";var t=e.i(988122);e.s(["Collapse",()=>t.default])},240647,e=>{"use strict";var t=e.i(286612);e.s(["RightOutlined",()=>t.default])},245704,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let l={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M699 353h-46.9c-10.2 0-19.9 4.9-25.9 13.3L469 584.3l-71.2-98.8c-6-8.3-15.6-13.3-25.9-13.3H325c-6.5 0-10.3 7.4-6.5 12.7l124.6 172.8a31.8 31.8 0 0051.7 0l210.6-292c3.9-5.3.1-12.7-6.4-12.7z"}},{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"}}]},name:"check-circle",theme:"outlined"};var n=e.i(9583),r=a.forwardRef(function(e,r){return a.createElement(n.default,(0,t.default)({},e,{ref:r,icon:l}))});e.s(["CheckCircleOutlined",0,r],245704)},149192,e=>{"use strict";var t=e.i(864517);e.s(["CloseOutlined",()=>t.default])},518617,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let l={icon:{tag:"svg",attrs:{"fill-rule":"evenodd",viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm0 76c-205.4 0-372 166.6-372 372s166.6 372 372 372 372-166.6 372-372-166.6-372-372-372zm128.01 198.83c.03 0 .05.01.09.06l45.02 45.01a.2.2 0 01.05.09.12.12 0 010 .07c0 .02-.01.04-.05.08L557.25 512l127.87 127.86a.27.27 0 01.05.06v.02a.12.12 0 010 .07c0 .03-.01.05-.05.09l-45.02 45.02a.2.2 0 01-.09.05.12.12 0 01-.07 0c-.02 0-.04-.01-.08-.05L512 557.25 384.14 685.12c-.04.04-.06.05-.08.05a.12.12 0 01-.07 0c-.03 0-.05-.01-.09-.05l-45.02-45.02a.2.2 0 01-.05-.09.12.12 0 010-.07c0-.02.01-.04.06-.08L466.75 512 338.88 384.14a.27.27 0 01-.05-.06l-.01-.02a.12.12 0 010-.07c0-.03.01-.05.05-.09l45.02-45.02a.2.2 0 01.09-.05.12.12 0 01.07 0c.02 0 .04.01.08.06L512 466.75l127.86-127.86c.04-.05.06-.06.08-.06a.12.12 0 01.07 0z"}}]},name:"close-circle",theme:"outlined"};var n=e.i(9583),r=a.forwardRef(function(e,r){return a.createElement(n.default,(0,t.default)({},e,{ref:r,icon:l}))});e.s(["CloseCircleOutlined",0,r],518617)},657150,e=>{"use strict";let t=(0,e.i(475254).default)("bot",[["path",{d:"M12 8V4H8",key:"hb8ula"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2",key:"enze0r"}],["path",{d:"M2 14h2",key:"vft8re"}],["path",{d:"M20 14h2",key:"4cs60a"}],["path",{d:"M15 13v2",key:"1xurst"}],["path",{d:"M9 13v2",key:"rq6x2g"}]]);e.s(["default",0,t])},531245,782273,793916,e=>{"use strict";var t=e.i(657150);e.s(["Bot",()=>t.default],531245),e.i(247167);var a=e.i(931067),l=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M625.9 115c-5.9 0-11.9 1.6-17.4 5.3L254 352H90c-8.8 0-16 7.2-16 16v288c0 8.8 7.2 16 16 16h164l354.5 231.7c5.5 3.6 11.6 5.3 17.4 5.3 16.7 0 32.1-13.3 32.1-32.1V147.1c0-18.8-15.4-32.1-32.1-32.1zM586 803L293.4 611.7l-18-11.7H146V424h129.4l17.9-11.7L586 221v582zm348-327H806c-8.8 0-16 7.2-16 16v40c0 8.8 7.2 16 16 16h128c8.8 0 16-7.2 16-16v-40c0-8.8-7.2-16-16-16zm-41.9 261.8l-110.3-63.7a15.9 15.9 0 00-21.7 5.9l-19.9 34.5c-4.4 7.6-1.8 17.4 5.8 21.8L856.3 800a15.9 15.9 0 0021.7-5.9l19.9-34.5c4.4-7.6 1.7-17.4-5.8-21.8zM760 344a15.9 15.9 0 0021.7 5.9L892 286.2c7.6-4.4 10.2-14.2 5.8-21.8L878 230a15.9 15.9 0 00-21.7-5.9L746 287.8a15.99 15.99 0 00-5.8 21.8L760 344z"}}]},name:"sound",theme:"outlined"};var r=e.i(9583),o=l.forwardRef(function(e,t){return l.createElement(r.default,(0,a.default)({},e,{ref:t,icon:n}))});e.s(["SoundOutlined",0,o],782273);let i={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M842 454c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8 0 140.3-113.7 254-254 254S258 594.3 258 454c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8 0 168.7 126.6 307.9 290 327.6V884H326.7c-13.7 0-24.7 14.3-24.7 32v36c0 4.4 2.8 8 6.2 8h407.6c3.4 0 6.2-3.6 6.2-8v-36c0-17.7-11-32-24.7-32H548V782.1c165.3-18 294-158 294-328.1zM512 624c93.9 0 170-75.2 170-168V232c0-92.8-76.1-168-170-168s-170 75.2-170 168v224c0 92.8 76.1 168 170 168zm-94-392c0-50.6 41.9-92 94-92s94 41.4 94 92v224c0 50.6-41.9 92-94 92s-94-41.4-94-92V232z"}}]},name:"audio",theme:"outlined"};var s=l.forwardRef(function(e,t){return l.createElement(r.default,(0,a.default)({},e,{ref:t,icon:i}))});e.s(["AudioOutlined",0,s],793916)},94629,e=>{"use strict";var t=e.i(271645);let a=t.forwardRef(function(e,a){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:a},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"}))});e.s(["SwitchVerticalIcon",0,a],94629)},166406,e=>{"use strict";var t=e.i(190144);e.s(["CopyOutlined",()=>t.default])},447566,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let l={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 000 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"}}]},name:"arrow-left",theme:"outlined"};var n=e.i(9583),r=a.forwardRef(function(e,r){return a.createElement(n.default,(0,t.default)({},e,{ref:r,icon:l}))});e.s(["ArrowLeftOutlined",0,r],447566)},969550,e=>{"use strict";var t=e.i(843476),a=e.i(271645);let l=a.forwardRef(function(e,t){return a.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),a.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"}))});var n=e.i(464571),r=e.i(311451),o=e.i(199133),i=e.i(374009);e.s(["default",0,({options:e,onApplyFilters:s,onResetFilters:c,initialValues:u={},buttonLabel:d="Filters"})=>{let[m,p]=(0,a.useState)(!1),[f,g]=(0,a.useState)(u),[h,v]=(0,a.useState)({}),[A,b]=(0,a.useState)({}),[y,x]=(0,a.useState)({}),[C,I]=(0,a.useState)({}),w=(0,a.useCallback)((0,i.default)(async(e,t)=>{if(t.isSearchable&&t.searchFn){b(e=>({...e,[t.name]:!0}));try{let a=await t.searchFn(e);v(e=>({...e,[t.name]:a}))}catch(e){console.error("Error searching:",e),v(e=>({...e,[t.name]:[]}))}finally{b(e=>({...e,[t.name]:!1}))}}},300),[]),O=(0,a.useCallback)(async e=>{if(e.isSearchable&&e.searchFn&&!e.loading&&!C[e.name]){b(t=>({...t,[e.name]:!0})),I(t=>({...t,[e.name]:!0}));try{let t=await e.searchFn("");v(a=>({...a,[e.name]:t}))}catch(t){console.error("Error loading initial options:",t),v(t=>({...t,[e.name]:[]}))}finally{b(t=>({...t,[e.name]:!1}))}}},[C]);(0,a.useEffect)(()=>{m&&e.forEach(e=>{e.isSearchable&&!C[e.name]&&O(e)})},[m,e,O,C]);let E=(e,t)=>{let a={...f,[e]:t};g(a),s(a)};return(0,t.jsxs)("div",{className:"w-full",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 mb-6",children:[(0,t.jsx)(n.Button,{icon:(0,t.jsx)(l,{className:"h-4 w-4"}),onClick:()=>p(!m),className:"flex items-center gap-2",children:d}),(0,t.jsx)(n.Button,{onClick:()=>{let t={};e.forEach(e=>{t[e.name]=""}),g(t),c()},children:"Reset Filters"})]}),m&&(0,t.jsx)("div",{className:"grid grid-cols-3 gap-x-6 gap-y-4 mb-6",children:e.map(e=>{let a,l=A[e.name]||e.loading;return(0,t.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,t.jsx)("label",{className:"text-sm text-gray-600",children:e.label||e.name}),e.isSearchable?(0,t.jsx)(o.Select,{showSearch:!0,className:"w-full",placeholder:`Search ${e.label||e.name}...`,value:f[e.name]||void 0,onChange:t=>E(e.name,t),onOpenChange:t=>{t&&e.isSearchable&&!C[e.name]&&O(e)},onSearch:t=>{x(a=>({...a,[e.name]:t})),e.searchFn&&w(t,e)},filterOption:!1,loading:l,options:h[e.name]||[],allowClear:!0,notFoundContent:l?"Loading...":"No results found"}):e.options?(0,t.jsx)(o.Select,{className:"w-full",placeholder:`Select ${e.label||e.name}...`,value:f[e.name]||void 0,onChange:t=>E(e.name,t),allowClear:!0,children:e.options.map(e=>(0,t.jsx)(o.Select.Option,{value:e.value,children:e.label},e.value))}):e.customComponent?(a=e.customComponent,(0,t.jsx)(a,{value:f[e.name]||void 0,onChange:t=>E(e.name,t??""),placeholder:`Select ${e.label||e.name}...`,allFilters:f})):(0,t.jsx)(r.Input,{className:"w-full",placeholder:`Enter ${e.label||e.name}...`,value:f[e.name]||"",onChange:t=>E(e.name,t.target.value),allowClear:!0})]},e.name)})})]})}],969550)},50882,e=>{"use strict";var t=e.i(843476),a=e.i(621482),l=e.i(243652),n=e.i(602869),r=e.i(135214);let o=(0,l.createQueryKeys)("infiniteKeyAliases");var i=e.i(56456),s=e.i(152473),c=e.i(199133),u=e.i(271645);e.s(["PaginatedKeyAliasSelect",0,({value:e,onChange:l,placeholder:d="Select a key alias",style:m,pageSize:p=50,allowClear:f=!0,disabled:g=!1,allFilters:h})=>{let[v,A]=(0,u.useState)(""),[b,y]=(0,s.useDebouncedState)("",{wait:300}),{data:x,fetchNextPage:C,hasNextPage:I,isFetchingNextPage:w,isLoading:O}=((e=50,t,l)=>{let{accessToken:i}=(0,r.default)();return(0,a.useInfiniteQuery)({queryKey:o.list({filters:{size:e,...t&&{search:t},...l&&{team_id:l}}}),queryFn:async({pageParam:a})=>await (0,n.keyAliasesCall)(i,a,e,t,l),initialPageParam:1,getNextPageParam:e=>{if(e.current_page{if(!x?.pages)return[];let e=new Set,t=[];for(let a of x.pages)for(let l of a.aliases)!l||e.has(l)||(e.add(l),t.push({label:l,value:l}));return t},[x]);return(0,t.jsx)(c.Select,{value:e||void 0,onChange:e=>{l?.(e??"")},placeholder:d,style:{width:"100%",...m},allowClear:f,disabled:g,showSearch:!0,filterOption:!1,onSearch:e=>{A(e),y(e)},searchValue:v,onPopupScroll:e=>{let t=e.currentTarget;(t.scrollTop+t.clientHeight)/t.scrollHeight>=.8&&I&&!w&&C()},loading:O,notFoundContent:O?(0,t.jsx)(i.LoadingOutlined,{spin:!0}):"No key aliases found",options:E,popupRender:e=>(0,t.jsxs)(t.Fragment,{children:[e,w&&(0,t.jsx)("div",{style:{textAlign:"center",padding:8},children:(0,t.jsx)(i.LoadingOutlined,{spin:!0})})]})})}],50882)},307582,e=>{"use strict";var t=e.i(843476);e.s(["TimeCell",0,({utcTime:e})=>(0,t.jsx)("span",{style:{fontFamily:"monospace",width:"180px",display:"inline-block"},children:(e=>{try{return new Date(e).toLocaleString("en-US",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!0}).replace(",","")}catch(e){return"Error converting time"}})(e)})])},700514,e=>{"use strict";var t=e.i(271645);e.s(["defaultPageSize",0,25,"useBaseUrl",0,()=>{let[e,a]=(0,t.useState)("http://localhost:4000");return(0,t.useEffect)(()=>{{let{protocol:e,host:t}=window.location;a(`${e}//${t}`)}},[]),e}])},625901,e=>{"use strict";var t=e.i(266027),a=e.i(621482),l=e.i(243652),n=e.i(602869),r=e.i(135214);let o=(0,l.createQueryKeys)("models"),i=(0,l.createQueryKeys)("modelHub"),s=(0,l.createQueryKeys)("allProxyModels");(0,l.createQueryKeys)("selectedTeamModels");let c=(0,l.createQueryKeys)("infiniteModels"),u=(0,l.createQueryKeys)("userModels");e.s(["useAllProxyModels",0,()=>{let{accessToken:e,userId:a,userRole:l}=(0,r.default)();return(0,t.useQuery)({queryKey:s.list({}),queryFn:async()=>await (0,n.modelAvailableCall)(e,a,l,!0,null,!0,!1,"expand"),enabled:!!(e&&a&&l)})},"useInfiniteModelInfo",0,(e=50,t)=>{let{accessToken:l,userId:o,userRole:i}=(0,r.default)();return(0,a.useInfiniteQuery)({queryKey:c.list({filters:{...o&&{userId:o},...i&&{userRole:i},size:e,...t&&{search:t}}}),queryFn:async({pageParam:a})=>await (0,n.modelInfoCall)(l,o,i,a,e,t),initialPageParam:1,getNextPageParam:e=>{if(e.current_page{let{accessToken:e}=(0,r.default)();return(0,t.useQuery)({queryKey:i.list({}),queryFn:async()=>await (0,n.modelHubCall)(e),enabled:!!e})},"useModelsInfo",0,(e=1,a=50,l,i,s,c,u)=>{let{accessToken:d,userId:m,userRole:p}=(0,r.default)();return(0,t.useQuery)({queryKey:o.list({filters:{...m&&{userId:m},...p&&{userRole:p},page:e,size:a,...l&&{search:l},...i&&{modelId:i},...s&&{teamId:s},...c&&{sortBy:c},...u&&{sortOrder:u}}}),queryFn:async()=>await (0,n.modelInfoCall)(d,m,p,e,a,l,i,s,c,u),enabled:!!(d&&m&&p)})},"useUserModels",0,()=>{let{accessToken:e,userId:a,userRole:l}=(0,r.default)();return(0,t.useQuery)({queryKey:u.list({}),queryFn:async()=>(await (0,n.modelAvailableCall)(e,a,l)).data.map(e=>e.id),enabled:!!(e&&a&&l)})}])},633627,e=>{"use strict";var t=e.i(602869);let a=(e,t,a,l)=>{for(let n of e){let e=n?.key_alias;e&&"string"==typeof e&&t.add(e.trim());let r=n?.organization_id??n?.org_id;r&&"string"==typeof r&&a.add(r.trim());let o=n?.user_id;if(o&&"string"==typeof o){let e=n?.user?.user_email||o;l.set(o,e)}}},l=async(e,l)=>{if(!e||!l)return{keyAliases:[],organizationIds:[],userIds:[]};try{let n=new Set,r=new Set,o=new Map,i=await (0,t.keyListCall)(e,null,l,null,null,null,1,100,null,null,"user",null),s=i?.keys||[],c=i?.total_pages??1;a(s,n,r,o);let u=Math.min(c,10)-1;if(u>0){let i=Array.from({length:u},(a,n)=>(0,t.keyListCall)(e,null,l,null,null,null,n+2,100,null,null,"user",null));for(let e of(await Promise.allSettled(i)))"fulfilled"===e.status&&a(e.value?.keys||[],n,r,o)}return{keyAliases:Array.from(n).sort(),organizationIds:Array.from(r).sort(),userIds:Array.from(o.entries()).map(([e,t])=>({id:e,email:t}))}}catch(e){return console.error("Error fetching team filter options:",e),{keyAliases:[],organizationIds:[],userIds:[]}}},n=async(e,a)=>{if(!e)return[];try{let l=[],n=1,r=!0;for(;r;){let o=await (0,t.teamListCall)(e,a||null,null);l=[...l,...o],n{"use strict";var t=e.i(843476),a=e.i(482725),l=e.i(56456);e.s(["AntDLoadingSpinner",0,function({size:e,fontSize:n}){let r=(0,t.jsx)(l.LoadingOutlined,{style:n?{fontSize:n}:void 0,spin:!0});return(0,t.jsx)(a.Spin,{indicator:r,size:e})}])}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/033clseufop6o.js b/litellm/proxy/_experimental/out/_next/static/chunks/033clseufop6o.js new file mode 100644 index 00000000000..3bcc0cb1811 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/033clseufop6o.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,447566,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 000 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"}}]},name:"arrow-left",theme:"outlined"};var s=e.i(9583),o=r.forwardRef(function(e,o){return r.createElement(s.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["ArrowLeftOutlined",0,o],447566)},599724,936325,e=>{"use strict";var t=e.i(95779),r=e.i(444755),a=e.i(673706),s=e.i(271645);let o=s.default.forwardRef((e,o)=>{let{color:l,className:i,children:n}=e;return s.default.createElement("p",{ref:o,className:(0,r.tremorTwMerge)("text-tremor-default",l?(0,a.getColorClassNames)(l,t.colorPalette.text).textColor:(0,r.tremorTwMerge)("text-tremor-content","dark:text-dark-tremor-content"),i)},n)});o.displayName="Text",e.s(["default",0,o],936325),e.s(["Text",0,o],599724)},994388,e=>{"use strict";var t=e.i(290571),r=e.i(829087),a=e.i(271645);let s=["preEnter","entering","entered","preExit","exiting","exited","unmounted"],o=e=>({_s:e,status:s[e],isEnter:e<3,isMounted:6!==e,isResolved:2===e||e>4}),l=e=>e?6:5,i=(e,t,r,a,s)=>{clearTimeout(a.current);let l=o(e);t(l),r.current=l,s&&s({current:l})};var n=e.i(480731),d=e.i(444755),c=e.i(673706);let u=e=>{var r=(0,t.__rest)(e,[]);return a.default.createElement("svg",Object.assign({},r,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"}),a.default.createElement("path",{fill:"none",d:"M0 0h24v24H0z"}),a.default.createElement("path",{d:"M18.364 5.636L16.95 7.05A7 7 0 1 0 19 12h2a9 9 0 1 1-2.636-6.364z"}))};var m=e.i(95779);let g={xs:{height:"h-4",width:"w-4"},sm:{height:"h-5",width:"w-5"},md:{height:"h-5",width:"w-5"},lg:{height:"h-6",width:"w-6"},xl:{height:"h-6",width:"w-6"}},h=(e,t)=>{switch(e){case"primary":return{textColor:t?(0,c.getColorClassNames)("white").textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",hoverTextColor:t?(0,c.getColorClassNames)("white").textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:t?(0,c.getColorClassNames)(t,m.colorPalette.background).bgColor:"bg-tremor-brand dark:bg-dark-tremor-brand",hoverBgColor:t?(0,c.getColorClassNames)(t,m.colorPalette.darkBackground).hoverBgColor:"hover:bg-tremor-brand-emphasis dark:hover:bg-dark-tremor-brand-emphasis",borderColor:t?(0,c.getColorClassNames)(t,m.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand",hoverBorderColor:t?(0,c.getColorClassNames)(t,m.colorPalette.darkBorder).hoverBorderColor:"hover:border-tremor-brand-emphasis dark:hover:border-dark-tremor-brand-emphasis"};case"secondary":return{textColor:t?(0,c.getColorClassNames)(t,m.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",hoverTextColor:t?(0,c.getColorClassNames)(t,m.colorPalette.text).textColor:"hover:text-tremor-brand-emphasis dark:hover:text-dark-tremor-brand-emphasis",bgColor:(0,c.getColorClassNames)("transparent").bgColor,hoverBgColor:t?(0,d.tremorTwMerge)((0,c.getColorClassNames)(t,m.colorPalette.background).hoverBgColor,"hover:bg-opacity-20 dark:hover:bg-opacity-20"):"hover:bg-tremor-brand-faint dark:hover:bg-dark-tremor-brand-faint",borderColor:t?(0,c.getColorClassNames)(t,m.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand"};case"light":return{textColor:t?(0,c.getColorClassNames)(t,m.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",hoverTextColor:t?(0,c.getColorClassNames)(t,m.colorPalette.darkText).hoverTextColor:"hover:text-tremor-brand-emphasis dark:hover:text-dark-tremor-brand-emphasis",bgColor:(0,c.getColorClassNames)("transparent").bgColor,borderColor:"",hoverBorderColor:""}}},p=(0,c.makeClassName)("Button"),f=({loading:e,iconSize:t,iconPosition:r,Icon:s,needMargin:o,transitionStatus:l})=>{let i=o?r===n.HorizontalPositions.Left?(0,d.tremorTwMerge)("-ml-1","mr-1.5"):(0,d.tremorTwMerge)("-mr-1","ml-1.5"):"",c=(0,d.tremorTwMerge)("w-0 h-0"),m={default:c,entering:c,entered:t,exiting:t,exited:c};return e?a.default.createElement(u,{className:(0,d.tremorTwMerge)(p("icon"),"animate-spin shrink-0",i,m.default,m[l]),style:{transition:"width 150ms"}}):a.default.createElement(s,{className:(0,d.tremorTwMerge)(p("icon"),"shrink-0",t,i)})},b=a.default.forwardRef((e,s)=>{let{icon:u,iconPosition:m=n.HorizontalPositions.Left,size:b=n.Sizes.SM,color:x,variant:v="primary",disabled:w,loading:C=!1,loadingText:y,children:k,tooltip:N,className:T}=e,M=(0,t.__rest)(e,["icon","iconPosition","size","color","variant","disabled","loading","loadingText","children","tooltip","className"]),S=C||w,E=void 0!==u||C,R=C&&y,j=!(!k&&!R),P=(0,d.tremorTwMerge)(g[b].height,g[b].width),O="light"!==v?(0,d.tremorTwMerge)("rounded-tremor-default border","shadow-tremor-input","dark:shadow-dark-tremor-input"):"",L=h(v,x),z=("light"!==v?{xs:{paddingX:"px-2.5",paddingY:"py-1.5",fontSize:"text-xs"},sm:{paddingX:"px-4",paddingY:"py-2",fontSize:"text-sm"},md:{paddingX:"px-4",paddingY:"py-2",fontSize:"text-md"},lg:{paddingX:"px-4",paddingY:"py-2.5",fontSize:"text-lg"},xl:{paddingX:"px-4",paddingY:"py-3",fontSize:"text-xl"}}:{xs:{paddingX:"",paddingY:"",fontSize:"text-xs"},sm:{paddingX:"",paddingY:"",fontSize:"text-sm"},md:{paddingX:"",paddingY:"",fontSize:"text-md"},lg:{paddingX:"",paddingY:"",fontSize:"text-lg"},xl:{paddingX:"",paddingY:"",fontSize:"text-xl"}})[b],{tooltipProps:_,getReferenceProps:B}=(0,r.useTooltip)(300),[H,I]=(({enter:e=!0,exit:t=!0,preEnter:r,preExit:s,timeout:n,initialEntered:d,mountOnEnter:c,unmountOnExit:u,onStateChange:m}={})=>{let[g,h]=(0,a.useState)(()=>o(d?2:l(c))),p=(0,a.useRef)(g),f=(0,a.useRef)(0),[b,x]="object"==typeof n?[n.enter,n.exit]:[n,n],v=(0,a.useCallback)(()=>{let e=((e,t)=>{switch(e){case 1:case 0:return 2;case 4:case 3:return l(t)}})(p.current._s,u);e&&i(e,h,p,f,m)},[m,u]);return[g,(0,a.useCallback)(a=>{let o=e=>{switch(i(e,h,p,f,m),e){case 1:b>=0&&(f.current=((...e)=>setTimeout(...e))(v,b));break;case 4:x>=0&&(f.current=((...e)=>setTimeout(...e))(v,x));break;case 0:case 3:f.current=((...e)=>setTimeout(...e))(()=>{isNaN(document.body.offsetTop)||o(e+1)},0)}},n=p.current.isEnter;"boolean"!=typeof a&&(a=!n),a?n||o(e?+!r:2):n&&o(t?s?3:4:l(u))},[v,m,e,t,r,s,b,x,u]),v]})({timeout:50});return(0,a.useEffect)(()=>{I(C)},[C]),a.default.createElement("button",Object.assign({ref:(0,c.mergeRefs)([s,_.refs.setReference]),className:(0,d.tremorTwMerge)(p("root"),"shrink-0 inline-flex justify-center items-center group font-medium outline-none",O,z.paddingX,z.paddingY,z.fontSize,L.textColor,L.bgColor,L.borderColor,L.hoverBorderColor,S?"opacity-50 cursor-not-allowed":(0,d.tremorTwMerge)(h(v,x).hoverTextColor,h(v,x).hoverBgColor,h(v,x).hoverBorderColor),T),disabled:S},B,M),a.default.createElement(r.default,Object.assign({text:N},_)),E&&m!==n.HorizontalPositions.Right?a.default.createElement(f,{loading:C,iconSize:P,iconPosition:m,Icon:u,transitionStatus:H.status,needMargin:j}):null,R||k?a.default.createElement("span",{className:(0,d.tremorTwMerge)(p("text"),"text-tremor-default whitespace-nowrap")},R?y:k):null,E&&m===n.HorizontalPositions.Right?a.default.createElement(f,{loading:C,iconSize:P,iconPosition:m,Icon:u,transitionStatus:H.status,needMargin:j}):null)});b.displayName="Button",e.s(["Button",0,b],994388)},304967,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(480731),s=e.i(95779),o=e.i(444755),l=e.i(673706);let i=(0,l.makeClassName)("Card"),n=r.default.forwardRef((e,n)=>{let{decoration:d="",decorationColor:c,children:u,className:m}=e,g=(0,t.__rest)(e,["decoration","decorationColor","children","className"]);return r.default.createElement("div",Object.assign({ref:n,className:(0,o.tremorTwMerge)(i("root"),"relative w-full text-left ring-1 rounded-tremor-default p-6","bg-tremor-background ring-tremor-ring shadow-tremor-card","dark:bg-dark-tremor-background dark:ring-dark-tremor-ring dark:shadow-dark-tremor-card",c?(0,l.getColorClassNames)(c,s.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand",(e=>{if(!e)return"";switch(e){case a.HorizontalPositions.Left:return"border-l-4";case a.VerticalPositions.Top:return"border-t-4";case a.HorizontalPositions.Right:return"border-r-4";case a.VerticalPositions.Bottom:return"border-b-4";default:return""}})(d),m)},g),u)});n.displayName="Card",e.s(["Card",0,n],304967)},629569,e=>{"use strict";var t=e.i(290571),r=e.i(95779),a=e.i(444755),s=e.i(673706),o=e.i(271645);let l=o.default.forwardRef((e,l)=>{let{color:i,children:n,className:d}=e,c=(0,t.__rest)(e,["color","children","className"]);return o.default.createElement("p",Object.assign({ref:l,className:(0,a.tremorTwMerge)("font-medium text-tremor-title",i?(0,s.getColorClassNames)(i,r.colorPalette.darkText).textColor:"text-tremor-content-strong dark:text-dark-tremor-content-strong",d)},c),n)});l.displayName="Title",e.s(["Title",0,l],629569)},653496,e=>{"use strict";var t=e.i(721369);e.s(["Tabs",()=>t.default])},536916,e=>{"use strict";var t=e.i(374276);e.s(["Checkbox",()=>t.default])},954616,e=>{"use strict";var t=e.i(271645),r=e.i(114272),a=e.i(540143),s=e.i(915823),o=e.i(619273),l=class extends s.Subscribable{#e;#t=void 0;#r;#a;constructor(e,t){super(),this.#e=e,this.setOptions(t),this.bindMethods(),this.#s()}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(e){let t=this.options;this.options=this.#e.defaultMutationOptions(e),(0,o.shallowEqualObjects)(this.options,t)||this.#e.getMutationCache().notify({type:"observerOptionsUpdated",mutation:this.#r,observer:this}),t?.mutationKey&&this.options.mutationKey&&(0,o.hashKey)(t.mutationKey)!==(0,o.hashKey)(this.options.mutationKey)?this.reset():this.#r?.state.status==="pending"&&this.#r.setOptions(this.options)}onUnsubscribe(){this.hasListeners()||this.#r?.removeObserver(this)}onMutationUpdate(e){this.#s(),this.#o(e)}getCurrentResult(){return this.#t}reset(){this.#r?.removeObserver(this),this.#r=void 0,this.#s(),this.#o()}mutate(e,t){return this.#a=t,this.#r?.removeObserver(this),this.#r=this.#e.getMutationCache().build(this.#e,this.options),this.#r.addObserver(this),this.#r.execute(e)}#s(){let e=this.#r?.state??(0,r.getDefaultState)();this.#t={...e,isPending:"pending"===e.status,isSuccess:"success"===e.status,isError:"error"===e.status,isIdle:"idle"===e.status,mutate:this.mutate,reset:this.reset}}#o(e){a.notifyManager.batch(()=>{if(this.#a&&this.hasListeners()){let t=this.#t.variables,r=this.#t.context,a={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};if(e?.type==="success"){try{this.#a.onSuccess?.(e.data,t,r,a)}catch(e){Promise.reject(e)}try{this.#a.onSettled?.(e.data,null,t,r,a)}catch(e){Promise.reject(e)}}else if(e?.type==="error"){try{this.#a.onError?.(e.error,t,r,a)}catch(e){Promise.reject(e)}try{this.#a.onSettled?.(void 0,e.error,t,r,a)}catch(e){Promise.reject(e)}}}this.listeners.forEach(e=>{e(this.#t)})})}},i=e.i(912598);e.s(["useMutation",0,function(e,r){let s=(0,i.useQueryClient)(r),[n]=t.useState(()=>new l(s,e));t.useEffect(()=>{n.setOptions(e)},[n,e]);let d=t.useSyncExternalStore(t.useCallback(e=>n.subscribe(a.notifyManager.batchCalls(e)),[n]),()=>n.getCurrentResult(),()=>n.getCurrentResult()),c=t.useCallback((e,t)=>{n.mutate(e,t).catch(o.noop)},[n]);if(d.error&&(0,o.shouldThrowError)(n.options.throwOnError,[d.error]))throw d.error;return{...d,mutate:c,mutateAsync:d.mutate}}],954616)},597440,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"}}]},name:"delete",theme:"outlined"};var s=e.i(9583),o=r.forwardRef(function(e,o){return r.createElement(s.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["default",0,o],597440)},955135,e=>{"use strict";var t=e.i(597440);e.s(["DeleteOutlined",()=>t.default])},646563,e=>{"use strict";var t=e.i(959013);e.s(["PlusOutlined",()=>t.default])},91739,e=>{"use strict";var t=e.i(544195);e.s(["Radio",()=>t.default])},482725,e=>{"use strict";var t=e.i(244451);e.s(["Spin",()=>t.default])},500330,e=>{"use strict";var t=e.i(727749);let r=(e,t=0,r=!1,a=!0)=>{if(null==e||!Number.isFinite(e)||0===e&&!a)return"-";let s={minimumFractionDigits:t,maximumFractionDigits:t};if(!r)return e.toLocaleString("en-US",s);let o=e<0?"-":"",l=Math.abs(e),i=l,n="";return l>=1e6?(i=l/1e6,n="M"):l>=1e3&&(i=l/1e3,n="K"),`${o}${i.toLocaleString("en-US",s)}${n}`},a=async(e,r="Copied to clipboard")=>{if(!e)return!1;if(!navigator||!navigator.clipboard||!navigator.clipboard.writeText)return s(e,r);try{return await navigator.clipboard.writeText(e),t.default.success(r),!0}catch(t){return console.error("Clipboard API failed: ",t),s(e,r)}},s=(e,r)=>{try{let a=document.createElement("textarea");a.value=e,a.style.position="fixed",a.style.left="-999999px",a.style.top="-999999px",a.setAttribute("readonly",""),document.body.appendChild(a),a.focus(),a.select();let s=document.execCommand("copy");if(document.body.removeChild(a),s)return t.default.success(r),!0;throw Error("execCommand failed")}catch(e){return t.default.fromBackend("Failed to copy to clipboard"),console.error("Failed to copy: ",e),!1}};e.s(["copyToClipboard",0,a,"formatNumberWithCommas",0,r,"getSpendString",0,(e,t=6)=>{if(null==e||!Number.isFinite(e)||0===e)return"-";let a=r(e,t,!1,!1);if(0===Number(a.replace(/,/g,""))){let e=(1/10**t).toFixed(t);return`< $${e}`}return`$${a}`},"updateExistingKeys",0,function(e,t){let r=structuredClone(e);for(let[e,a]of Object.entries(t))e in r&&(r[e]=a);return r}])},211576,e=>{"use strict";var t=e.i(131757);e.s(["Col",()=>t.default])},178654,e=>{"use strict";let t=e.i(211576).Col;e.s(["Col",0,t],178654)},621192,e=>{"use strict";let t=e.i(264042).Row;e.s(["Row",0,t],621192)},988297,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 4v16m8-8H4"}))});e.s(["PlusIcon",0,r],988297)},246349,e=>{"use strict";let t=(0,e.i(475254).default)("chevron-right",[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]]);e.s(["default",0,t])},695411,e=>{"use strict";var t=e.i(602869);let r=async e=>{try{let r=await (0,t.modelHubCall)(e);if(r?.data.length>0){let e=r.data.map(e=>({model_group:e.model_group,mode:e?.mode}));return e.sort((e,t)=>e.model_group.localeCompare(t.model_group)),e}return[]}catch(e){throw console.error("Error fetching model info:",e),e}};e.s(["fetchAvailableModels",0,r])},555987,e=>{"use strict";var t=e.i(221688),r=e.i(950643);let a=/^(https?:|data:|blob:|\/\/)/i;e.s(["resolveLogoSrc",0,(e,s=t.serverRootPath)=>{if(e){let t;return a.test(e)?e:(t=(0,r.normalizeRootPath)(s),`${t}${e.startsWith("/")?e:`/${e}`}`)}}])},269200,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(444755);let s=(0,e.i(673706).makeClassName)("Table"),o=r.default.forwardRef((e,o)=>{let{children:l,className:i}=e,n=(0,t.__rest)(e,["children","className"]);return r.default.createElement("div",{className:(0,a.tremorTwMerge)(s("root"),"overflow-auto",i)},r.default.createElement("table",Object.assign({ref:o,className:(0,a.tremorTwMerge)(s("table"),"w-full text-tremor-default","text-tremor-content","dark:text-dark-tremor-content")},n),l))});o.displayName="Table",e.s(["Table",0,o],269200)},427612,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(444755);let s=(0,e.i(673706).makeClassName)("TableHead"),o=r.default.forwardRef((e,o)=>{let{children:l,className:i}=e,n=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("thead",Object.assign({ref:o,className:(0,a.tremorTwMerge)(s("root"),"text-left","text-tremor-content","dark:text-dark-tremor-content",i)},n),l))});o.displayName="TableHead",e.s(["TableHead",0,o],427612)},64848,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(444755);let s=(0,e.i(673706).makeClassName)("TableHeaderCell"),o=r.default.forwardRef((e,o)=>{let{children:l,className:i}=e,n=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("th",Object.assign({ref:o,className:(0,a.tremorTwMerge)(s("root"),"whitespace-nowrap text-left font-semibold top-0 px-4 py-3.5","text-tremor-content-strong","dark:text-dark-tremor-content-strong",i)},n),l))});o.displayName="TableHeaderCell",e.s(["TableHeaderCell",0,o],64848)},942232,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(444755);let s=(0,e.i(673706).makeClassName)("TableBody"),o=r.default.forwardRef((e,o)=>{let{children:l,className:i}=e,n=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("tbody",Object.assign({ref:o,className:(0,a.tremorTwMerge)(s("root"),"align-top divide-y","divide-tremor-border","dark:divide-dark-tremor-border",i)},n),l))});o.displayName="TableBody",e.s(["TableBody",0,o],942232)},496020,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(444755);let s=(0,e.i(673706).makeClassName)("TableRow"),o=r.default.forwardRef((e,o)=>{let{children:l,className:i}=e,n=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("tr",Object.assign({ref:o,className:(0,a.tremorTwMerge)(s("row"),i)},n),l))});o.displayName="TableRow",e.s(["TableRow",0,o],496020)},977572,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(444755);let s=(0,e.i(673706).makeClassName)("TableCell"),o=r.default.forwardRef((e,o)=>{let{children:l,className:i}=e,n=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("td",Object.assign({ref:o,className:(0,a.tremorTwMerge)(s("root"),"align-middle whitespace-nowrap text-left p-4",i)},n),l))});o.displayName="TableCell",e.s(["TableCell",0,o],977572)},68155,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"}))});e.s(["TrashIcon",0,r],68155)},797672,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"}))});e.s(["PencilIcon",0,r],797672)},992619,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(779241),s=e.i(599724),o=e.i(199133),l=e.i(983561),i=e.i(695411);e.s(["default",0,({accessToken:e,value:n,placeholder:d="Select a Model",onChange:c,disabled:u=!1,style:m,className:g,showLabel:h=!0,labelText:p="Select Model"})=>{let[f,b]=(0,r.useState)(n),[x,v]=(0,r.useState)(!1),[w,C]=(0,r.useState)([]),y=(0,r.useRef)(null);return(0,r.useEffect)(()=>{b(n)},[n]),(0,r.useEffect)(()=>{e&&(async()=>{try{let t=await (0,i.fetchAvailableModels)(e);t.length>0&&C(t)}catch(e){console.error("Error fetching model info:",e)}})()},[e]),(0,t.jsxs)("div",{children:[h&&(0,t.jsxs)(s.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,t.jsx)(l.RobotOutlined,{className:"mr-2"})," ",p]}),(0,t.jsx)(o.Select,{value:f,placeholder:d,onChange:e=>{"custom"===e?(v(!0),b(void 0)):(v(!1),b(e),c&&c(e))},options:[...Array.from(new Set(w.map(e=>e.model_group))).map((e,t)=>({value:e,label:e,key:t})),{value:"custom",label:"Enter custom model",key:"custom"}],style:{width:"100%",...m},showSearch:!0,className:`rounded-md ${g||""}`,disabled:u}),x&&(0,t.jsx)(a.TextInput,{className:"mt-2",placeholder:"Enter custom model name",onValueChange:e=>{y.current&&clearTimeout(y.current),y.current=setTimeout(()=>{b(e),c&&c(e)},500)},disabled:u})]})}])},350967,46757,e=>{"use strict";var t=e.i(290571),r=e.i(444755),a=e.i(673706),s=e.i(271645);let o={0:"grid-cols-none",1:"grid-cols-1",2:"grid-cols-2",3:"grid-cols-3",4:"grid-cols-4",5:"grid-cols-5",6:"grid-cols-6",7:"grid-cols-7",8:"grid-cols-8",9:"grid-cols-9",10:"grid-cols-10",11:"grid-cols-11",12:"grid-cols-12"},l={0:"sm:grid-cols-none",1:"sm:grid-cols-1",2:"sm:grid-cols-2",3:"sm:grid-cols-3",4:"sm:grid-cols-4",5:"sm:grid-cols-5",6:"sm:grid-cols-6",7:"sm:grid-cols-7",8:"sm:grid-cols-8",9:"sm:grid-cols-9",10:"sm:grid-cols-10",11:"sm:grid-cols-11",12:"sm:grid-cols-12"},i={0:"md:grid-cols-none",1:"md:grid-cols-1",2:"md:grid-cols-2",3:"md:grid-cols-3",4:"md:grid-cols-4",5:"md:grid-cols-5",6:"md:grid-cols-6",7:"md:grid-cols-7",8:"md:grid-cols-8",9:"md:grid-cols-9",10:"md:grid-cols-10",11:"md:grid-cols-11",12:"md:grid-cols-12"},n={0:"lg:grid-cols-none",1:"lg:grid-cols-1",2:"lg:grid-cols-2",3:"lg:grid-cols-3",4:"lg:grid-cols-4",5:"lg:grid-cols-5",6:"lg:grid-cols-6",7:"lg:grid-cols-7",8:"lg:grid-cols-8",9:"lg:grid-cols-9",10:"lg:grid-cols-10",11:"lg:grid-cols-11",12:"lg:grid-cols-12"};e.s(["colSpan",0,{1:"col-span-1",2:"col-span-2",3:"col-span-3",4:"col-span-4",5:"col-span-5",6:"col-span-6",7:"col-span-7",8:"col-span-8",9:"col-span-9",10:"col-span-10",11:"col-span-11",12:"col-span-12",13:"col-span-13"},"colSpanLg",0,{1:"lg:col-span-1",2:"lg:col-span-2",3:"lg:col-span-3",4:"lg:col-span-4",5:"lg:col-span-5",6:"lg:col-span-6",7:"lg:col-span-7",8:"lg:col-span-8",9:"lg:col-span-9",10:"lg:col-span-10",11:"lg:col-span-11",12:"lg:col-span-12",13:"lg:col-span-13"},"colSpanMd",0,{1:"md:col-span-1",2:"md:col-span-2",3:"md:col-span-3",4:"md:col-span-4",5:"md:col-span-5",6:"md:col-span-6",7:"md:col-span-7",8:"md:col-span-8",9:"md:col-span-9",10:"md:col-span-10",11:"md:col-span-11",12:"md:col-span-12",13:"md:col-span-13"},"colSpanSm",0,{1:"sm:col-span-1",2:"sm:col-span-2",3:"sm:col-span-3",4:"sm:col-span-4",5:"sm:col-span-5",6:"sm:col-span-6",7:"sm:col-span-7",8:"sm:col-span-8",9:"sm:col-span-9",10:"sm:col-span-10",11:"sm:col-span-11",12:"sm:col-span-12",13:"sm:col-span-13"},"gridCols",0,o,"gridColsLg",0,n,"gridColsMd",0,i,"gridColsSm",0,l],46757);let d=(0,a.makeClassName)("Grid"),c=(e,t)=>e&&Object.keys(t).includes(String(e))?t[e]:"",u=s.default.forwardRef((e,a)=>{let{numItems:u=1,numItemsSm:m,numItemsMd:g,numItemsLg:h,children:p,className:f}=e,b=(0,t.__rest)(e,["numItems","numItemsSm","numItemsMd","numItemsLg","children","className"]),x=c(u,o),v=c(m,l),w=c(g,i),C=c(h,n),y=(0,r.tremorTwMerge)(x,v,w,C);return s.default.createElement("div",Object.assign({ref:a,className:(0,r.tremorTwMerge)(d("root"),"grid",y,f)},b),p)});u.displayName="Grid",e.s(["Grid",0,u],350967)},981339,e=>{"use strict";var t=e.i(185793);e.s(["Skeleton",()=>t.default])},500727,e=>{"use strict";var t=e.i(266027),r=e.i(243652),a=e.i(602869),s=e.i(135214);let o=(0,r.createQueryKeys)("mcpServers");e.s(["useMCPServers",0,e=>{let{accessToken:r}=(0,s.default)();return(0,t.useQuery)({queryKey:o.list(e?{filters:{teamId:e}}:void 0),queryFn:async()=>await (0,a.fetchMCPServers)(r,e),enabled:!!r})}])},699857,e=>{"use strict";var t=e.i(266027),r=e.i(243652),a=e.i(602869),s=e.i(135214);let o=(0,r.createQueryKeys)("mcpToolsets");e.s(["useMCPToolsets",0,()=>{let{accessToken:e}=(0,s.default)();return(0,t.useQuery)({queryKey:o.list(),queryFn:async()=>await (0,a.fetchMCPToolsets)(e),enabled:!!e})}])},841947,e=>{"use strict";let t=(0,e.i(475254).default)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);e.s(["default",0,t])},361653,e=>{"use strict";let t=(0,e.i(475254).default)("circle-alert",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]]);e.s(["default",0,t])},409797,e=>{"use strict";var t=e.i(631171);e.s(["ChevronDownIcon",()=>t.default])},531516,696609,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(536916),s=e.i(599724),o=e.i(409797),l=e.i(246349),l=l;let i=/\b(delete|remove|destroy|purge|drop|erase|unlink)\b/i,n=/\b(create|add|insert|new|post|submit|register|make|generate|write|upload)\b/i,d=/\b(update|edit|modify|change|patch|put|set|rename|move|transform)\b/i,c=/\b(get|read|list|fetch|search|find|query|retrieve|show|view|check|describe|info)\b/i;function u(e,t=""){let r=e.toLowerCase();if(c.test(r))return"read";if(i.test(r))return"delete";if(d.test(r))return"update";if(n.test(r))return"create";if(t){let e=t.toLowerCase();if(c.test(e))return"read";if(i.test(e))return"delete";if(d.test(e))return"update";if(n.test(e))return"create"}return"unknown"}function m(e){let t={read:[],create:[],update:[],delete:[],unknown:[]};for(let r of e)t[u(r.name,r.description)].push(r);return t}let g={read:{label:"Read",description:"Safe operations — fetch, list, search. No side effects.",risk:"low"},create:{label:"Create",description:"Add new resources — insert, upload, register.",risk:"medium"},update:{label:"Update",description:"Modify existing resources — edit, patch, rename.",risk:"medium"},delete:{label:"Delete",description:"Destructive operations — remove, purge, destroy.",risk:"high"},unknown:{label:"Other",description:"Operations that could not be automatically classified.",risk:"unknown"}};e.s(["CRUD_GROUP_META",0,g,"classifyToolOp",0,u,"groupToolsByCrud",0,m],696609);let h=["read","create","update","delete","unknown"],p={low:"bg-green-100 text-green-800",medium:"bg-yellow-100 text-yellow-800",high:"bg-red-100 text-red-800 font-semibold",unknown:"bg-gray-100 text-gray-700"},f={read:"border-green-200",create:"border-blue-200",update:"border-yellow-200",delete:"border-red-300",unknown:"border-gray-200"},b={read:"bg-green-50",create:"bg-blue-50",update:"bg-yellow-50",delete:"bg-red-50",unknown:"bg-gray-50"};e.s(["default",0,({tools:e,value:i,onChange:n,readOnly:d=!1,searchFilter:c=""})=>{let[u,x]=(0,r.useState)({read:!1,create:!1,update:!1,delete:!1,unknown:!0}),v=(0,r.useMemo)(()=>m(e),[e]),w=(0,r.useMemo)(()=>new Set(void 0===i?e.map(e=>e.name):i),[i,e]),C=e=>{if(d)return;let t=new Set(w);t.has(e)?t.delete(e):t.add(e),n(Array.from(t))};return 0===e.length?null:(0,t.jsx)("div",{className:"space-y-3",children:h.map(e=>{let r,i=v[e];if(0===i.length)return null;if(c){let e=c.toLowerCase();if(!i.some(t=>t.name.toLowerCase().includes(e)||(t.description??"").toLowerCase().includes(e)))return null}let m=g[e],h=(r=v[e]).length>0&&r.every(e=>w.has(e.name)),y=(e=>{let t=v[e];if(0===t.length)return!1;let r=t.filter(e=>w.has(e.name)).length;return r>0&&r{x(t=>({...t,[e]:!t[e]}))},children:[k?(0,t.jsx)(l.default,{className:"w-4 h-4 text-gray-500 shrink-0"}):(0,t.jsx)(o.ChevronDownIcon,{className:"w-4 h-4 text-gray-500 shrink-0"}),(0,t.jsx)("span",{className:"font-semibold text-gray-900 text-sm",children:m.label}),(0,t.jsx)("span",{className:`text-xs px-2 py-0.5 rounded-full ${p[m.risk]}`,children:"high"===m.risk?"High Risk":"medium"===m.risk?"Medium Risk":"low"===m.risk?"Safe":"Unclassified"}),(0,t.jsxs)("span",{className:"text-xs text-gray-500 ml-1",children:[i.filter(e=>w.has(e.name)).length,"/",i.length," allowed"]})]}),!d&&(0,t.jsxs)("div",{className:"flex items-center gap-2 ml-4",children:[(0,t.jsx)(s.Text,{className:"text-xs text-gray-500",children:h?"All on":y?"Partial":"All off"}),(0,t.jsx)(a.Checkbox,{checked:h,indeterminate:y,onChange:t=>((e,t)=>{if(d)return;let r=new Set(w);for(let a of v[e])t?r.add(a.name):r.delete(a.name);n(Array.from(r))})(e,t.target.checked),onClick:e=>e.stopPropagation()})]})]}),!k&&(0,t.jsx)("div",{className:"px-4 pt-2 pb-1 text-xs text-gray-500 bg-white border-b border-gray-100",children:m.description}),!k&&(0,t.jsx)("div",{className:"bg-white divide-y divide-gray-50",children:i.filter(e=>!c||e.name.toLowerCase().includes(c.toLowerCase())||(e.description??"").toLowerCase().includes(c.toLowerCase())).map(e=>{let r,o=(r=e.name,w.has(r));return(0,t.jsxs)("div",{className:`flex items-start gap-3 px-4 py-2.5 transition-colors hover:bg-gray-50 ${!d?"cursor-pointer":""} ${o?"":"opacity-60"}`,onClick:()=>C(e.name),children:[(0,t.jsx)(a.Checkbox,{checked:o,onChange:()=>C(e.name),disabled:d,onClick:e=>e.stopPropagation()}),(0,t.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,t.jsx)(s.Text,{className:"font-medium text-gray-900 text-sm",children:e.name}),e.description&&(0,t.jsx)(s.Text,{className:"text-xs text-gray-500 mt-0.5 leading-snug",children:e.description})]}),(0,t.jsx)("span",{className:`text-xs px-1.5 py-0.5 rounded shrink-0 ${o?"bg-green-100 text-green-700":"bg-gray-100 text-gray-500"}`,children:o?"on":"off"})]},e.name)})})]},e)})})}],531516)},962944,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M848 359.3H627.7L825.8 109c4.1-5.3.4-13-6.3-13H436c-2.8 0-5.5 1.5-6.9 4L170 547.5c-3.1 5.3.7 12 6.9 12h174.4l-89.4 357.6c-1.9 7.8 7.5 13.3 13.3 7.7L853.5 373c5.2-4.9 1.7-13.7-5.5-13.7zM378.2 732.5l60.3-241H281.1l189.6-327.4h224.6L487 427.4h211L378.2 732.5z"}}]},name:"thunderbolt",theme:"outlined"};var s=e.i(9583),o=r.forwardRef(function(e,o){return r.createElement(s.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["ThunderboltOutlined",0,o],962944)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/035i-tbvd3z7s.js b/litellm/proxy/_experimental/out/_next/static/chunks/035i-tbvd3z7s.js new file mode 100644 index 00000000000..7e8cf73121d --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/035i-tbvd3z7s.js @@ -0,0 +1,10 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,664307,e=>{"use strict";var t=e.i(843476),l=e.i(602869),s=e.i(266027),a=e.i(243652),r=e.i(135214);let i=(0,a.createQueryKeys)("credentials"),o=()=>{let{accessToken:e}=(0,r.default)();return(0,s.useQuery)({queryKey:i.list({}),queryFn:async()=>await (0,l.credentialListCall)(e),enabled:!!e})};var n=e.i(368670),d=e.i(625901),c=e.i(292639),m=e.i(954616),u=e.i(785242),h=e.i(152990),p=e.i(682830),x=e.i(271645),g=e.i(269200),f=e.i(427612),_=e.i(64848),j=e.i(942232),y=e.i(496020),b=e.i(977572),v=e.i(446891);function N({data:e=[],columns:l,isLoading:s=!1,sorting:a=[],onSortingChange:r,pagination:i,onPaginationChange:o,enablePagination:n=!1,onRowClick:d}){let[c]=x.default.useState("onChange"),[m,u]=x.default.useState({}),[w,C]=x.default.useState({}),k=(0,h.useReactTable)({data:e,columns:l,state:{sorting:a,columnSizing:m,columnVisibility:w,...n&&i?{pagination:i}:{}},columnResizeMode:c,onSortingChange:r,onColumnSizingChange:u,onColumnVisibilityChange:C,...n&&o?{onPaginationChange:o}:{},getCoreRowModel:(0,p.getCoreRowModel)(),...n?{getPaginationRowModel:(0,p.getPaginationRowModel)()}:{},enableSorting:!0,enableColumnResizing:!0,manualSorting:!0,defaultColumn:{minSize:40,maxSize:500}});return(0,t.jsx)("div",{className:"rounded-lg custom-border relative",children:(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsx)("div",{className:"relative min-w-full",children:(0,t.jsxs)(g.Table,{className:"[&_td]:py-2 [&_th]:py-2",style:{width:k.getTotalSize(),minWidth:"100%",tableLayout:"fixed"},children:[(0,t.jsx)(f.TableHead,{children:k.getHeaderGroups().map(e=>(0,t.jsx)(y.TableRow,{children:e.headers.map(e=>(0,t.jsxs)(_.TableHeaderCell,{className:`py-1 h-8 relative ${"actions"===e.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)] w-[120px] ml-8":""} ${e.column.columnDef.meta?.className||""}`,style:{width:"actions"===e.id?120:e.getSize(),position:"actions"===e.id?"sticky":"relative",right:"actions"===e.id?0:"auto"},children:[(0,t.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,t.jsx)("div",{className:"flex items-center",children:e.isPlaceholder?null:(0,h.flexRender)(e.column.columnDef.header,e.getContext())}),"actions"!==e.id&&e.column.getCanSort()&&r&&(0,t.jsx)(v.TableHeaderSortDropdown,{sortState:!1!==e.column.getIsSorted()&&e.column.getIsSorted(),onSortChange:t=>{!1===t?r([]):r([{id:e.column.id,desc:"desc"===t}])},columnId:e.column.id})]}),e.column.getCanResize()&&(0,t.jsx)("div",{onMouseDown:e.getResizeHandler(),onTouchStart:e.getResizeHandler(),className:`absolute right-0 top-0 h-full w-2 cursor-col-resize select-none touch-none ${e.column.getIsResizing()?"bg-blue-500":"hover:bg-blue-200"}`})]},e.id))},e.id))}),(0,t.jsx)(j.TableBody,{children:s?(0,t.jsx)(y.TableRow,{children:(0,t.jsx)(b.TableCell,{colSpan:l.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:"🚅 Loading models..."})})})}):k.getRowModel().rows.length>0?k.getRowModel().rows.map(e=>(0,t.jsx)(y.TableRow,{className:d?"cursor-pointer hover:bg-gray-50":"",onClick:()=>d?.(e.original),children:e.getVisibleCells().map(e=>(0,t.jsx)(b.TableCell,{className:`py-0.5 overflow-hidden ${"actions"===e.column.id?"sticky right-0 bg-white shadow-[-4px_0_8px_-6px_rgba(0,0,0,0.1)] w-[120px] ml-8":""} ${e.column.columnDef.meta?.className||""}`,style:{width:"actions"===e.column.id?120:e.column.getSize(),position:"actions"===e.column.id?"sticky":"relative",right:"actions"===e.column.id?0:"auto"},children:(0,h.flexRender)(e.column.columnDef.cell,e.getContext())},e.id))},e.id)):(0,t.jsx)(y.TableRow,{children:(0,t.jsx)(b.TableCell,{colSpan:l.length,className:"h-8 text-center",children:(0,t.jsx)("div",{className:"text-center text-gray-500",children:(0,t.jsx)("p",{children:"No models found"})})})})})]})})})})}var w=e.i(751904),C=e.i(827252),k=e.i(772345),S=e.i(68155),T=e.i(389083),I=e.i(994388),F=e.i(752978),P=e.i(312361),M=e.i(525720),A=e.i(282786),E=e.i(770914),L=e.i(790848),O=e.i(592968),R=e.i(898586),B=e.i(418371);let{Text:z,Title:q}=R.Typography,V=(0,t.jsxs)(E.Space,{direction:"vertical",size:12,children:[(0,t.jsx)(z,{strong:!0,style:{fontSize:13},children:"Credential types"}),(0,t.jsxs)(E.Space,{direction:"vertical",size:8,children:[(0,t.jsx)(M.Flex,{align:"center",gap:8,children:(0,t.jsxs)(E.Space,{direction:"vertical",children:[(0,t.jsxs)(M.Flex,{align:"center",gap:8,children:[(0,t.jsx)(k.SyncOutlined,{style:{color:"#1890ff"}}),(0,t.jsx)(q,{level:5,style:{margin:0,color:"#1890ff"},children:"Reusable"})]}),(0,t.jsx)(z,{type:"secondary",children:"Credentials saved in LiteLLM that can be added to models repeatedly."})]})}),(0,t.jsx)(P.Divider,{size:"small"}),(0,t.jsx)(M.Flex,{align:"center",gap:8,children:(0,t.jsxs)(E.Space,{direction:"vertical",size:8,children:[(0,t.jsxs)(M.Flex,{align:"center",gap:8,children:[(0,t.jsx)(w.EditOutlined,{style:{color:"#8c8c8c",fontSize:14,flexShrink:0}}),(0,t.jsx)(q,{level:5,style:{margin:0},children:"Manual"})]}),(0,t.jsx)(z,{type:"secondary",children:"Credentials added directly during model creation or defined in the config file."})]})})]})]}),D=e=>e?.model_info?.team_public_model_name?e.model_info.team_public_model_name:e?.model_name||"-";var H=e.i(127952),G=e.i(727749),U=e.i(313603),$=e.i(912598),K=e.i(350967),J=e.i(404206),W=e.i(906579),Q=e.i(464571),Y=e.i(199133),X=e.i(981339),Z=e.i(153472);let ee=async(e,t)=>{let s=(0,l.getProxyBaseUrl)(),a=s?`${s}/config/field/update`:"/config/field/update",r=await fetch(a,{method:"POST",headers:{[(0,l.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({field_name:"store_model_in_db",field_value:t.store_model_in_db,config_type:"general_settings"})});if(!r.ok){let e=await r.json().catch(()=>({}));throw Error(e?.error?.message||e?.message||e?.detail||"Failed to update model storage settings")}return await r.json()};var et=e.i(190702),el=e.i(808613),es=e.i(212931);let ea=({isVisible:e,onCancel:l,onSuccess:s})=>{let[a]=el.Form.useForm(),{mutateAsync:i,isPending:o}=(()=>{let{accessToken:e}=(0,r.default)();return(0,m.useMutation)({mutationFn:async t=>{if(!e)throw Error("Access token is required");return await ee(e,t)}})})(),{data:n,isLoading:d,refetch:c}=(0,Z.useProxyConfig)(Z.ConfigType.GENERAL_SETTINGS);(0,x.useEffect)(()=>{e&&c()},[e,c]);let u=(0,x.useMemo)(()=>{if(!n)return{store_model_in_db:!1};let e=n.find(e=>"store_model_in_db"===e.field_name);return{store_model_in_db:e?.field_value??!1}},[n]),h=async e=>{try{await i(e,{onSuccess:()=>{G.default.success("Model storage settings updated successfully"),c(),s?.()},onError:e=>{G.default.fromBackend("Failed to save model storage settings: "+(0,et.parseErrorMessage)(e))}})}catch(e){G.default.fromBackend("Failed to save model storage settings: "+(0,et.parseErrorMessage)(e))}},p=()=>{a.resetFields(),l()};return(0,t.jsx)(es.Modal,{title:(0,t.jsx)(R.Typography.Title,{level:5,children:"Model Settings"}),open:e,footer:(0,t.jsxs)(E.Space,{children:[(0,t.jsx)(Q.Button,{onClick:p,disabled:o||d,children:"Cancel"}),(0,t.jsx)(Q.Button,{type:"primary",loading:o,disabled:d,onClick:()=>a.submit(),children:o?"Saving...":"Save Settings"})]}),onCancel:p,children:(0,t.jsx)(el.Form,{form:a,layout:"horizontal",onFinish:h,initialValues:u,children:(0,t.jsx)(el.Form.Item,{label:"Store Model in DB",name:"store_model_in_db",tooltip:n?.find(e=>"store_model_in_db"===e.field_name)?.field_description||"If enabled, models and config are stored in and loaded from the database.",valuePropName:"checked",children:d?(0,t.jsx)(X.Skeleton.Input,{active:!0,block:!0}):(0,t.jsx)(L.Switch,{})})},n?JSON.stringify(u):"loading")})};var er=e.i(374009);let ei=(e,t)=>{if(!e?.data)return{data:[]};let l=JSON.parse(JSON.stringify(e.data));for(let e=0;e"model"!==e&&"api_base"!==e))),l[e].provider=o,l[e].input_cost=n,l[e].output_cost=d,l[e].litellm_model_name=a,null!=l[e].input_cost&&(l[e].input_cost=(1e6*Number(l[e].input_cost)).toFixed(2)),null!=l[e].output_cost&&(l[e].output_cost=(1e6*Number(l[e].output_cost)).toFixed(2)),l[e].max_tokens=c,l[e].max_input_tokens=m,l[e].api_base=s?.litellm_params?.api_base,l[e].cleanedLitellmParams=u}return{data:l}},{Text:eo}=R.Typography,en=({selectedModelGroup:e,setSelectedModelGroup:s,availableModelGroups:a,availableModelAccessGroups:i,setSelectedModelId:o,setSelectedTeamId:c})=>{let{data:m,isLoading:h}=(0,n.useModelCostMap)(),{accessToken:p,userId:g,userRole:f,premiumUser:_}=(0,r.default)(),{data:j,isLoading:y}=(0,u.useTeams)(),b=(0,$.useQueryClient)(),[v,P]=(0,x.useState)(""),[R,q]=(0,x.useState)(""),[Z,ee]=(0,x.useState)("current_team"),[et,el]=(0,x.useState)("personal"),[es,en]=(0,x.useState)(!1),[ed,ec]=(0,x.useState)(null),[em,eu]=(0,x.useState)(new Set),[eh,ep]=(0,x.useState)(1),[ex]=(0,x.useState)(50),[eg,ef]=(0,x.useState)({pageIndex:0,pageSize:50}),[e_,ej]=(0,x.useState)([]),[ey,eb]=(0,x.useState)(!1),ev=(0,x.useMemo)(()=>(0,er.default)(e=>{q(e),ep(1),ef(e=>({...e,pageIndex:0}))},200),[]);(0,x.useEffect)(()=>(ev(v),()=>{ev.cancel()}),[v,ev]);let eN="personal"===et?void 0:et.team_id,ew=(0,x.useMemo)(()=>{if(0===e_.length)return;let e=e_[0];return({input_cost:"costs",model_info_db_model:"status",model_info_created_by:"created_at",model_info_updated_at:"updated_at"})[e.id]||e.id},[e_]),eC=(0,x.useMemo)(()=>{if(0!==e_.length)return e_[0].desc?"desc":"asc"},[e_]),{data:ek,isLoading:eS,refetch:eT}=(0,d.useModelsInfo)(eh,ex,R||void 0,void 0,eN,ew,eC),eI=eS||h,eF=e=>null!=m&&"object"==typeof m&&e in m?m[e].litellm_provider:"openai",eP=(0,x.useMemo)(()=>ek?ei(ek,eF):{data:[]},[ek,m]),[eM,eA]=(0,x.useState)(null),[eE,eL]=(0,x.useState)(!1),eO=(0,x.useMemo)(()=>ek?{total_count:ek.total_count??0,current_page:ek.current_page??1,total_pages:ek.total_pages??1,size:ek.size??ex}:{total_count:0,current_page:1,total_pages:1,size:ex},[ek,ex]),eR=(0,x.useMemo)(()=>eP&&eP.data&&0!==eP.data.length?eP.data.filter(t=>{let l="all"===e||t.model_name===e||!e||"wildcard"===e&&t.model_name?.includes("*"),s="all"===ed||t.model_info.access_groups?.includes(ed)||!ed;return l&&s}):[],[eP,e,ed]);(0,x.useEffect)(()=>{ef(e=>({...e,pageIndex:0})),ep(1)},[e,ed]),(0,x.useEffect)(()=>{ep(1),ef(e=>({...e,pageIndex:0}))},[eN]),(0,x.useEffect)(()=>{ep(1),ef(e=>({...e,pageIndex:0}))},[e_]);let eB=(0,x.useMemo)(()=>eM&&eP?.data?eP.data.find(e=>e.model_info.id===eM):null,[eM,eP]),ez=async()=>{if(p&&eM)try{eL(!0),await (0,l.modelDeleteCall)(p,eM),G.default.success("Model deleted successfully"),b.invalidateQueries({queryKey:["models","list"]}),eT()}catch(e){console.error("Error deleting model:",e),G.default.fromBackend(e)}finally{eL(!1),eA(null)}},[eq,eV]=(0,x.useState)(null),eD=async(e,t)=>{if(p)try{eV(e),await (0,l.modelPatchUpdateCall)(p,{blocked:t},e),G.default.success(t?"Model paused":"Model resumed"),b.invalidateQueries({queryKey:["models","list"]})}catch(e){console.error("Error toggling model pause state:",e),G.default.fromBackend(e)}finally{eV(null)}};return(0,t.jsxs)(J.TabPanel,{children:[(0,t.jsx)(K.Grid,{children:(0,t.jsx)("div",{className:"flex flex-col space-y-4",children:(0,t.jsxs)("div",{className:"bg-white rounded-lg shadow-sm",children:[(0,t.jsxs)("div",{className:"border-b px-6 py-4 bg-gray-50",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between",children:[(0,t.jsxs)("div",{className:"flex items-center gap-4",children:[(0,t.jsx)(eo,{className:"text-lg font-semibold text-gray-900",children:"Current Team:"}),(0,t.jsx)("div",{className:"w-80",children:eI?(0,t.jsx)(X.Skeleton.Input,{active:!0,block:!0,size:"large"}):(0,t.jsx)(Y.Select,{style:{width:"100%"},size:"large",defaultValue:"personal",value:"personal"===et?"personal":et.team_id,onChange:e=>{if("personal"===e)el("personal"),ep(1),ef(e=>({...e,pageIndex:0}));else{let t=j?.find(t=>t.team_id===e);t&&(el(t),ep(1),ef(e=>({...e,pageIndex:0})))}},loading:y,options:[{value:"personal",label:(0,t.jsxs)(E.Space,{direction:"horizontal",align:"center",children:[(0,t.jsx)(W.Badge,{color:"blue",size:"small"}),(0,t.jsx)(eo,{style:{fontSize:16},children:"Personal"})]})},...j?.filter(e=>e.team_id).map(e=>({value:e.team_id,label:(0,t.jsxs)(E.Space,{direction:"horizontal",align:"center",children:[(0,t.jsx)(W.Badge,{color:"green",size:"small"}),(0,t.jsx)(eo,{ellipsis:!0,style:{fontSize:16},children:e.team_alias?e.team_alias:e.team_id})]})}))??[]]})})]}),(0,t.jsxs)("div",{className:"flex items-center gap-4",children:[(0,t.jsx)(eo,{className:"text-lg font-semibold text-gray-900",children:"View:"}),(0,t.jsx)("div",{className:"w-64",children:eI?(0,t.jsx)(X.Skeleton.Input,{active:!0,block:!0,size:"large"}):(0,t.jsx)(Y.Select,{style:{width:"100%"},size:"large",defaultValue:"current_team",value:Z,onChange:e=>ee(e),options:[{value:"current_team",label:(0,t.jsxs)(E.Space,{direction:"horizontal",align:"center",children:[(0,t.jsx)(W.Badge,{color:"purple",size:"small"}),(0,t.jsx)(eo,{style:{fontSize:16},children:"Current Team Models"})]})},{value:"all",label:(0,t.jsxs)(E.Space,{direction:"horizontal",align:"center",children:[(0,t.jsx)(W.Badge,{color:"gray",size:"small"}),(0,t.jsx)(eo,{style:{fontSize:16},children:"All Available Models"})]})}]})})]})]}),"current_team"===Z&&(0,t.jsxs)("div",{className:"flex items-start gap-2 mt-3",children:[(0,t.jsx)(C.InfoCircleOutlined,{className:"text-gray-400 mt-0.5 shrink-0 text-xs"}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"personal"===et?(0,t.jsxs)("span",{children:["To access these models: Create a Virtual Key without selecting a team on the"," ",(0,t.jsx)("a",{href:"/public?login=success&page=api-keys",className:"text-gray-600 hover:text-gray-800 underline",children:"Virtual Keys page"})]}):(0,t.jsxs)("span",{children:['To access these models: Create a Virtual Key and select Team as "',"string"!=typeof et?et.team_alias||et.team_id:"",'" on the'," ",(0,t.jsx)("a",{href:"/public?login=success&page=api-keys",className:"text-gray-600 hover:text-gray-800 underline",children:"Virtual Keys page"})]})})]})]}),(0,t.jsx)("div",{className:"border-b px-6 py-4",children:(0,t.jsxs)("div",{className:"flex flex-col space-y-4",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between gap-3",children:[(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-3",children:[(0,t.jsxs)("div",{className:"relative w-64",children:[(0,t.jsx)("input",{type:"text",placeholder:"Search model names...","data-testid":"model-search-input",className:"w-full px-3 py-2 pl-8 border rounded-md text-sm focus:outline-hidden focus:ring-2 focus:ring-blue-500 focus:border-blue-500",value:v,onChange:e=>P(e.target.value)}),(0,t.jsx)("svg",{className:"absolute left-2.5 top-2.5 h-4 w-4 text-gray-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})})]}),(0,t.jsxs)("button",{className:`px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2 ${es?"bg-gray-100":""}`,onClick:()=>en(!es),children:[(0,t.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"})}),"Filters"]}),(0,t.jsxs)("button",{className:"px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2",onClick:()=>{P(""),s("all"),ec(null),el("personal"),ee("current_team"),ep(1),ef({pageIndex:0,pageSize:50}),ej([])},children:[(0,t.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),"Reset Filters"]})]}),(0,t.jsx)(Q.Button,{icon:(0,t.jsx)(U.SettingOutlined,{}),onClick:()=>eb(!0),title:"Model Settings"})]}),es&&(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-3 mt-3",children:[(0,t.jsx)("div",{className:"w-64",children:(0,t.jsx)(Y.Select,{className:"w-full",value:e??"all",onChange:e=>s("all"===e?"all":e),placeholder:"Filter by Public Model Name",showSearch:!0,options:[{value:"all",label:"All Models"},{value:"wildcard",label:"Wildcard Models (*)"},...a.map((e,t)=>({value:e,label:e}))]})}),(0,t.jsx)("div",{className:"w-64",children:(0,t.jsx)(Y.Select,{className:"w-full",value:ed??"all",onChange:e=>ec("all"===e?null:e),placeholder:"Filter by Model Access Group",showSearch:!0,options:[{value:"all",label:"All Model Access Groups"},...i.map((e,t)=>({value:e,label:e}))]})})]}),(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[eI?(0,t.jsx)(X.Skeleton.Input,{active:!0,style:{width:184,height:20}}):(0,t.jsx)("span",{"data-testid":"models-results-count",className:"text-sm text-gray-700",children:eO.total_count>0?`Showing ${(eh-1)*ex+1} - ${Math.min(eh*ex,eO.total_count)} of ${eO.total_count} results`:"Showing 0 results"}),(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[eI?(0,t.jsx)(X.Skeleton.Button,{active:!0,style:{width:84,height:30}}):(0,t.jsx)("button",{onClick:()=>{ep(eh-1),ef(e=>({...e,pageIndex:0}))},disabled:1===eh,className:`px-3 py-1 text-sm border rounded-md ${1===eh?"bg-gray-100 text-gray-400 cursor-not-allowed":"hover:bg-gray-50"}`,children:"Previous"}),eI?(0,t.jsx)(X.Skeleton.Button,{active:!0,style:{width:56,height:30}}):(0,t.jsx)("button",{onClick:()=>{ep(eh+1),ef(e=>({...e,pageIndex:0}))},disabled:eh>=eO.total_pages,className:`px-3 py-1 text-sm border rounded-md ${eh>=eO.total_pages?"bg-gray-100 text-gray-400 cursor-not-allowed":"hover:bg-gray-50"}`,children:"Next"})]})]})]})}),(0,t.jsx)(N,{columns:[{header:()=>(0,t.jsx)("span",{className:"text-sm font-semibold",children:"Model ID"}),accessorKey:"model_info.id",enableSorting:!1,size:130,minSize:80,cell:({row:e})=>{let l=e.original;return(0,t.jsx)(O.Tooltip,{title:l.model_info.id,children:(0,t.jsx)(z,{ellipsis:!0,className:"text-blue-500 bg-blue-50 hover:bg-blue-100 text-xs cursor-pointer w-full block",style:{fontSize:14,padding:"1px 8px"},onClick:e=>{e.stopPropagation(),o(l.model_info.id)},children:l.model_info.id})})}},{header:()=>(0,t.jsx)("span",{className:"text-sm font-semibold",children:"Model Information"}),accessorKey:"model_name",size:250,minSize:120,cell:({row:e})=>{let l=e.original,s=D(e.original)||"-",a=(0,t.jsxs)(E.Space,{direction:"vertical",size:12,style:{minWidth:220},children:[(0,t.jsxs)(M.Flex,{align:"center",gap:8,children:[(0,t.jsx)(B.ProviderLogo,{provider:l.provider}),(0,t.jsx)(z,{type:"secondary",style:{fontSize:12},ellipsis:!0,children:l.provider||"Unknown provider"})]}),(0,t.jsxs)(E.Space,{direction:"vertical",size:6,children:[(0,t.jsxs)(E.Space,{direction:"vertical",size:2,style:{width:"100%"},children:[(0,t.jsx)(z,{type:"secondary",style:{fontSize:11},children:"Public Model Name"}),(0,t.jsx)(z,{strong:!0,style:{fontSize:13,maxWidth:480},ellipsis:!0,title:s,children:s})]}),(0,t.jsxs)(E.Space,{direction:"vertical",size:2,children:[(0,t.jsx)(z,{type:"secondary",style:{fontSize:11},children:"LiteLLM Model Name"}),(0,t.jsx)(z,{style:{fontSize:13},copyable:{text:l.litellm_model_name||"-"},ellipsis:!0,title:l.litellm_model_name||"-",children:l.litellm_model_name||"-"})]})]})]});return(0,t.jsx)(A.Popover,{content:a,placement:"right",arrow:{pointAtCenter:!0},styles:{root:{maxWidth:500}},children:(0,t.jsxs)("div",{className:"flex items-start space-x-2 min-w-0 w-full cursor-pointer",children:[(0,t.jsx)("div",{className:"shrink-0 mt-0.5",children:l.provider?(0,t.jsx)(B.ProviderLogo,{provider:l.provider}):(0,t.jsx)("div",{className:"w-4 h-4 rounded-full bg-gray-200 flex items-center justify-center text-xs",children:"-"})}),(0,t.jsxs)("div",{className:"flex flex-col min-w-0 flex-1",children:[(0,t.jsx)(z,{ellipsis:!0,className:"text-gray-900",style:{fontSize:12,fontWeight:500,lineHeight:"16px"},children:s}),(0,t.jsx)(z,{ellipsis:!0,type:"secondary",style:{fontSize:12,lineHeight:"16px",marginTop:2},children:l.litellm_model_name||"-"})]})]})})}},{header:()=>(0,t.jsxs)("span",{className:"flex items-center gap-1",children:[(0,t.jsx)("span",{className:"text-sm font-semibold",children:"Credentials"}),(0,t.jsx)(A.Popover,{content:V,placement:"bottom",arrow:{pointAtCenter:!0},children:(0,t.jsx)(C.InfoCircleOutlined,{className:"cursor-pointer text-gray-400 hover:text-gray-600",style:{fontSize:12}})})]}),accessorKey:"litellm_credential_name",enableSorting:!1,size:180,minSize:100,cell:({row:e})=>{let l=e.original,s=l.litellm_params?.litellm_credential_name,a=!!s;return(0,t.jsx)("div",{className:"flex items-center space-x-2 min-w-0 w-full",children:a?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(k.SyncOutlined,{className:"shrink-0",style:{color:"#1890ff",fontSize:14}}),(0,t.jsx)("span",{className:"text-xs truncate text-blue-600",title:s,children:s})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(w.EditOutlined,{className:"shrink-0",style:{color:"#8c8c8c",fontSize:14}}),(0,t.jsx)("span",{className:"text-xs text-gray-500",children:"Manual"})]})})}},{header:()=>(0,t.jsx)("span",{className:"text-sm font-semibold",children:"Created By"}),accessorKey:"model_info.created_by",sortingFn:"datetime",size:160,minSize:100,cell:({row:e})=>{let l=e.original,s=!l.model_info?.db_model,a=l.model_info.created_by,r=l.model_info.created_at?new Date(l.model_info.created_at).toLocaleDateString():null;return(0,t.jsxs)("div",{className:"flex flex-col min-w-0 w-full",children:[(0,t.jsx)("div",{className:"text-xs font-medium text-gray-900 truncate",title:s?"Defined in config":a||"Unknown",children:s?"Defined in config":a||"Unknown"}),(0,t.jsx)("div",{className:"text-xs text-gray-500 truncate mt-0.5",title:s?"Config file":r||"Unknown date",children:s?"-":r||"Unknown date"})]})}},{header:()=>(0,t.jsx)("span",{className:"text-sm font-semibold",children:"Updated At"}),accessorKey:"model_info.updated_at",sortingFn:"datetime",size:120,minSize:80,cell:({row:e})=>{let l=e.original;return(0,t.jsx)("span",{className:"text-xs",children:l.model_info.updated_at?new Date(l.model_info.updated_at).toLocaleDateString():"-"})}},{header:()=>(0,t.jsx)("span",{className:"text-sm font-semibold",children:"Costs"}),accessorKey:"input_cost",size:120,minSize:80,cell:({row:e})=>{let l=e.original,s=l.input_cost,a=l.output_cost;return null==s&&null==a?(0,t.jsx)("div",{className:"w-full",children:(0,t.jsx)("span",{className:"text-xs text-gray-400",children:"-"})}):(0,t.jsx)(O.Tooltip,{title:"Cost per 1M tokens",children:(0,t.jsxs)("div",{className:"flex flex-col min-w-0 w-full",children:[null!=s&&(0,t.jsxs)("div",{className:"text-xs font-medium text-gray-900 truncate",children:["In: $",s]}),null!=a&&(0,t.jsxs)("div",{className:"text-xs text-gray-500 truncate mt-0.5",children:["Out: $",a]})]})})}},{header:()=>(0,t.jsx)("span",{className:"text-sm font-semibold",children:"Team ID"}),accessorKey:"model_info.team_id",enableSorting:!1,size:130,minSize:80,cell:({row:e})=>{let l=e.original;return l.model_info.team_id?(0,t.jsx)("div",{className:"overflow-hidden w-full",children:(0,t.jsx)(O.Tooltip,{title:l.model_info.team_id,children:(0,t.jsxs)(I.Button,{size:"xs",variant:"light",className:"font-mono text-blue-500 bg-blue-50 hover:bg-blue-100 text-xs font-normal px-2 py-0.5 text-left overflow-hidden truncate w-full",onClick:e=>{e.stopPropagation(),c(l.model_info.team_id)},children:[l.model_info.team_id.slice(0,7),"..."]})})}):"-"}},{header:()=>(0,t.jsx)("span",{className:"text-sm font-semibold",children:"Model Access Group"}),accessorKey:"model_info.model_access_group",enableSorting:!1,size:180,minSize:100,cell:({row:e})=>{let l=e.original,s=l.model_info.access_groups;if(!s||0===s.length)return"-";let a=l.model_info.id,r=em.has(a),i=s.length>1;return(0,t.jsxs)("div",{className:"flex items-center gap-1 overflow-hidden w-full",children:[(0,t.jsx)(T.Badge,{size:"xs",color:"blue",className:"text-xs px-1.5 py-0.5 h-5 leading-tight shrink-0",children:s[0]}),(r||!i&&2===s.length)&&s.slice(1).map((e,l)=>(0,t.jsx)(T.Badge,{size:"xs",color:"blue",className:"text-xs px-1.5 py-0.5 h-5 leading-tight shrink-0",children:e},l+1)),i&&(0,t.jsx)("button",{onClick:e=>{let t;e.stopPropagation(),t=new Set(em),r?t.delete(a):t.add(a),eu(t)},className:"text-xs text-blue-600 hover:text-blue-800 px-1 py-0.5 rounded-sm hover:bg-blue-50 h-5 leading-tight shrink-0 whitespace-nowrap",children:r?"−":`+${s.length-1}`})]})}},{header:()=>(0,t.jsx)("span",{className:"text-sm font-semibold",children:"Status"}),accessorKey:"model_info.db_model",size:120,minSize:80,cell:({row:e})=>{let l=e.original;return(0,t.jsx)("div",{className:` + inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium + ${l.model_info.db_model?"bg-blue-50 text-blue-600":"bg-gray-100 text-gray-600"} + `,children:l.model_info.db_model?"DB Model":"Config Model"})}},{id:"actions",header:()=>(0,t.jsx)("span",{className:"text-sm font-semibold",children:"Actions"}),size:100,minSize:80,enableResizing:!1,cell:({row:e})=>{let l=e.original,s="Admin"===f||l.model_info?.created_by===g,a=!l.model_info?.db_model,r="Admin"===f,i=l.model_info?.blocked===!0,o=!a&&r&&!!eD,n=eq===l.model_info?.id;return(0,t.jsxs)("div",{className:"flex items-center justify-end gap-2 pr-4",children:[(0,t.jsx)(O.Tooltip,{title:a?"Config models cannot be paused from the dashboard. Pause is DB-backed.":r?i?"Resume model — restore normal routing.":"Pause model — stop routing requests until resumed.":"Only proxy admins can pause or resume a model.",children:(0,t.jsx)(L.Switch,{size:"small",checked:!i,disabled:!o||n,loading:n,"aria-label":i?"Resume model":"Pause model",onClick:(e,t)=>{t.stopPropagation()},onChange:e=>{let t=l.model_info?.id;o&&eD&&t&&eD(t,!e)}})}),a?(0,t.jsx)(O.Tooltip,{title:"Config model cannot be deleted on the dashboard. Please delete it from the config file.",children:(0,t.jsx)(F.Icon,{icon:S.TrashIcon,size:"sm",className:"opacity-50 cursor-not-allowed"})}):(0,t.jsx)(O.Tooltip,{title:"Delete model",children:(0,t.jsx)(F.Icon,{icon:S.TrashIcon,size:"sm",onClick:e=>{e.stopPropagation(),s&&eA&&eA(l.model_info.id)},className:s?"cursor-pointer hover:text-red-600":"opacity-50 cursor-not-allowed"})})]})}}],data:eR,isLoading:eS,sorting:e_,onSortingChange:ej,pagination:eg,onPaginationChange:ef,enablePagination:!0,onRowClick:e=>o(e.model_info.id)})]})})}),(0,t.jsx)(H.default,{isOpen:!!eM,title:"Delete Model",alertMessage:"This action cannot be undone.",message:"Are you sure you want to delete this model?",resourceInformationTitle:"Model Information",resourceInformation:eB?[{label:"Model Name",value:eB.model_name||"Not Set"},{label:"LiteLLM Model Name",value:eB.litellm_model_name||"Not Set"},{label:"Provider",value:eB.provider||"Not Set"},{label:"Created By",value:eB.model_info?.created_by||"Not Set"}]:[],onCancel:()=>eA(null),onOk:ez,confirmLoading:eE}),(0,t.jsx)(ea,{isVisible:ey,onCancel:()=>eb(!1),onSuccess:()=>eb(!1)})]})};var ed=e.i(206929),ec=e.i(35983),em=e.i(599724),eu=e.i(629569),eh=e.i(28651);let ep={"BadRequestError (400)":"BadRequestErrorRetries","AuthenticationError (401)":"AuthenticationErrorRetries","TimeoutError (408)":"TimeoutErrorRetries","RateLimitError (429)":"RateLimitErrorRetries","ContentPolicyViolationError (400)":"ContentPolicyViolationErrorRetries","InternalServerError (500)":"InternalServerErrorRetries"},ex=({selectedModelGroup:e,setSelectedModelGroup:l,availableModelGroups:s,globalRetryPolicy:a,setGlobalRetryPolicy:r,defaultRetry:i,modelGroupRetryPolicy:o,setModelGroupRetryPolicy:n,handleSaveRetrySettings:d,isSaving:c=!1})=>{let m="global"===e,u=(t,l)=>{n(s=>{let a={...s?.[e]??{}};return null==l?delete a[t]:a[t]=l,{...s??{},[e]:a}})};return(0,t.jsxs)(J.TabPanel,{children:[(0,t.jsx)("div",{className:"flex items-center gap-4 mb-6",children:(0,t.jsxs)("div",{className:"flex items-center",children:[(0,t.jsx)(em.Text,{children:"Retry Policy Scope:"}),(0,t.jsxs)(ed.Select,{className:"ml-2 w-48",value:m?"global":e||s[0],onValueChange:e=>l(e),children:[(0,t.jsx)(ec.SelectItem,{value:"global",children:"Global Default"}),s.map((e,l)=>(0,t.jsx)(ec.SelectItem,{value:e,children:e},l))]})]})}),m?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(eu.Title,{children:"Global Retry Policy"}),(0,t.jsx)(em.Text,{className:"mb-6",children:"Default retry settings applied to all model groups unless overridden"})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(eu.Title,{children:["Retry Policy for ",e]}),(0,t.jsx)(em.Text,{className:"mb-6",children:"Model-specific retry settings. Falls back to global defaults if not set."})]}),(0,t.jsx)("table",{children:(0,t.jsx)("tbody",{children:Object.entries(ep).map(([l,s],n)=>{let d=a?.[s]??i,c=m?void 0:o?.[e]?.[s],h=null!=c;return(0,t.jsxs)("tr",{className:"flex justify-between items-center mt-2",children:[(0,t.jsxs)("td",{children:[(0,t.jsx)(em.Text,{children:l}),!m&&(0,t.jsxs)(em.Text,{className:"text-xs text-gray-500 ml-2",children:["(Global: ",d,")"]})]}),(0,t.jsxs)("td",{className:"flex items-center gap-2",children:[(0,t.jsx)(eh.InputNumber,{className:"ml-5",value:m?d:h?c:null,placeholder:m?void 0:String(d),min:0,step:1,onChange:e=>m?void(null!=e&&r(t=>({...t??{},[s]:e}))):u(s,e)}),!m&&h&&(0,t.jsx)(I.Button,{variant:"light",size:"xs",onClick:()=>u(s,null),children:"Reset"})]})]},n)})})}),(0,t.jsx)(I.Button,{className:"mt-6 mr-8",onClick:d,loading:c,disabled:c,children:"Save"})]})};var eg=e.i(883552),ef=e.i(262218),e_=e.i(175712),ej=e.i(91979),ey=e.i(637235),eb=e.i(724154);e.i(247167);var ev=e.i(931067);let eN={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M811.4 418.7C765.6 297.9 648.9 212 512.2 212S258.8 297.8 213 418.6C127.3 441.1 64 519.1 64 612c0 110.5 89.5 200 199.9 200h496.2C870.5 812 960 722.5 960 612c0-92.7-63.1-170.7-148.6-193.3zm36.3 281a123.07 123.07 0 01-87.6 36.3H263.9c-33.1 0-64.2-12.9-87.6-36.3A123.3 123.3 0 01140 612c0-28 9.1-54.3 26.2-76.3a125.7 125.7 0 0166.1-43.7l37.9-9.9 13.9-36.6c8.6-22.8 20.6-44.1 35.7-63.4a245.6 245.6 0 0152.4-49.9c41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.2c19.9 14 37.5 30.8 52.4 49.9 15.1 19.3 27.1 40.7 35.7 63.4l13.8 36.5 37.8 10c54.3 14.5 92.1 63.8 92.1 120 0 33.1-12.9 64.3-36.3 87.7z"}}]},name:"cloud",theme:"outlined"};var ew=e.i(9583),eC=x.forwardRef(function(e,t){return x.createElement(ew.default,(0,ev.default)({},e,{ref:t,icon:eN}))}),ek=e.i(210612),eS=e.i(285027);let{Text:eT}=R.Typography,eI=({accessToken:e,onReloadSuccess:s,buttonText:a="Reload Price Data",showIcon:r=!0,size:i="middle",type:o="primary",className:n=""})=>{let[d,c]=(0,x.useState)(!1),[m,u]=(0,x.useState)(!1),[h,p]=(0,x.useState)(!1),[g,f]=(0,x.useState)(!1),[_,j]=(0,x.useState)(6),[y,b]=(0,x.useState)(null),[v,N]=(0,x.useState)(!1),[w,k]=(0,x.useState)(null),[S,T]=(0,x.useState)(!1);(0,x.useEffect)(()=>{I(),F();let e=setInterval(()=>{I(),F()},3e4);return()=>clearInterval(e)},[e]);let I=async()=>{if(e){N(!0);try{let t=await (0,l.getModelCostMapReloadStatus)(e);b(t)}catch(e){console.error("Failed to fetch reload status:",e),b({scheduled:!1,interval_hours:null,last_run:null,next_run:null})}finally{N(!1)}}},F=async()=>{if(e){T(!0);try{let t=await (0,l.getModelCostMapSource)(e);k(t)}catch(e){console.error("Failed to fetch cost map source info:",e)}finally{T(!1)}}},M=async()=>{if(!e)return void G.default.fromBackend("No access token available");c(!0);try{let t=await (0,l.reloadModelCostMap)(e);"success"===t.status?(G.default.success(`Price data reloaded successfully! ${t.models_count||0} models updated.`),s?.(),await I(),await F()):G.default.fromBackend("Failed to reload price data")}catch(e){console.error("Error reloading price data:",e),G.default.fromBackend("Failed to reload price data. Please try again.")}finally{c(!1)}},A=async()=>{if(!e)return void G.default.fromBackend("No access token available");if(_<=0)return void G.default.fromBackend("Hours must be greater than 0");u(!0);try{let t=await (0,l.scheduleModelCostMapReload)(e,_);"success"===t.status?(G.default.success(`Periodic reload scheduled for every ${_} hours`),f(!1),await I()):G.default.fromBackend("Failed to schedule periodic reload")}catch(e){console.error("Error scheduling reload:",e),G.default.fromBackend("Failed to schedule periodic reload. Please try again.")}finally{u(!1)}},L=async()=>{if(!e)return void G.default.fromBackend("No access token available");p(!0);try{let t=await (0,l.cancelModelCostMapReload)(e);"success"===t.status?(G.default.success("Periodic reload cancelled successfully"),await I()):G.default.fromBackend("Failed to cancel periodic reload")}catch(e){console.error("Error cancelling reload:",e),G.default.fromBackend("Failed to cancel periodic reload. Please try again.")}finally{p(!1)}},R=e=>{if(!e)return"Never";try{return new Date(e).toLocaleString()}catch{return e}};return(0,t.jsxs)("div",{className:n,children:[(0,t.jsxs)(E.Space,{direction:"horizontal",size:"middle",style:{marginBottom:16},children:[(0,t.jsx)(eg.Popconfirm,{title:"Hard Refresh Price Data",description:"This will immediately fetch the latest pricing information from the remote source. Continue?",onConfirm:M,okText:"Yes",cancelText:"No",okButtonProps:{style:{backgroundColor:"#6366f1",borderColor:"#6366f1",color:"white",fontWeight:"500",borderRadius:"0.375rem",padding:"0.375rem 0.75rem",height:"auto",fontSize:"0.875rem",lineHeight:"1.25rem",transition:"all 0.2s ease-in-out"},onMouseEnter:e=>{e.currentTarget.style.backgroundColor="#4f46e5"},onMouseLeave:e=>{e.currentTarget.style.backgroundColor="#6366f1"}},children:(0,t.jsx)(Q.Button,{type:o,size:i,loading:d,icon:r?(0,t.jsx)(ej.ReloadOutlined,{}):void 0,style:{backgroundColor:"#6366f1",borderColor:"#6366f1",color:"white",fontWeight:"500",borderRadius:"0.375rem",padding:"0.375rem 0.75rem",height:"auto",fontSize:"0.875rem",lineHeight:"1.25rem",transition:"all 0.2s ease-in-out"},onMouseEnter:e=>{e.currentTarget.style.backgroundColor="#4f46e5"},onMouseLeave:e=>{e.currentTarget.style.backgroundColor="#6366f1"},children:a})}),y?.scheduled?(0,t.jsx)(Q.Button,{type:"default",size:i,danger:!0,icon:(0,t.jsx)(eb.StopOutlined,{}),loading:h,onClick:L,style:{borderColor:"#ff4d4f",color:"#ff4d4f",fontWeight:"500",borderRadius:"0.375rem",padding:"0.375rem 0.75rem",height:"auto",fontSize:"0.875rem",lineHeight:"1.25rem"},children:"Cancel Periodic Reload"}):(0,t.jsx)(Q.Button,{type:"default",size:i,icon:(0,t.jsx)(ey.ClockCircleOutlined,{}),onClick:()=>f(!0),style:{borderColor:"#d9d9d9",color:"#6366f1",fontWeight:"500",borderRadius:"0.375rem",padding:"0.375rem 0.75rem",height:"auto",fontSize:"0.875rem",lineHeight:"1.25rem"},children:"Set Up Periodic Reload"})]}),w&&(0,t.jsx)(e_.Card,{size:"small",style:{backgroundColor:"remote"===w.source?"#f0f7ff":"#fff8f0",border:`1px solid ${"remote"===w.source?"#bae0ff":"#ffd591"}`,borderRadius:8,marginBottom:12},children:(0,t.jsxs)(E.Space,{direction:"vertical",size:"small",style:{width:"100%"},children:[(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:8},children:["remote"===w.source?(0,t.jsx)(eC,{style:{color:"#1677ff",fontSize:16}}):(0,t.jsx)(ek.DatabaseOutlined,{style:{color:"#fa8c16",fontSize:16}}),(0,t.jsx)(eT,{strong:!0,style:{fontSize:"13px"},children:"Pricing Data Source"}),(0,t.jsx)(ef.Tag,{color:"remote"===w.source?"blue":"orange",style:{marginLeft:"auto",fontWeight:600,textTransform:"uppercase",fontSize:"11px"},children:"remote"===w.source?"Remote":"Local"})]}),(0,t.jsx)(P.Divider,{style:{margin:"6px 0"}}),(0,t.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[(0,t.jsx)(eT,{type:"secondary",style:{fontSize:"12px"},children:"Models loaded:"}),(0,t.jsx)(eT,{strong:!0,style:{fontSize:"12px"},children:w.model_count.toLocaleString()})]}),w.url&&(0,t.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:8},children:[(0,t.jsx)(eT,{type:"secondary",style:{fontSize:"12px",whiteSpace:"nowrap"},children:"remote"===w.source?"Loaded from:":"Attempted URL:"}),(0,t.jsx)(O.Tooltip,{title:w.url,children:(0,t.jsx)(eT,{style:{fontSize:"11px",maxWidth:240,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"block",color:"#1677ff",cursor:"default"},children:w.url})})]}),w.is_env_forced&&(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:6,marginTop:2},children:[(0,t.jsx)(C.InfoCircleOutlined,{style:{color:"#fa8c16",fontSize:12}}),(0,t.jsxs)(eT,{type:"secondary",style:{fontSize:"11px"},children:["Local mode forced via ",(0,t.jsx)("code",{children:"LITELLM_LOCAL_MODEL_COST_MAP=True"})]})]}),w.fallback_reason&&(0,t.jsxs)("div",{style:{display:"flex",alignItems:"flex-start",gap:6,backgroundColor:"#fff7e6",border:"1px solid #ffd591",borderRadius:4,padding:"4px 8px",marginTop:2},children:[(0,t.jsx)(eS.WarningOutlined,{style:{color:"#fa8c16",fontSize:12,marginTop:2}}),(0,t.jsxs)(eT,{style:{fontSize:"11px",color:"#614700"},children:["Fell back to local: ",w.fallback_reason]})]})]})}),y&&(0,t.jsx)(e_.Card,{size:"small",style:{backgroundColor:"#f8f9fa",border:"1px solid #e9ecef",borderRadius:8},children:(0,t.jsxs)(E.Space,{direction:"vertical",size:"small",style:{width:"100%"},children:[y.scheduled?(0,t.jsx)("div",{children:(0,t.jsxs)(ef.Tag,{color:"green",icon:(0,t.jsx)(ey.ClockCircleOutlined,{}),children:["Scheduled every ",y.interval_hours," hours"]})}):(0,t.jsx)(eT,{type:"secondary",children:"No periodic reload scheduled"}),(0,t.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[(0,t.jsx)(eT,{type:"secondary",style:{fontSize:"12px"},children:"Last run:"}),(0,t.jsx)(eT,{style:{fontSize:"12px"},children:R(y.last_run)})]}),y.scheduled&&(0,t.jsxs)(t.Fragment,{children:[y.next_run&&(0,t.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[(0,t.jsx)(eT,{type:"secondary",style:{fontSize:"12px"},children:"Next run:"}),(0,t.jsx)(eT,{style:{fontSize:"12px"},children:R(y.next_run)})]}),(0,t.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[(0,t.jsx)(eT,{type:"secondary",style:{fontSize:"12px"},children:"Status:"}),(0,t.jsx)(ef.Tag,{color:y?.scheduled?y.last_run?"success":"processing":"default",children:y?.scheduled?y.last_run?"Active":"Ready":"Not scheduled"})]})]})]})}),(0,t.jsxs)(es.Modal,{title:"Set Up Periodic Reload",open:g,onOk:A,onCancel:()=>f(!1),confirmLoading:m,okText:"Schedule",cancelText:"Cancel",okButtonProps:{style:{backgroundColor:"#6366f1",borderColor:"#6366f1",color:"white"}},children:[(0,t.jsx)("div",{style:{marginBottom:16},children:(0,t.jsx)(eT,{children:"Set up automatic reload of price data every:"})}),(0,t.jsx)("div",{style:{marginBottom:16},children:(0,t.jsx)(eh.InputNumber,{min:1,max:168,value:_,onChange:e=>j(e||6),addonAfter:"hours",style:{width:"100%"}})}),(0,t.jsx)("div",{children:(0,t.jsxs)(eT,{type:"secondary",children:["This will automatically fetch the latest pricing data from the remote source every ",_," hours."]})})]})]})},eF=()=>{let{accessToken:e}=(0,r.default)(),{refetch:l}=(0,n.useModelCostMap)();return(0,t.jsx)(J.TabPanel,{children:(0,t.jsxs)("div",{className:"p-6",children:[(0,t.jsxs)("div",{className:"mb-6",children:[(0,t.jsx)(eu.Title,{children:"Price Data Management"}),(0,t.jsx)(em.Text,{className:"text-tremor-content",children:"Manage model pricing data and configure automatic reload schedules"})]}),(0,t.jsx)(eI,{accessToken:e,onReloadSuccess:()=>{l()},buttonText:"Reload Price Data",size:"middle",type:"primary",className:"w-full"})]})})};var eP=e.i(916925);let eM=async(e,t,l)=>{try{let t=e.model_mappings||[];if("model_mappings"in e&&delete e.model_mappings,e.model&&e.model.includes("all-wildcard")){let l=e.custom_llm_provider,s=(eP.provider_map[l]??l.toLowerCase())+"/*";e.model_name=s,t.push({public_name:s,litellm_model:s}),e.model=s}let l=[];for(let s of t){let t={},a={},r=s.public_name;for(let[l,r]of(t.model=s.litellm_model,void 0!==e.input_cost_per_token&&null!==e.input_cost_per_token&&""!==e.input_cost_per_token&&(e.input_cost_per_token=Number(e.input_cost_per_token)/1e6),void 0!==e.output_cost_per_token&&null!==e.output_cost_per_token&&""!==e.output_cost_per_token&&(e.output_cost_per_token=Number(e.output_cost_per_token)/1e6),void 0!==e.cache_read_input_token_cost&&null!==e.cache_read_input_token_cost&&""!==e.cache_read_input_token_cost?e.cache_read_input_token_cost=Number(e.cache_read_input_token_cost)/1e6:void 0!==e.input_cost_per_token&&null!==e.input_cost_per_token&&""!==e.input_cost_per_token?e.cache_read_input_token_cost=Number(e.input_cost_per_token):delete e.cache_read_input_token_cost,void 0!==e.cache_creation_input_token_cost&&null!==e.cache_creation_input_token_cost&&""!==e.cache_creation_input_token_cost?e.cache_creation_input_token_cost=Number(e.cache_creation_input_token_cost)/1e6:delete e.cache_creation_input_token_cost,t.model=s.litellm_model,Object.entries(e)))if(""!==r&&"custom_pricing"!==l&&"pricing_model"!==l&&"cache_control"!==l)if("model_name"==l)t.model=r;else if("custom_llm_provider"==l)t.custom_llm_provider=eP.provider_map[r]??r.toLowerCase();else if("model"==l)continue;else if("base_model"===l)a[l]=r;else if("team_id"===l)a.team_id=r;else if("model_access_group"===l)a.access_groups=r;else if("mode"==l)a.mode=r,delete t.mode;else if("custom_model_name"===l)t.model=r;else if("litellm_extra_params"==l){let e={};if(r&&void 0!=r){try{e=JSON.parse(r),"litellm_credential_name"in e&&delete e.litellm_credential_name}catch(e){throw G.default.fromBackend("Failed to parse LiteLLM Extra Params: "+e),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,s]of Object.entries(e))t[l]=s}}else if("model_info_params"==l){let e={};if(r&&void 0!=r){try{e=JSON.parse(r)}catch(e){throw G.default.fromBackend("Failed to parse LiteLLM Extra Params: "+e),Error("Failed to parse litellm_extra_params: "+e)}for(let[t,l]of Object.entries(e))a[t]=l}}else if("input_cost_per_token"===l||"output_cost_per_token"===l||"input_cost_per_second"===l||"cache_read_input_token_cost"===l||"cache_creation_input_token_cost"===l){null!=r&&""!==r&&(t[l]=Number(r));continue}else t[l]=r;l.push({litellmParamsObj:t,modelInfoObj:a,modelName:r})}return l}catch(e){G.default.fromBackend("Failed to create model: "+e)}},eA=async(e,t,s,a)=>{try{let r=await eM(e,t,s);if(!r||0===r.length)return;for(let e of r){let{litellmParamsObj:s,modelInfoObj:a,modelName:r}=e,i={model_name:r,litellm_params:s,model_info:a};await (0,l.modelCreateCall)(t,i)}a&&a(),s.resetFields()}catch(e){G.default.fromBackend("Failed to add model: "+e)}};var eE=e.i(591935),eL=e.i(304967),eO=e.i(779241);let eR=(0,a.createQueryKeys)("providerFields"),eB=()=>(0,s.useQuery)({queryKey:eR.list({}),queryFn:async()=>await (0,l.getProviderCreateMetadata)(),staleTime:864e5,gcTime:864e5});var ez=e.i(519756),eq=e.i(178654),eV=e.i(311451),eD=e.i(621192),eH=e.i(515831);let{Link:eG}=R.Typography,eU=e=>{let t="password"===e.field_type?"password":"select"===e.field_type?"select":"upload"===e.field_type?"upload":"textarea"===e.field_type?"textarea":"text";return{key:e.key,label:e.label,placeholder:e.placeholder??void 0,tooltip:e.tooltip??void 0,required:e.required??!1,type:t,options:e.options??void 0,defaultValue:e.default_value??void 0}},e$={},eK=({selectedProvider:e,uploadProps:l})=>{let s=eP.Providers[e],a=el.Form.useFormInstance(),{data:r,isLoading:i,error:o}=eB(),n=x.default.useMemo(()=>{if(!r)return null;let e={};return r.forEach(t=>{let l=t.provider_display_name,s=t.credential_fields.map(eU);e[l]=s,t.provider&&(e[t.provider]=s),t.litellm_provider&&(e[t.litellm_provider]=s)}),e},[r]);x.default.useEffect(()=>{n&&Object.assign(e$,n)},[n]);let d=x.default.useMemo(()=>{let t=e$[s]??e$[e];if(t)return t;if(!r)return[];let l=r.find(t=>t.provider_display_name===s||t.provider===e||t.litellm_provider===e);if(!l)return[];let a=l.credential_fields.map(eU);return e$[l.provider_display_name]=a,l.provider&&(e$[l.provider]=a),l.litellm_provider&&(e$[l.litellm_provider]=a),a},[s,e,r]),c=x.default.useMemo(()=>d.some(e=>"api_version"===e.key),[d]),m=x.default.useRef(null),u=x.default.useCallback(e=>{if(!c)return;let t=(e=>{let t=e.indexOf("?");if(-1===t)return null;let l=new URLSearchParams(e.slice(t+1).split("#")[0]);return l.get("api_version")||l.get("api-version")})(e.target.value);if(t){m.current=t,a.setFieldsValue({api_version:t});return}a.getFieldValue("api_version")===m.current&&a.setFieldsValue({api_version:""}),m.current=null},[a,c]),h={name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let t=new FileReader;t.onload=e=>{if(e.target){let t=e.target.result;a.setFieldsValue({vertex_credentials:t})}},t.readAsText(e)}return!1}};return(0,t.jsxs)(t.Fragment,{children:[i&&0===d.length&&(0,t.jsx)(eD.Row,{children:(0,t.jsx)(eq.Col,{span:24,children:(0,t.jsx)(em.Text,{className:"mb-2",children:"Loading provider fields..."})})}),o&&0===d.length&&(0,t.jsx)(eD.Row,{children:(0,t.jsx)(eq.Col,{span:24,children:(0,t.jsx)(em.Text,{className:"mb-2 text-red-500",children:o instanceof Error?o.message:"Failed to load provider credential fields"})})}),d.map(e=>(0,t.jsxs)(x.default.Fragment,{children:[(0,t.jsx)(el.Form.Item,{label:e.label,name:e.key,rules:e.required?[{required:!0,message:"Required"}]:void 0,tooltip:e.tooltip,className:"vertex_credentials"===e.key?"mb-0":void 0,children:"select"===e.type?(0,t.jsx)(Y.Select,{placeholder:e.placeholder,defaultValue:e.defaultValue,children:e.options?.map(e=>(0,t.jsx)(Y.Select.Option,{value:e,children:e},e))}):"upload"===e.type?(0,t.jsx)(eH.Upload,{...h,onChange:e=>{l?.onChange&&l.onChange(e)},children:(0,t.jsx)(Q.Button,{icon:(0,t.jsx)(ez.UploadOutlined,{}),children:"Click to Upload"})}):"textarea"===e.type?(0,t.jsx)(eV.Input.TextArea,{placeholder:e.placeholder,defaultValue:e.defaultValue,rows:6,style:{fontFamily:"monospace",fontSize:"12px"}}):(0,t.jsx)(eO.TextInput,{placeholder:e.placeholder,type:"password"===e.type?"password":"text",defaultValue:e.defaultValue,onChange:"api_base"===e.key?u:void 0})}),"vertex_credentials"===e.key&&(0,t.jsx)(eD.Row,{children:(0,t.jsx)(eq.Col,{children:(0,t.jsx)(em.Text,{className:"mb-3 mt-1",children:"Give a gcp service account(.json file)"})})}),"base_model"===e.key&&(0,t.jsxs)(eD.Row,{children:[(0,t.jsx)(eq.Col,{span:10}),(0,t.jsx)(eq.Col,{span:10,children:(0,t.jsxs)(em.Text,{className:"mb-2",children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from"," ",(0,t.jsx)(eG,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})})]})]},e.key))]})};var eJ=e.i(555987);function eW(e,t,l){let s=e.getFieldValue("credential_name");e.resetFields(),void 0!==s&&e.setFieldValue("credential_name",s),l(t),e.setFieldValue("custom_llm_provider",t)}let{Link:eQ}=R.Typography,eY=({open:e,onCancel:l,onAddCredential:s,uploadProps:a})=>{let[r]=el.Form.useForm(),[i,o]=(0,x.useState)(eP.Providers.OpenAI);return(0,t.jsx)(es.Modal,{title:"Add New Credential",open:e,onCancel:()=>{l(),r.resetFields()},footer:null,width:600,children:(0,t.jsxs)(el.Form,{form:r,onFinish:e=>{s(Object.entries(e).reduce((e,[t,l])=>(""!==l&&null!=l&&(e[t]=l),e),{})),r.resetFields()},layout:"vertical",children:[(0,t.jsx)(el.Form.Item,{label:"Credential Name:",name:"credential_name",rules:[{required:!0,message:"Credential name is required"}],children:(0,t.jsx)(eO.TextInput,{placeholder:"Enter a friendly name for these credentials"})}),(0,t.jsx)(el.Form.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"Helper to auto-populate provider specific fields",children:(0,t.jsx)(Y.Select,{showSearch:!0,onChange:e=>{eW(r,e,o)},children:Object.entries(eP.Providers).map(([e,l])=>(0,t.jsx)(Y.Select.Option,{value:e,children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("img",{src:(0,eJ.resolveLogoSrc)(eP.providerLogoMap[l]),alt:`${e} logo`,className:"w-5 h-5",onError:e=>{let t=e.target,s=t.parentElement;if(s){let e=document.createElement("div");e.className="w-5 h-5 rounded-full bg-gray-200 flex items-center justify-center text-xs",e.textContent=l.charAt(0),s.replaceChild(e,t)}}}),(0,t.jsx)("span",{children:l})]})},e))})}),(0,t.jsx)(eK,{selectedProvider:i,uploadProps:a}),(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsx)(O.Tooltip,{title:"Get help on our github",children:(0,t.jsx)(eQ,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})}),(0,t.jsxs)("div",{children:[(0,t.jsx)(Q.Button,{onClick:()=>{l(),r.resetFields()},style:{marginRight:10},children:"Cancel"}),(0,t.jsx)(Q.Button,{htmlType:"submit",children:"Add Credential"})]})]})]})})},{Link:eX}=R.Typography;function eZ({open:e,onCancel:l,onUpdateCredential:s,uploadProps:a,existingCredential:r}){let[i]=el.Form.useForm(),[o,n]=(0,x.useState)(eP.Providers.Anthropic);return(0,x.useEffect)(()=>{if(r){let e=Object.entries(r.credential_values||{}).reduce((e,[t,l])=>(e[t]=l??null,e),{});i.setFieldsValue({credential_name:r.credential_name,custom_llm_provider:r.credential_info.custom_llm_provider,...e}),n(r.credential_info.custom_llm_provider)}},[r]),(0,t.jsx)(es.Modal,{title:"Edit Credential",open:e,onCancel:()=>{l(),i.resetFields()},footer:null,width:600,destroyOnHidden:!0,children:(0,t.jsxs)(el.Form,{form:i,onFinish:e=>{s(Object.entries(e).reduce((e,[t,l])=>(""!==l&&null!=l&&(e[t]=l),e),{})),i.resetFields()},layout:"vertical",children:[(0,t.jsx)(el.Form.Item,{label:"Credential Name:",name:"credential_name",rules:[{required:!0,message:"Credential name is required"}],initialValue:r?.credential_name,children:(0,t.jsx)(eO.TextInput,{placeholder:"Enter a friendly name for these credentials",disabled:!!r?.credential_name})}),(0,t.jsx)(el.Form.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"Helper to auto-populate provider specific fields",children:(0,t.jsx)(Y.Select,{showSearch:!0,onChange:e=>{eW(i,e,n)},children:Object.entries(eP.Providers).map(([e,l])=>(0,t.jsx)(Y.Select.Option,{value:e,children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("img",{src:(0,eJ.resolveLogoSrc)(eP.providerLogoMap[l]),alt:`${e} logo`,className:"w-5 h-5",onError:e=>{let t=e.target,s=t.parentElement;if(s){let e=document.createElement("div");e.className="w-5 h-5 rounded-full bg-gray-200 flex items-center justify-center text-xs",e.textContent=l.charAt(0),s.replaceChild(e,t)}}}),(0,t.jsx)("span",{children:l})]})},e))})}),(0,t.jsx)(eK,{selectedProvider:o,uploadProps:a}),(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsx)(O.Tooltip,{title:"Get help on our github",children:(0,t.jsx)(eX,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})}),(0,t.jsxs)("div",{children:[(0,t.jsx)(Q.Button,{onClick:()=>{l(),i.resetFields()},style:{marginRight:10},children:"Cancel"}),(0,t.jsx)(Q.Button,{htmlType:"submit",children:"Update Credential"})]})]})]})})}var e0=e.i(708347);let e1=({uploadProps:e})=>{let{accessToken:s,userRole:a}=(0,r.default)(),i=(0,e0.isProxyAdminRole)(a??""),{data:n,refetch:d}=o(),c=n?.credentials||[],[m,u]=(0,x.useState)(!1),[h,p]=(0,x.useState)(!1),[v,N]=(0,x.useState)(null),[w,C]=(0,x.useState)(null),[k,F]=(0,x.useState)(!1),[P,M]=(0,x.useState)(!1),[A]=el.Form.useForm(),E=["credential_name","custom_llm_provider"],L=async e=>{if(!s)return;let t=Object.entries(e).filter(([e])=>!E.includes(e)).reduce((e,[t,l])=>({...e,[t]:l}),{}),a={credential_name:e.credential_name,credential_values:t,credential_info:{custom_llm_provider:e.custom_llm_provider}};await (0,l.credentialUpdateCall)(s,e.credential_name,a),G.default.success("Credential updated successfully"),p(!1),await d()},O=async e=>{if(!s)return;let t=Object.entries(e).filter(([e])=>!E.includes(e)).reduce((e,[t,l])=>({...e,[t]:l}),{}),a={credential_name:e.credential_name,credential_values:t,credential_info:{custom_llm_provider:e.custom_llm_provider}};await (0,l.credentialCreateCall)(s,a),G.default.success("Credential added successfully"),u(!1),await d()},R=async()=>{if(s&&w){M(!0);try{await (0,l.credentialDeleteCall)(s,w.credential_name),G.default.success("Credential deleted successfully"),await d()}catch(e){G.default.error("Failed to delete credential")}finally{C(null),F(!1),M(!1)}}};return(0,t.jsxs)("div",{className:"w-full mx-auto flex-auto overflow-y-auto p-2",children:[i&&(0,t.jsx)(I.Button,{onClick:()=>u(!0),children:"Add Credential"}),(0,t.jsx)("div",{className:"flex justify-between items-center mt-4 mb-4",children:(0,t.jsx)(em.Text,{children:"Configured credentials for different AI providers. Add and manage your API credentials."})}),(0,t.jsx)(eL.Card,{children:(0,t.jsxs)(g.Table,{children:[(0,t.jsx)(f.TableHead,{children:(0,t.jsxs)(y.TableRow,{children:[(0,t.jsx)(_.TableHeaderCell,{children:"Credential Name"}),(0,t.jsx)(_.TableHeaderCell,{children:"Provider"}),(0,t.jsx)(_.TableHeaderCell,{children:"Actions"})]})}),(0,t.jsx)(j.TableBody,{children:c&&0!==c.length?c.map((e,l)=>{var s;let a,r;return(0,t.jsxs)(y.TableRow,{children:[(0,t.jsx)(b.TableCell,{children:e.credential_name}),(0,t.jsx)(b.TableCell,{children:(s=e.credential_info?.custom_llm_provider||"-",r=(a={openai:"blue",azure:"indigo",anthropic:"purple",default:"gray"})[s.toLowerCase()]||a.default,(0,t.jsx)(T.Badge,{color:r,size:"xs",children:s}))}),(0,t.jsx)(b.TableCell,{children:i?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(I.Button,{icon:eE.PencilAltIcon,variant:"light",size:"sm",onClick:()=>{N(e),p(!0)}}),(0,t.jsx)(I.Button,{icon:S.TrashIcon,variant:"light",size:"sm",onClick:()=>{C(e),F(!0)},className:"ml-2"})]}):null})]},l)}):(0,t.jsx)(y.TableRow,{children:(0,t.jsx)(b.TableCell,{colSpan:4,className:"text-center py-4 text-gray-500",children:"No credentials configured"})})})]})}),m&&(0,t.jsx)(eY,{onAddCredential:O,open:m,onCancel:()=>u(!1),uploadProps:e}),h&&(0,t.jsx)(eZ,{open:h,existingCredential:v,onUpdateCredential:L,uploadProps:e,onCancel:()=>p(!1)}),(0,t.jsx)(H.default,{isOpen:k,onCancel:()=>{C(null),F(!1)},onOk:R,title:"Delete Credential?",message:"Are you sure you want to delete this credential? This action cannot be undone and may break existing integrations.",resourceInformationTitle:"Credential Information",resourceInformation:[{label:"Credential Name",value:w?.credential_name},{label:"Provider",value:w?.credential_info?.custom_llm_provider||"-"}],confirmLoading:P,requiredConfirmation:w?.credential_name})]})};var e2=e.i(278587),e4=e.i(309426),e5=e.i(197647),e6=e.i(653824),e3=e.i(881073),e8=e.i(723731),e7=e.i(475647),e9=e.i(91739),te=e.i(437902),tt=e.i(166406);let{Text:tl}=R.Typography,ts=({formValues:e,accessToken:s,testMode:a,modelName:r="this model",onClose:i,onTestComplete:o})=>{var n,d,c;let m,u,[h,p]=x.default.useState(null),[g,f]=x.default.useState(null),[_,j]=x.default.useState(null),[y,b]=x.default.useState(!0),[v,N]=x.default.useState(!1),[w,k]=x.default.useState(!1),S=async()=>{b(!0),k(!1),p(null),f(null),j(null),N(!1),await new Promise(e=>setTimeout(e,100));try{let t=await eM(e,s,null);if(!t){p("Failed to prepare model data. Please check your form inputs."),N(!1),b(!1);return}let{litellmParamsObj:a,modelInfoObj:r,modelName:i}=t[0],o=await (0,l.testConnectionRequest)(s,a,r,r?.mode);if("success"===o.status)G.default.success("Connection test successful!"),p(null),N(!0);else{let e=o.result?.error||o.message||"Unknown error";p(e),f(a),j(o.result?.raw_request_typed_dict),N(!1)}}catch(e){console.error("Test connection error:",e),p(e instanceof Error?e.message:String(e)),N(!1)}finally{b(!1),o&&o()}};x.default.useEffect(()=>{let e=setTimeout(()=>{S()},200);return()=>clearTimeout(e)},[]);let T=e=>e?e.split("stack trace:")[0].trim().replace(/^litellm\.(.*?)Error: /,""):"Unknown error",I="string"==typeof h?T(h):h?.message?T(h.message):"Unknown error",F=_?(n=_.raw_request_api_base,d=_.raw_request_body,c=_.raw_request_headers||{},m=JSON.stringify(d,null,2).split("\n").map(e=>` ${e}`).join("\n"),u=Object.entries(c).map(([e,t])=>`-H '${e}: ${t}'`).join(" \\\n "),`curl -X POST \\ + ${n} \\ + ${u?`${u} \\ + `:""}-H 'Content-Type: application/json' \\ + -d '{ +${m} + }'`):"";return(0,t.jsxs)("div",{style:{padding:"24px",borderRadius:"8px",backgroundColor:"#fff"},children:[y?(0,t.jsxs)("div",{style:{textAlign:"center",padding:"32px 20px"},className:"jsx-dc9a0e2d897fe63b",children:[(0,t.jsx)("div",{style:{marginBottom:"16px"},className:"jsx-dc9a0e2d897fe63b loading-spinner",children:(0,t.jsx)("div",{style:{border:"3px solid #f3f3f3",borderTop:"3px solid #1890ff",borderRadius:"50%",width:"30px",height:"30px",animation:"spin 1s linear infinite",margin:"0 auto"},className:"jsx-dc9a0e2d897fe63b"})}),(0,t.jsxs)(tl,{style:{fontSize:"16px"},children:["Testing connection to ",r,"..."]}),(0,t.jsx)(te.default,{id:"dc9a0e2d897fe63b",children:"@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}"})]}):v?(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",padding:"32px 20px"},children:[(0,t.jsx)("div",{style:{color:"#52c41a",fontSize:"24px",display:"flex",alignItems:"center"},children:(0,t.jsx)("svg",{viewBox:"64 64 896 896",focusable:"false","data-icon":"check-circle",width:"1em",height:"1em",fill:"currentColor","aria-hidden":"true",children:(0,t.jsx)("path",{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 01-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z"})})}),(0,t.jsxs)(tl,{"data-testid":"connection-success-msg",type:"success",style:{fontSize:"18px",fontWeight:500,marginLeft:"10px"},children:["Connection to ",r," successful!"]})]}):(0,t.jsx)(t.Fragment,{children:(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",marginBottom:"20px"},children:[(0,t.jsx)(eS.WarningOutlined,{style:{color:"#ff4d4f",fontSize:"24px",marginRight:"12px"}}),(0,t.jsxs)(tl,{"data-testid":"connection-failure-msg",type:"danger",style:{fontSize:"18px",fontWeight:500},children:["Connection to ",r," failed"]})]}),(0,t.jsxs)("div",{style:{backgroundColor:"#fff2f0",border:"1px solid #ffccc7",borderRadius:"8px",padding:"16px",marginBottom:"20px",boxShadow:"0 1px 2px rgba(0, 0, 0, 0.03)"},children:[(0,t.jsxs)(tl,{strong:!0,style:{display:"block",marginBottom:"8px"},children:["Error:"," "]}),(0,t.jsx)(tl,{type:"danger",style:{fontSize:"14px",lineHeight:"1.5"},children:I}),h&&(0,t.jsx)("div",{style:{marginTop:"12px"},children:(0,t.jsx)(Q.Button,{type:"link",onClick:()=>k(!w),style:{paddingLeft:0,height:"auto"},children:w?"Hide Details":"Show Details"})})]}),w&&(0,t.jsxs)("div",{style:{marginBottom:"20px"},children:[(0,t.jsx)(tl,{strong:!0,style:{display:"block",marginBottom:"8px",fontSize:"15px"},children:"Troubleshooting Details"}),(0,t.jsx)("pre",{style:{backgroundColor:"#f5f5f5",padding:"16px",borderRadius:"8px",fontSize:"13px",maxHeight:"200px",overflow:"auto",border:"1px solid #e8e8e8",lineHeight:"1.5"},children:"string"==typeof h?h:JSON.stringify(h,null,2)})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(tl,{strong:!0,style:{display:"block",marginBottom:"8px",fontSize:"15px"},children:"API Request"}),(0,t.jsx)("pre",{style:{backgroundColor:"#f5f5f5",padding:"16px",borderRadius:"8px",fontSize:"13px",maxHeight:"250px",overflow:"auto",border:"1px solid #e8e8e8",lineHeight:"1.5"},children:F||"No request data available"}),(0,t.jsx)(Q.Button,{style:{marginTop:"8px"},icon:(0,t.jsx)(tt.CopyOutlined,{}),onClick:()=>{navigator.clipboard.writeText(F||""),G.default.success("Copied to clipboard")},children:"Copy to Clipboard"})]})]})}),(0,t.jsx)(P.Divider,{style:{margin:"24px 0 16px"}}),(0,t.jsx)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:(0,t.jsx)(Q.Button,{type:"link",href:"https://docs.litellm.ai/docs/providers",target:"_blank",icon:(0,t.jsx)(C.InfoCircleOutlined,{}),children:"View Documentation"})})]})},ta=async(e,t,s,a)=>{try{let r;"complexity_router"===e.model_type?r={model_name:e.auto_router_name,litellm_params:{model:"auto_router/complexity_router",complexity_router_config:e.complexity_router_config,complexity_router_default_model:e.auto_router_default_model},model_info:{}}:(r={model_name:e.auto_router_name,litellm_params:{model:`auto_router/${e.auto_router_name}`,auto_router_config:JSON.stringify(e.auto_router_config),auto_router_default_model:e.auto_router_default_model},model_info:{}},e.auto_router_embedding_model&&"custom"!==e.auto_router_embedding_model?r.litellm_params.auto_router_embedding_model=e.auto_router_embedding_model:e.custom_embedding_model&&(r.litellm_params.auto_router_embedding_model=e.custom_embedding_model)),e.team_id&&(r.model_info.team_id=e.team_id),e.model_access_group&&e.model_access_group.length>0&&(r.model_info.access_groups=e.model_access_group),await (0,l.modelCreateCall)(t,r);let i="complexity_router"===e.model_type?"Complexity Router":"Semantic Router";G.default.success(`Successfully created ${i}: ${e.auto_router_name}`),s.resetFields(),a&&a()}catch(e){console.error("Failed to add auto router:",e),G.default.fromBackend("Failed to add auto router: "+e)}};var tr=e.i(695411),ti=e.i(955135),to=e.i(646563),tn=e.i(362024),td=e.i(21548);let{Text:tc}=R.Typography,{TextArea:tm}=eV.Input,tu=({modelInfo:e,value:l,onChange:s})=>{let[a,r]=(0,x.useState)([]),[i,o]=(0,x.useState)(!1),[n,d]=(0,x.useState)([]);(0,x.useEffect)(()=>{let e=l?.routes;if(e){let t=[];r(l=>e.map((e,s)=>{let a=l[s],r=a?.id||e.id||`route-${s}-${Date.now()}`;return t.push(r),{id:r,model:e.name||e.model||"",utterances:e.utterances||[],description:e.description||"",score_threshold:e.score_threshold??.5}})),d(t)}else r([]),d([])},[l]);let c=(e,t,l)=>{let s=a.map(s=>s.id===e?{...s,[t]:l}:s);r(s),m(s)},m=e=>{let t={routes:e.map(e=>({name:e.model,utterances:e.utterances,description:e.description,score_threshold:e.score_threshold}))};s?.(t)},u=e.map(e=>({value:e.model_group,label:e.model_group}));return(0,t.jsxs)("div",{className:"w-full max-w-none",children:[(0,t.jsxs)(M.Flex,{justify:"space-between",align:"center",gap:"middle",style:{width:"100%",marginBottom:24},children:[(0,t.jsxs)(E.Space,{align:"center",children:[(0,t.jsx)(R.Typography.Title,{level:4,style:{margin:0},children:"Routes Configuration"}),(0,t.jsx)(O.Tooltip,{title:"Configure routing logic to automatically select the best model based on user input patterns",children:(0,t.jsx)(C.InfoCircleOutlined,{className:"text-gray-400"})})]}),(0,t.jsx)(Q.Button,{type:"primary",icon:(0,t.jsx)(to.PlusOutlined,{}),onClick:()=>{let e=`route-${Date.now()}`,t=[...a,{id:e,model:"",utterances:[],description:"",score_threshold:.5}];r(t),m(t),d(t=>[...t,e])},className:"bg-blue-600 hover:bg-blue-700",children:"Add Route"})]}),0===a.length?(0,t.jsx)(e_.Card,{children:(0,t.jsx)(td.Empty,{description:'No routes configured. Click "Add Route" to get started.'})}):(0,t.jsx)(tn.Collapse,{activeKey:n,onChange:e=>d(Array.isArray(e)?e:[e].filter(Boolean)),style:{width:"100%"},items:a.map((e,l)=>({key:e.id,label:(0,t.jsxs)(tc,{style:{fontSize:16},children:["Route ",l+1,": ",e.model||"Unnamed"]}),extra:(0,t.jsx)(Q.Button,{type:"text",danger:!0,size:"small",icon:(0,t.jsx)(ti.DeleteOutlined,{}),onClick:t=>{var l;let s;t.stopPropagation(),l=e.id,r(s=a.filter(e=>e.id!==l)),m(s),d(e=>e.filter(e=>e!==l))}}),children:(0,t.jsxs)(e_.Card,{children:[(0,t.jsxs)("div",{className:"mb-4 w-full",children:[(0,t.jsx)(tc,{className:"text-sm font-medium mb-2 block",children:"Model"}),(0,t.jsx)(Y.Select,{value:e.model,onChange:t=>c(e.id,"model",t),placeholder:"Select model",showSearch:!0,style:{width:"100%"},options:u})]}),(0,t.jsxs)("div",{className:"mb-4 w-full",children:[(0,t.jsx)(tc,{className:"text-sm font-medium mb-2 block",children:"Description"}),(0,t.jsx)(tm,{value:e.description,onChange:t=>c(e.id,"description",t.target.value),placeholder:"Describe when this route should be used...",rows:2,style:{width:"100%"}})]}),(0,t.jsxs)("div",{className:"mb-4 w-full",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 mb-2",children:[(0,t.jsx)(tc,{className:"text-sm font-medium",children:"Score Threshold"}),(0,t.jsx)(O.Tooltip,{title:"Minimum similarity score to route to this model (0-1)",children:(0,t.jsx)(C.InfoCircleOutlined,{className:"text-gray-400"})})]}),(0,t.jsx)(eh.InputNumber,{value:e.score_threshold,onChange:t=>c(e.id,"score_threshold",t||0),min:0,max:1,step:.1,style:{width:"100%"},placeholder:"0.5"})]}),(0,t.jsxs)("div",{className:"w-full",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 mb-2",children:[(0,t.jsx)(tc,{className:"text-sm font-medium",children:"Example Utterances"}),(0,t.jsx)(O.Tooltip,{title:"Training examples for this route. Type an utterance and press Enter to add it.",children:(0,t.jsx)(C.InfoCircleOutlined,{className:"text-gray-400"})})]}),(0,t.jsx)(tc,{className:"text-xs text-gray-500 mb-2",children:"Type an utterance and press Enter to add it. You can also paste multiple lines."}),(0,t.jsx)(Y.Select,{mode:"tags",value:e.utterances,onChange:t=>c(e.id,"utterances",t),placeholder:"Type an utterance and press Enter...",style:{width:"100%"},tokenSeparators:["\n"],maxTagCount:"responsive",allowClear:!0})]})]},e.id)}))}),(0,t.jsx)(P.Divider,{}),(0,t.jsxs)("div",{className:"flex justify-between items-center mb-4 w-full",children:[(0,t.jsx)(tc,{className:"text-lg font-semibold",children:"JSON Preview"}),(0,t.jsx)(Q.Button,{type:"link",onClick:()=>o(!i),className:"text-blue-600 p-0",children:i?"Hide":"Show"})]}),i&&(0,t.jsx)(e_.Card,{className:"bg-gray-50 w-full",children:(0,t.jsx)("pre",{className:"text-sm overflow-auto max-h-64 w-full",children:JSON.stringify({routes:a.map(e=>({name:e.model,utterances:e.utterances,description:e.description,score_threshold:e.score_threshold}))},null,2)})})]})},{Text:th}=R.Typography,tp={SIMPLE:{label:"Simple",description:"Basic questions, greetings, simple factual queries",examples:'"Hello!", "What is Python?", "Thanks!"'},MEDIUM:{label:"Medium",description:"Standard queries requiring some reasoning or explanation",examples:'"Explain how REST APIs work", "Debug this error"'},COMPLEX:{label:"Complex",description:"Technical, multi-part requests requiring deep knowledge",examples:'"Design a microservices architecture", "Implement a rate limiter"'},REASONING:{label:"Reasoning",description:"Chain-of-thought, analysis, explicit reasoning requests",examples:'"Think step by step...", "Analyze the pros and cons..."'}},tx=({modelInfo:e,value:l,onChange:s})=>{let a=e.map(e=>({value:e.model_group,label:e.model_group}));return(0,t.jsxs)("div",{className:"w-full max-w-none",children:[(0,t.jsxs)(E.Space,{align:"center",style:{marginBottom:16},children:[(0,t.jsx)(R.Typography.Title,{level:4,style:{margin:0},children:"Complexity Tier Configuration"}),(0,t.jsx)(O.Tooltip,{title:"Map each complexity tier to a model. Simple queries use cheaper/faster models, complex queries use more capable models.",children:(0,t.jsx)(C.InfoCircleOutlined,{className:"text-gray-400"})})]}),(0,t.jsx)(th,{type:"secondary",style:{display:"block",marginBottom:24},children:"The complexity router automatically classifies requests by complexity using rule-based scoring (no API calls, <1ms latency). Configure which model handles each tier."}),(0,t.jsx)(e_.Card,{children:Object.keys(tp).map((e,r)=>{let i=tp[e];return(0,t.jsxs)("div",{children:[r>0&&(0,t.jsx)(P.Divider,{style:{margin:"16px 0"}}),(0,t.jsxs)("div",{className:"mb-4",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 mb-2",children:[(0,t.jsxs)(th,{strong:!0,style:{fontSize:16},children:[i.label," Tier"]}),(0,t.jsx)(O.Tooltip,{title:i.description,children:(0,t.jsx)(C.InfoCircleOutlined,{className:"text-gray-400"})})]}),(0,t.jsxs)(th,{type:"secondary",style:{display:"block",marginBottom:8,fontSize:12},children:["Examples: ",i.examples]}),(0,t.jsx)(Y.Select,{value:l[e],onChange:t=>{s({...l,[e]:t})},placeholder:`Select model for ${i.label.toLowerCase()} queries`,showSearch:!0,style:{width:"100%"},options:a})]})]},e)})}),(0,t.jsx)(P.Divider,{}),(0,t.jsxs)(e_.Card,{className:"bg-gray-50",children:[(0,t.jsx)(th,{strong:!0,style:{display:"block",marginBottom:8},children:"How Classification Works"}),(0,t.jsx)(th,{type:"secondary",style:{fontSize:13},children:"The router scores each request across 7 dimensions: token count, code presence, reasoning markers, technical terms, simple indicators, multi-step patterns, and question complexity. The weighted score determines the tier:"}),(0,t.jsxs)("ul",{style:{marginTop:8,marginBottom:0,paddingLeft:20,fontSize:13,color:"rgba(0, 0, 0, 0.45)"},children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"SIMPLE"}),": Score < 0.15"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"MEDIUM"}),": Score 0.15 - 0.35"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"COMPLEX"}),": Score 0.35 - 0.60"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"REASONING"}),": Score > 0.60 (or 2+ reasoning markers)"]})]})]})]})};var tg=e.i(962944),tf=e.i(539677);let{Title:t_,Link:tj}=R.Typography,ty=({form:e,handleOk:s,accessToken:a,userRole:r})=>{let[i,o]=(0,x.useState)(!1),[n,d]=(0,x.useState)(!1),[c,m]=(0,x.useState)(""),[u,h]=(0,x.useState)([]),[p,g]=(0,x.useState)([]),[f,_]=(0,x.useState)(!1),[j,y]=(0,x.useState)(!1),[b,v]=(0,x.useState)("complexity"),[N,w]=(0,x.useState)(null),[C,k]=(0,x.useState)({SIMPLE:"",MEDIUM:"",COMPLEX:"",REASONING:""});(0,x.useEffect)(()=>{(async()=>{h((await (0,l.modelAvailableCall)(a,"","",!1,null,!0,!0)).data.map(e=>e.id))})()},[a]),(0,x.useEffect)(()=>{(async()=>{try{let e=await (0,tr.fetchAvailableModels)(a);g(e)}catch(e){console.error("Error fetching model info for auto router:",e)}})()},[a]);let S=e0.all_admin_roles.includes(r),T=async()=>{d(!0),m(`test-${Date.now()}`),o(!0)},I=()=>{let t=e.getFieldsValue();if(!t.auto_router_name)return void G.default.fromBackend("Please enter an Auto Router Name");if("complexity"===b){if(0===Object.values(C).filter(Boolean).length)return void G.default.fromBackend("Please select at least one model for a complexity tier");let l=C.MEDIUM||C.SIMPLE||C.COMPLEX||C.REASONING;e.setFieldsValue({custom_llm_provider:"auto_router",model:t.auto_router_name,api_key:"not_required_for_auto_router",auto_router_default_model:l}),e.validateFields(["auto_router_name"]).then(r=>{ta({...r,auto_router_name:t.auto_router_name,auto_router_default_model:l,model_type:"complexity_router",complexity_router_config:{tiers:C},model_access_group:t.model_access_group},a,e,s)}).catch(e=>{console.error("Validation failed:",e),G.default.fromBackend("Please fill in all required fields")})}else{if(!t.auto_router_default_model)return void G.default.fromBackend("Please select a Default Model");if(e.setFieldsValue({custom_llm_provider:"auto_router",model:t.auto_router_name,api_key:"not_required_for_auto_router"}),!N||!N.routes||0===N.routes.length)return void G.default.fromBackend("Please configure at least one route for the auto router");if(N.routes.filter(e=>!e.name||!e.description||0===e.utterances.length).length>0)return void G.default.fromBackend("Please ensure all routes have a target model, description, and at least one utterance");e.validateFields().then(t=>{ta({...t,auto_router_config:N,model_type:"semantic_router"},a,e,s)}).catch(e=>{console.error("Validation failed:",e);let t=e.errorFields||[];if(t.length>0){let e=t.map(e=>{let t=e.name[0];return({auto_router_name:"Auto Router Name",auto_router_default_model:"Default Model",auto_router_embedding_model:"Embedding Model"})[t]||t});G.default.fromBackend(`Please fill in the following required fields: ${e.join(", ")}`)}else G.default.fromBackend("Please fill in all required fields")})}};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(t_,{level:2,children:"Add Auto Router"}),(0,t.jsx)(em.Text,{className:"text-gray-600 mb-6",children:"Create an auto router that automatically selects the best model based on request complexity or semantic matching."}),(0,t.jsx)(e_.Card,{className:"mb-4",children:(0,t.jsxs)("div",{className:"mb-4",children:[(0,t.jsx)(em.Text,{className:"text-sm font-medium mb-2 block",children:"Router Type"}),(0,t.jsx)(e9.Radio.Group,{value:b,onChange:e=>v(e.target.value),className:"w-full",children:(0,t.jsxs)(E.Space,{direction:"vertical",className:"w-full",children:[(0,t.jsxs)(e9.Radio,{value:"complexity",className:"w-full",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(tg.ThunderboltOutlined,{className:"text-yellow-500"}),(0,t.jsx)("span",{className:"font-medium",children:"Complexity Router"}),(0,t.jsx)(W.Badge,{count:"Recommended",style:{backgroundColor:"#52c41a",fontSize:"10px",padding:"0 6px"}})]}),(0,t.jsxs)("div",{className:"text-xs text-gray-500 ml-6 mt-1",children:["Automatically routes based on request complexity. No training data needed — just pick 4 models and go.",(0,t.jsx)("br",{}),(0,t.jsx)("span",{className:"text-green-600",children:"✓ Zero API calls"})," ·"," ",(0,t.jsx)("span",{className:"text-green-600",children:"✓ <1ms latency"})," ·"," ",(0,t.jsx)("span",{className:"text-green-600",children:"✓ No cost"})]})]}),(0,t.jsxs)(e9.Radio,{value:"semantic",className:"w-full mt-2",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(tf.BranchesOutlined,{className:"text-blue-500"}),(0,t.jsx)("span",{className:"font-medium",children:"Semantic Router"})]}),(0,t.jsx)("div",{className:"text-xs text-gray-500 ml-6 mt-1",children:"Routes based on semantic similarity to example utterances. Requires embedding model and training examples."})]})]})})]})}),(0,t.jsx)(e_.Card,{children:(0,t.jsxs)(el.Form,{form:e,onFinish:I,labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,t.jsx)(el.Form.Item,{rules:[{required:!0,message:"Auto router name is required"}],label:"Auto Router Name",name:"auto_router_name",tooltip:"Unique name for this auto router configuration",labelCol:{span:10},labelAlign:"left",children:(0,t.jsx)(eO.TextInput,{placeholder:"e.g., smart_router, auto_router_1"})}),"complexity"===b?(0,t.jsx)("div",{className:"w-full mb-4",children:(0,t.jsx)(tx,{modelInfo:p,value:C,onChange:e=>{k(e)}})}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("div",{className:"w-full mb-4",children:(0,t.jsx)(tu,{modelInfo:p,value:N,onChange:t=>{w(t),e.setFieldValue("auto_router_config",t)}})}),(0,t.jsx)(el.Form.Item,{rules:[{required:"semantic"===b,message:"Default model is required"}],label:"Default Model",name:"auto_router_default_model",tooltip:"Fallback model to use when auto routing logic cannot determine the best model",labelCol:{span:10},labelAlign:"left",children:(0,t.jsx)(Y.Select,{placeholder:"Select a default model",onChange:e=>{_("custom"===e)},options:[...Array.from(new Set(p.map(e=>e.model_group))).map(e=>({value:e,label:e})),{value:"custom",label:"Enter custom model name"}],style:{width:"100%"},showSearch:!0})}),(0,t.jsx)(el.Form.Item,{label:"Embedding Model",name:"auto_router_embedding_model",tooltip:"Optional: Embedding model to use for semantic routing decisions",labelCol:{span:10},labelAlign:"left",children:(0,t.jsx)(Y.Select,{value:e.getFieldValue("auto_router_embedding_model"),placeholder:"Select an embedding model (optional)",onChange:t=>{y("custom"===t),e.setFieldValue("auto_router_embedding_model",t)},options:[...Array.from(new Set(p.map(e=>e.model_group))).map(e=>({value:e,label:e})),{value:"custom",label:"Enter custom model name"}],style:{width:"100%"},showSearch:!0,allowClear:!0})})]}),(0,t.jsxs)("div",{className:"flex items-center my-4",children:[(0,t.jsx)("div",{className:"grow border-t border-gray-200"}),(0,t.jsx)("span",{className:"px-4 text-gray-500 text-sm",children:"Additional Settings"}),(0,t.jsx)("div",{className:"grow border-t border-gray-200"})]}),S&&(0,t.jsx)(el.Form.Item,{label:"Model Access Group",name:"model_access_group",className:"mb-4",tooltip:"Use model access groups to control who can access this auto router",children:(0,t.jsx)(Y.Select,{mode:"tags",showSearch:!0,placeholder:"Select existing groups or type to create new ones",optionFilterProp:"children",tokenSeparators:[","],options:u.map(e=>({value:e,label:e})),maxTagCount:"responsive",allowClear:!0})}),(0,t.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,t.jsx)(O.Tooltip,{title:"Get help on our github",children:(0,t.jsx)(R.Typography.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})}),(0,t.jsxs)("div",{className:"space-x-2",children:[(0,t.jsx)(Q.Button,{onClick:T,loading:n,children:"Test Connection"}),(0,t.jsx)(Q.Button,{type:"primary",onClick:()=>{I()},children:"Add Auto Router"})]})]})]})}),(0,t.jsx)(es.Modal,{title:"Connection Test Results",open:i,onCancel:()=>{o(!1),d(!1)},footer:[(0,t.jsx)(Q.Button,{onClick:()=>{o(!1),d(!1)},children:"Close"},"close")],width:700,children:i&&(0,t.jsx)(ts,{formValues:e.getFieldsValue(),accessToken:a,testMode:"chat",modelName:e.getFieldValue("auto_router_name"),onClose:()=>{o(!1),d(!1)},onTestComplete:()=>d(!1)},c)})]})};var tb=e.i(838932),tv=e.i(109034),tN=e.i(793130),tw=e.i(560445),tC=e.i(663435),tk=e.i(677667),tS=e.i(898667),tT=e.i(130643),tI=e.i(635432),tF=e.i(564897),tP=e.i(435451);let{Text:tM}=R.Typography,tA=({form:e,showCacheControl:l,onCacheControlChange:s})=>{let a=t=>{let l=e.getFieldValue("litellm_extra_params");try{let s=l?JSON.parse(l):{};t.length>0?s.cache_control_injection_points=t:delete s.cache_control_injection_points,Object.keys(s).length>0?e.setFieldValue("litellm_extra_params",JSON.stringify(s,null,2)):e.setFieldValue("litellm_extra_params","")}catch(e){console.error("Error updating cache control points:",e)}};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(el.Form.Item,{label:"Cache Control Injection Points",name:"cache_control",valuePropName:"checked",className:"mb-4",tooltip:"Tell litellm where to inject cache control checkpoints. You can specify either by role (to apply to all messages of that role) or by specific message index.",children:(0,t.jsx)(L.Switch,{onChange:s,className:"bg-gray-600"})}),l&&(0,t.jsxs)("div",{className:"ml-6 pl-4 border-l-2 border-gray-200",children:[(0,t.jsx)(tM,{className:"text-sm text-gray-500 block mb-4",children:"Providers like Anthropic, Bedrock API require users to specify where to inject cache control checkpoints, litellm can automatically add them for you as a cost saving feature."}),(0,t.jsx)(el.Form.List,{name:"cache_control_injection_points",initialValue:[{location:"message"}],children:(l,{add:s,remove:r})=>(0,t.jsxs)(t.Fragment,{children:[l.map((s,i)=>(0,t.jsxs)("div",{className:"flex items-center mb-4 gap-4",children:[(0,t.jsx)(el.Form.Item,{...s,label:"Type",name:[s.name,"location"],initialValue:"message",className:"mb-0",style:{width:"180px"},children:(0,t.jsx)(Y.Select,{disabled:!0,options:[{value:"message",label:"Message"}]})}),(0,t.jsx)(el.Form.Item,{...s,label:"Role",name:[s.name,"role"],className:"mb-0",style:{width:"180px"},tooltip:"LiteLLM will mark all messages of this role as cacheable",children:(0,t.jsx)(Y.Select,{placeholder:"Select a role",allowClear:!0,options:[{value:"user",label:"User"},{value:"system",label:"System"},{value:"assistant",label:"Assistant"}],onChange:()=>{a(e.getFieldValue("cache_control_points"))}})}),(0,t.jsx)(el.Form.Item,{...s,label:"Index",name:[s.name,"index"],className:"mb-0",style:{width:"180px"},tooltip:"(Optional) If set litellm will mark the message at this index as cacheable",children:(0,t.jsx)(tP.default,{type:"number",placeholder:"Optional",step:1,onChange:()=>{a(e.getFieldValue("cache_control_points"))}})}),l.length>1&&(0,t.jsx)(tF.MinusCircleOutlined,{className:"text-red-500 cursor-pointer text-lg ml-12",onClick:()=>{r(s.name),setTimeout(()=>{a(e.getFieldValue("cache_control_points"))},0)}})]},s.key)),(0,t.jsx)(el.Form.Item,{children:(0,t.jsxs)("button",{type:"button",className:"flex items-center justify-center w-full border border-dashed border-gray-300 py-2 px-4 text-gray-600 hover:text-blue-600 hover:border-blue-300 transition-all rounded-sm",onClick:()=>s(),children:[(0,t.jsx)(to.PlusOutlined,{className:"mr-2"}),"Add Injection Point"]})})]})})]})]})};var tE=e.i(916940),tL=e.i(122550);let{Link:tO}=R.Typography,tR=({showAdvancedSettings:e,setShowAdvancedSettings:l,teams:s,guardrailsList:a,tagsList:r,accessToken:i})=>{let[o]=el.Form.useForm(),[n,d]=x.default.useState(!1),[c,m]=x.default.useState("per_token"),[u,h]=x.default.useState(!1),p=(e,t)=>t&&(isNaN(Number(t))||0>Number(t))?Promise.reject("Please enter a valid positive number"):Promise.resolve();return(0,t.jsx)(t.Fragment,{children:(0,t.jsxs)(tk.Accordion,{className:"mt-2 mb-4",children:[(0,t.jsx)(tS.AccordionHeader,{children:(0,t.jsx)("b",{children:"Advanced Settings"})}),(0,t.jsx)(tT.AccordionBody,{children:(0,t.jsxs)("div",{className:"bg-white rounded-lg",children:[(0,t.jsx)(el.Form.Item,{label:"Custom Pricing",name:"custom_pricing",valuePropName:"checked",className:"mb-4",children:(0,t.jsx)(L.Switch,{onChange:e=>{d(e),e||o.setFieldsValue({input_cost_per_token:void 0,output_cost_per_token:void 0,cache_read_input_token_cost:void 0,cache_creation_input_token_cost:void 0,input_cost_per_second:void 0})},className:"bg-gray-600"})}),(0,t.jsx)(el.Form.Item,{label:(0,t.jsxs)("span",{children:["Attached Knowledge Bases (RAG)"," ",(0,t.jsx)(O.Tooltip,{title:"Vector stores to use for RAG. Every request to this model will automatically retrieve context from these knowledge bases.",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/completion/knowledgebase",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(C.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"vector_store_ids",className:"mt-4",help:"Select vector stores to attach. Requests to this model will automatically use these for RAG. Set up vector stores in Tools > Vector Stores.",children:(0,t.jsx)(tE.default,{onChange:()=>{},accessToken:i,placeholder:"Select knowledge bases (optional)"})}),(0,t.jsx)(el.Form.Item,{label:(0,t.jsxs)("span",{children:["Guardrails"," ",(0,t.jsx)(O.Tooltip,{title:"Apply safety guardrails to this key to filter content or enforce policies",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(C.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),name:"guardrails",className:"mt-4",help:"Select existing guardrails. Go to 'Guardrails' tab to create new guardrails.",children:(0,t.jsx)(Y.Select,{mode:"tags",style:{width:"100%"},placeholder:"Select or enter guardrails",options:a.map(e=>({value:e,label:e}))})}),(0,t.jsx)(el.Form.Item,{label:"Tags",name:"tags",className:"mb-4",children:(0,t.jsx)(Y.Select,{mode:"tags",style:{width:"100%"},placeholder:"Select or enter tags",options:Object.values(r).map(e=>({value:e.name,label:e.name,title:e.description||e.name}))})}),n&&(0,t.jsxs)("div",{className:"ml-6 pl-4 border-l-2 border-gray-200",children:[(0,t.jsx)(el.Form.Item,{label:"Pricing Model",name:"pricing_model",className:"mb-4",children:(0,t.jsx)(Y.Select,{defaultValue:"per_token",onChange:e=>m(e),options:[{value:"per_token",label:"Per Million Tokens"},{value:"per_second",label:"Per Second"}]})}),"per_token"===c?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(el.Form.Item,{label:"Input Cost (per 1M tokens)",name:"input_cost_per_token",rules:[{validator:p}],className:"mb-4",children:(0,t.jsx)(eO.TextInput,{})}),(0,t.jsx)(el.Form.Item,{label:"Output Cost (per 1M tokens)",name:"output_cost_per_token",rules:[{validator:p}],className:"mb-4",children:(0,t.jsx)(eO.TextInput,{})}),(0,t.jsx)(el.Form.Item,{label:"Cache Read Cost (per 1M tokens)",name:"cache_read_input_token_cost",rules:[{validator:p}],tooltip:"If left blank, defaults to Input Cost.",className:"mb-4",children:(0,t.jsx)(eO.TextInput,{placeholder:"Defaults to Input Cost if blank"})}),(0,t.jsx)(el.Form.Item,{label:"Cache Write Cost (per 1M tokens)",name:"cache_creation_input_token_cost",rules:[{validator:p}],tooltip:"If left blank, defaults to Input Cost (the backend falls back to input_cost_per_token when no cache-write rate is set).",className:"mb-4",children:(0,t.jsx)(eO.TextInput,{placeholder:"Defaults to Input Cost if blank"})})]}):(0,t.jsx)(el.Form.Item,{label:"Cost Per Second",name:"input_cost_per_second",rules:[{validator:p}],className:"mb-4",children:(0,t.jsx)(eO.TextInput,{})})]}),(0,t.jsx)(el.Form.Item,{label:"Use in pass through routes",name:"use_in_pass_through",valuePropName:"checked",className:"mb-4 mt-4",tooltip:(0,t.jsxs)("span",{children:["Allow using these credentials in pass through routes."," ",(0,t.jsx)(tO,{href:"https://docs.litellm.ai/docs/pass_through/vertex_ai",target:"_blank",children:"Learn more"})]}),children:(0,t.jsx)(L.Switch,{onChange:e=>{let t=o.getFieldValue("litellm_extra_params");try{let l=t?JSON.parse(t):{};e?l.use_in_pass_through=!0:delete l.use_in_pass_through,Object.keys(l).length>0?o.setFieldValue("litellm_extra_params",JSON.stringify(l,null,2)):o.setFieldValue("litellm_extra_params","")}catch(t){e?o.setFieldValue("litellm_extra_params",JSON.stringify({use_in_pass_through:!0},null,2)):o.setFieldValue("litellm_extra_params","")}},className:"bg-gray-600"})}),(0,t.jsx)(tA,{form:o,showCacheControl:u,onCacheControlChange:e=>{if(h(e),!e){let e=o.getFieldValue("litellm_extra_params");try{let t=e?JSON.parse(e):{};delete t.cache_control_injection_points,Object.keys(t).length>0?o.setFieldValue("litellm_extra_params",JSON.stringify(t,null,2)):o.setFieldValue("litellm_extra_params","")}catch(e){o.setFieldValue("litellm_extra_params","")}}}}),(0,t.jsx)(el.Form.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-4 mt-4",rules:[{validator:tL.formItemValidateJSON}],children:(0,t.jsx)(tI.default,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,t.jsxs)(eD.Row,{className:"mb-4",children:[(0,t.jsx)(eq.Col,{span:10}),(0,t.jsx)(eq.Col,{span:10,children:(0,t.jsxs)(em.Text,{className:"text-gray-600 text-sm",children:["Pass JSON of litellm supported params"," ",(0,t.jsx)(tO,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]}),(0,t.jsx)(el.Form.Item,{label:"Model Info",name:"model_info_params",tooltip:"Optional model info params. Returned when calling `/model/info` endpoint.",className:"mb-0",rules:[{validator:tL.formItemValidateJSON}],children:(0,t.jsx)(tI.default,{rows:4,placeholder:'{ "mode": "chat" }'})})]})})]})})};var tB=e.i(291542),tz=e.i(750113);let tq=({content:e,children:l,width:s="auto",className:a=""})=>{let[r,i]=(0,x.useState)(!1),[o,n]=(0,x.useState)("top"),d=(0,x.useRef)(null);return(0,t.jsxs)("div",{className:"relative inline-block",ref:d,children:[l||(0,t.jsx)(tz.QuestionCircleOutlined,{className:"ml-1 text-gray-500 cursor-help",onMouseEnter:()=>{if(d.current){let e=d.current.getBoundingClientRect(),t=e.top,l=window.innerHeight-e.bottom;t<300&&l>300?n("bottom"):n("top")}i(!0)},onMouseLeave:()=>i(!1)}),r&&(0,t.jsxs)("div",{className:`absolute left-1/2 -translate-x-1/2 z-50 bg-black/90 text-white p-2 rounded-md text-sm font-normal shadow-lg ${a}`,style:{["top"===o?"bottom":"top"]:"100%",width:s,marginBottom:"top"===o?"8px":"0",marginTop:"bottom"===o?"8px":"0"},children:[e,(0,t.jsx)("div",{className:"absolute left-1/2 -translate-x-1/2 w-0 h-0",style:{top:"top"===o?"100%":"auto",bottom:"bottom"===o?"100%":"auto",borderTop:"top"===o?"6px solid rgba(0, 0, 0, 0.9)":"6px solid transparent",borderBottom:"bottom"===o?"6px solid rgba(0, 0, 0, 0.9)":"6px solid transparent",borderLeft:"6px solid transparent",borderRight:"6px solid transparent"}})]})]})},tV=()=>{let e=el.Form.useFormInstance(),[l,s]=(0,x.useState)(0),a=el.Form.useWatch("model",e)||[],r=Array.isArray(a)?a:[a],i=el.Form.useWatch("custom_model_name",e),o=!r.includes("all-wildcard"),n=el.Form.useWatch("custom_llm_provider",e);if((0,x.useEffect)(()=>{if(i&&r.includes("custom")){let t=(e.getFieldValue("model_mappings")||[]).map(e=>"custom"===e.public_name||"custom"===e.litellm_model?n===eP.Providers.Azure?{public_name:i,litellm_model:`azure/${i}`}:{public_name:i,litellm_model:i}:e);e.setFieldValue("model_mappings",t),s(e=>e+1)}},[i,r,n,e]),(0,x.useEffect)(()=>{if(r.length>0&&!r.includes("all-wildcard")){let t=e.getFieldValue("model_mappings")||[];if(t.length!==r.length||!r.every(e=>t.some(t=>"custom"===e?"custom"===t.litellm_model||t.litellm_model===i:n===eP.Providers.Azure?t.litellm_model===`azure/${e}`:t.litellm_model===e))){let t=r.map(e=>"custom"===e&&i?n===eP.Providers.Azure?{public_name:i,litellm_model:`azure/${i}`}:{public_name:i,litellm_model:i}:n===eP.Providers.Azure?{public_name:e,litellm_model:`azure/${e}`}:{public_name:e,litellm_model:e});e.setFieldValue("model_mappings",t),s(e=>e+1)}}},[r,i,n,e]),!o)return null;let d=(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("div",{className:"mb-2 font-normal",children:"The name you specify in your API calls to LiteLLM Proxy"}),(0,t.jsxs)("div",{className:"mb-2 font-normal",children:[(0,t.jsx)("strong",{children:"Example:"})," If you name your public model"," ",(0,t.jsx)("code",{className:"bg-gray-700 px-1 py-0.5 rounded-sm text-xs",children:"example-name"}),", and choose"," ",(0,t.jsx)("code",{className:"bg-gray-700 px-1 py-0.5 rounded-sm text-xs",children:"openai/qwen-plus-latest"})," as the LiteLLM model"]}),(0,t.jsxs)("div",{className:"mb-2 font-normal",children:[(0,t.jsx)("strong",{children:"Usage:"})," You make an API call to the LiteLLM proxy with"," ",(0,t.jsx)("code",{className:"bg-gray-700 px-1 py-0.5 rounded-sm text-xs",children:'model = "example-name"'})]}),(0,t.jsxs)("div",{className:"font-normal",children:[(0,t.jsx)("strong",{children:"Result:"})," LiteLLM sends"," ",(0,t.jsx)("code",{className:"bg-gray-700 px-1 py-0.5 rounded-sm text-xs",children:"qwen-plus-latest"})," to the provider"]})]}),c=(0,t.jsx)("div",{children:"The model name LiteLLM will send to the LLM API"}),m=[{title:(0,t.jsxs)("span",{className:"flex items-center",children:["Public Model Name",(0,t.jsx)(tq,{content:d,width:"500px"})]}),dataIndex:"public_name",key:"public_name",render:(l,s,a)=>(0,t.jsx)(eO.TextInput,{value:l,onChange:t=>{let l=t.target.value,s=[...e.getFieldValue("model_mappings")],r=n===eP.Providers.Anthropic,i=l.endsWith("-1m"),o=e.getFieldValue("litellm_extra_params"),d=!o||""===o.trim(),c=l;if(r&&i&&d){let t=JSON.stringify({extra_headers:{"anthropic-beta":"context-1m-2025-08-07"}},null,2);e.setFieldValue("litellm_extra_params",t),c=l.slice(0,-3)}s[a].public_name=c,e.setFieldValue("model_mappings",s)}})},{title:(0,t.jsxs)("span",{className:"flex items-center",children:["LiteLLM Model Name",(0,t.jsx)(tq,{content:c,width:"360px"})]}),dataIndex:"litellm_model",key:"litellm_model"}];return(0,t.jsx)(t.Fragment,{children:(0,t.jsx)(el.Form.Item,{label:"Model Mappings",name:"model_mappings",tooltip:"Map public model names to LiteLLM model names for load balancing",labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",rules:[{required:!0,validator:async(e,t)=>{if(!t||0===t.length)throw Error("At least one model mapping is required");if(t.filter(e=>!e.public_name||""===e.public_name.trim()).length>0)throw Error("All model mappings must have valid public names")}}],children:(0,t.jsx)(tB.Table,{dataSource:e.getFieldValue("model_mappings"),columns:m,pagination:!1,size:"small"},l)})})},tD=({selectedProvider:e,providerModels:l,getPlaceholder:s})=>{let a=el.Form.useFormInstance(),r=t=>{let l=t.target.value,s=(a.getFieldValue("model_mappings")||[]).map(t=>"custom"===t.public_name||"custom"===t.litellm_model?e===eP.Providers.Azure?{public_name:l,litellm_model:`azure/${l}`}:{public_name:l,litellm_model:l}:t);a.setFieldsValue({model_mappings:s})};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(el.Form.Item,{label:"LiteLLM Model Name(s)",tooltip:"The model name LiteLLM will send to the LLM API",className:"mb-0",children:[(0,t.jsx)(el.Form.Item,{name:"model",rules:[{required:!0,message:`Please enter ${e===eP.Providers.Azure?"a deployment name":"at least one model"}.`}],noStyle:!0,children:e===eP.Providers.Azure||e===eP.Providers.OpenAI_Compatible||e===eP.Providers.Ollama?(0,t.jsx)(t.Fragment,{children:(0,t.jsx)(eO.TextInput,{placeholder:s(e),onChange:e===eP.Providers.Azure?e=>{let t=e.target.value,l=t?[{public_name:t,litellm_model:`azure/${t}`}]:[];a.setFieldsValue({model:t,model_mappings:l})}:void 0})}):l.length>0?(0,t.jsx)(Y.Select,{"data-testid":"model-name-select",mode:"multiple",allowClear:!0,showSearch:!0,placeholder:"Select models",onChange:t=>{let l=Array.isArray(t)?t:[t];if(l.includes("all-wildcard"))a.setFieldsValue({model_name:void 0,model_mappings:[]});else if(JSON.stringify(a.getFieldValue("model"))!==JSON.stringify(l)){let t=l.map(t=>e===eP.Providers.Azure?{public_name:t,litellm_model:`azure/${t}`}:{public_name:t,litellm_model:t});a.setFieldsValue({model:l,model_mappings:t})}},optionFilterProp:"children",filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase()),options:[{label:"Custom Model Name (Enter below)",value:"custom"},{label:`All ${e} Models (Wildcard)`,value:"all-wildcard"},...l.map(e=>({label:e,value:e}))],style:{width:"100%"}}):(0,t.jsx)(eO.TextInput,{placeholder:s(e)})}),(0,t.jsx)(el.Form.Item,{noStyle:!0,shouldUpdate:(e,t)=>e.model!==t.model,children:({getFieldValue:l})=>{let s=l("model")||[];return(Array.isArray(s)?s:[s]).includes("custom")&&(0,t.jsx)(el.Form.Item,{name:"custom_model_name",rules:[{required:!0,message:"Please enter a custom model name."}],className:"mt-2",children:(0,t.jsx)(eO.TextInput,{placeholder:e===eP.Providers.Azure?"Enter Azure deployment name":"Enter custom model name",onChange:r})})}})]}),(0,t.jsxs)(eD.Row,{children:[(0,t.jsx)(eq.Col,{span:10}),(0,t.jsx)(eq.Col,{span:14,children:(0,t.jsx)(em.Text,{className:"mb-3 mt-1",children:e===eP.Providers.Azure?"Your deployment name will be saved as the public model name, and LiteLLM will use 'azure/deployment-name' internally":"The model name LiteLLM will send to the LLM API"})})]})]})},tH=[{value:"chat",label:"Chat - /chat/completions"},{value:"completion",label:"Completion - /completions"},{value:"embedding",label:"Embedding - /embeddings"},{value:"audio_speech",label:"Audio Speech - /audio/speech"},{value:"audio_transcription",label:"Audio Transcription - /audio/transcriptions"},{value:"image_generation",label:"Image Generation - /images/generations"},{value:"video_generation",label:"Video Generation - /videos"},{value:"rerank",label:"Rerank - /rerank"},{value:"realtime",label:"Realtime - /realtime"},{value:"batch",label:"Batch - /batch"},{value:"ocr",label:"OCR - /ocr"}],{Title:tG,Link:tU}=R.Typography,t$=({form:e,handleOk:s,selectedProvider:a,setSelectedProvider:i,providerModels:o,setProviderModelsFn:n,getPlaceholder:d,uploadProps:c,showAdvancedSettings:m,setShowAdvancedSettings:u,teams:h,credentials:p})=>{let[g,f]=(0,x.useState)("chat"),[_,j]=(0,x.useState)(!1),[y,b]=(0,x.useState)(!1),[v,N]=(0,x.useState)(""),{accessToken:w,userRole:C,premiumUser:k,userId:S}=(0,r.default)(),{data:T,isLoading:I,error:F}=eB(),{data:P}=(0,tb.useGuardrails)(),M=P?.guardrails.map(e=>e.guardrail_name),{data:A,isLoading:E,error:L}=(0,tv.useTags)(),z=async()=>{b(!0),N(`test-${Date.now()}`),j(!0)},[q,V]=(0,x.useState)(!1),[D,H]=(0,x.useState)([]),[G,U]=(0,x.useState)(null);(0,x.useEffect)(()=>{(async()=>{H((await (0,l.modelAvailableCall)(w,"","",!1,null,!0,!0)).data.map(e=>e.id))})()},[w]);let $=(0,x.useMemo)(()=>T?[...T].sort((e,t)=>e.provider_display_name.localeCompare(t.provider_display_name)):[],[T]),K=F?F instanceof Error?F.message:"Failed to load providers":null,J=e0.all_admin_roles.includes(C),W=(0,e0.isUserTeamAdminForAnyTeam)(h,S);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(tG,{level:2,children:"Add Model"}),(0,t.jsx)(e_.Card,{children:(0,t.jsx)(el.Form,{form:e,onFinish:async e=>{await s().then(()=>{U(null)})},onFinishFailed:e=>{},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:(0,t.jsxs)(t.Fragment,{children:[W&&!J&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(el.Form.Item,{label:"Select Team",name:"team_id",rules:[{required:!0,message:"Please select a team to continue"}],tooltip:"Select the team for which you want to add this model",children:(0,t.jsx)(tC.default,{onChange:e=>{U(e)}})}),!G&&(0,t.jsx)(tw.Alert,{message:"Team Selection Required",description:"As a team admin, you need to select your team first before adding models.",type:"info",showIcon:!0,className:"mb-4"})]}),(J||W&&G)&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(el.Form.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,t.jsxs)(Y.Select,{virtual:!1,showSearch:!0,loading:I,placeholder:I?"Loading providers...":"Select a provider",optionFilterProp:"data-label",onChange:t=>{i(t),n(t),e.setFieldsValue({custom_llm_provider:t}),e.setFieldsValue({model:[],model_name:void 0})},children:[K&&0===$.length&&(0,t.jsx)(Y.Select.Option,{value:"",children:K},"__error"),$.map(e=>{let l=e.provider_display_name,s=e.provider;return eP.providerLogoMap[l],(0,t.jsx)(Y.Select.Option,{value:s,"data-label":l,children:(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)(B.ProviderLogo,{provider:s,className:"w-5 h-5"}),(0,t.jsx)("span",{children:l})]})},s)})]})}),(0,t.jsx)(tD,{selectedProvider:a,providerModels:o,getPlaceholder:d}),(0,t.jsx)(tV,{}),(0,t.jsx)(el.Form.Item,{label:"Mode",name:"mode",className:"mb-1",children:(0,t.jsx)(Y.Select,{style:{width:"100%"},value:g,onChange:e=>f(e),options:tH})}),(0,t.jsxs)(eD.Row,{children:[(0,t.jsx)(eq.Col,{span:10}),(0,t.jsx)(eq.Col,{span:10,children:(0,t.jsxs)(em.Text,{className:"mb-5 mt-1",children:[(0,t.jsx)("strong",{children:"Optional"})," - LiteLLM endpoint to use when health checking this model"," ",(0,t.jsx)(tU,{href:"https://docs.litellm.ai/docs/proxy/health#health",target:"_blank",children:"Learn more"})]})})]}),(0,t.jsx)("div",{className:"mb-4",children:(0,t.jsx)(R.Typography.Text,{className:"text-sm text-gray-500 mb-2",children:"Either select existing credentials OR enter new provider credentials below"})}),(0,t.jsx)(el.Form.Item,{label:"Existing Credentials",name:"litellm_credential_name",initialValue:null,children:(0,t.jsx)(Y.Select,{showSearch:!0,placeholder:"Select or search for existing credentials",optionFilterProp:"children",filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase()),options:[{value:null,label:"None"},...p.map(e=>({value:e.credential_name,label:e.credential_name}))],allowClear:!0})}),(0,t.jsx)(el.Form.Item,{noStyle:!0,shouldUpdate:(e,t)=>e.litellm_credential_name!==t.litellm_credential_name||e.provider!==t.provider,children:({getFieldValue:e})=>e("litellm_credential_name")?null:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("div",{className:"flex items-center my-4",children:[(0,t.jsx)("div",{className:"grow border-t border-gray-200"}),(0,t.jsx)("span",{className:"px-4 text-gray-500 text-sm",children:"OR"}),(0,t.jsx)("div",{className:"grow border-t border-gray-200"})]}),(0,t.jsx)(eK,{selectedProvider:a,uploadProps:c})]})}),(0,t.jsxs)("div",{className:"flex items-center my-4",children:[(0,t.jsx)("div",{className:"grow border-t border-gray-200"}),(0,t.jsx)("span",{className:"px-4 text-gray-500 text-sm",children:"Additional Model Info Settings"}),(0,t.jsx)("div",{className:"grow border-t border-gray-200"})]}),(J||!W)&&(0,t.jsx)(el.Form.Item,{label:"Team-BYOK Model",tooltip:"Only use this model + credential combination for this team. Useful when teams want to onboard their own OpenAI keys.",className:"mb-4",children:(0,t.jsx)(O.Tooltip,{title:k?"":"This is an enterprise-only feature. Upgrade to premium to restrict model+credential combinations to a specific team.",placement:"top",children:(0,t.jsx)(tN.Switch,{checked:q,onChange:t=>{V(t),t||e.setFieldValue("team_id",void 0)},disabled:!k})})}),q&&(J||!W)&&(0,t.jsx)(el.Form.Item,{label:"Select Team",name:"team_id",className:"mb-4",tooltip:"Only keys for this team will be able to call this model.",rules:[{required:q&&!J,message:"Please select a team."}],children:(0,t.jsx)(tC.default,{disabled:!k})}),J&&(0,t.jsx)(t.Fragment,{children:(0,t.jsx)(el.Form.Item,{label:"Model Access Group",name:"model_access_group",className:"mb-4",tooltip:"Use model access groups to give users access to select models, and add new ones to the group over time.",children:(0,t.jsx)(Y.Select,{mode:"tags",showSearch:!0,placeholder:"Select existing groups or type to create new ones",optionFilterProp:"children",tokenSeparators:[","],options:D.map(e=>({value:e,label:e})),maxTagCount:"responsive",allowClear:!0})})}),(0,t.jsx)(tR,{showAdvancedSettings:m,setShowAdvancedSettings:u,teams:h,guardrailsList:M||[],tagsList:A||{},accessToken:w||""})]}),(0,t.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,t.jsx)(O.Tooltip,{title:"Get help on our github",children:(0,t.jsx)(R.Typography.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})}),(0,t.jsxs)("div",{className:"space-x-2",children:[(0,t.jsx)(Q.Button,{"data-testid":"test-connect-btn",onClick:z,loading:y,children:"Test Connect"}),(0,t.jsx)(Q.Button,{"data-testid":"add-model-btn",htmlType:"submit",children:"Add Model"})]})]})]})})}),(0,t.jsx)(es.Modal,{title:"Connection Test Results",open:_,onCancel:()=>{j(!1),b(!1)},footer:[(0,t.jsx)(Q.Button,{onClick:()=>{j(!1),b(!1)},children:"Close"},"close")],width:700,children:_&&(0,t.jsx)(ts,{formValues:e.getFieldsValue(),accessToken:w,testMode:g,modelName:e.getFieldValue("model_name")||e.getFieldValue("model"),onClose:()=>{j(!1),b(!1)},onTestComplete:()=>b(!1)},v)})]})},tK=({form:e,handleOk:l,selectedProvider:s,setSelectedProvider:a,providerModels:r,setProviderModelsFn:i,getPlaceholder:o,uploadProps:n,showAdvancedSettings:d,setShowAdvancedSettings:c,teams:m,credentials:u,accessToken:h,userRole:p})=>{let[x]=el.Form.useForm();return(0,t.jsx)(t.Fragment,{children:(0,t.jsxs)(e6.TabGroup,{className:"w-full",children:[(0,t.jsxs)(e3.TabList,{className:"mb-4",children:[(0,t.jsx)(e5.Tab,{children:"Add Model"}),(0,t.jsx)(e5.Tab,{children:"Add Auto Router"})]}),(0,t.jsxs)(e8.TabPanels,{children:[(0,t.jsx)(J.TabPanel,{children:(0,t.jsx)(t$,{form:e,handleOk:l,selectedProvider:s,setSelectedProvider:a,providerModels:r,setProviderModelsFn:i,getPlaceholder:o,uploadProps:n,showAdvancedSettings:d,setShowAdvancedSettings:c,teams:m,credentials:u})}),(0,t.jsx)(J.TabPanel,{children:(0,t.jsx)(ty,{form:x,handleOk:()=>{x.validateFields().then(e=>{ta(e,h,x,l)}).catch(e=>{console.error("Validation failed:",e)})},accessToken:h,userRole:p})})]})]})})};var tJ=e.i(798496),tW=e.i(536916),tQ=e.i(502275),tY=e.i(122577);let tX=[{pattern:/Missing .* API Key/i,replacement:"Missing API Key"},{pattern:/Connection timeout/i,replacement:"Connection timeout"},{pattern:/Network.*not.*ok/i,replacement:"Network connection failed"},{pattern:/403.*Forbidden/i,replacement:"Access forbidden - check API key permissions"},{pattern:/401.*Unauthorized/i,replacement:"Unauthorized - invalid API key"},{pattern:/429.*rate limit/i,replacement:"Rate limit exceeded"},{pattern:/500.*Internal Server Error/i,replacement:"Provider internal server error"},{pattern:/litellm\.AuthenticationError/i,replacement:"Authentication failed"},{pattern:/litellm\.RateLimitError/i,replacement:"Rate limit exceeded"},{pattern:/litellm\.APIError/i,replacement:"API error"}],tZ=({accessToken:e,modelData:s,all_models_on_proxy:a,getDisplayModelName:r,setSelectedModelId:i,teams:o,isLoading:n=!1,paginationMeta:d,currentPage:c=1,pageSize:m=50,onPageChange:u})=>{let h,p,g,f,[_,j]=(0,x.useState)({}),[y,b]=(0,x.useState)([]),[v,N]=(0,x.useState)(!1),[w,C]=(0,x.useState)(!1),[k,S]=(0,x.useState)(null),[F,P]=(0,x.useState)(!1),[M,A]=(0,x.useState)(null);(0,x.useRef)(null),(0,x.useEffect)(()=>{e&&s?.data&&(async()=>{let t={};s.data.forEach(e=>{let l=e.model_info?.id;l&&(t[l]={status:"none",lastCheck:"None",lastSuccess:"None",loading:!1,error:void 0,fullError:void 0,successResponse:void 0})});try{let a=await (0,l.latestHealthChecksCall)(e);a&&a.latest_health_checks&&"object"==typeof a.latest_health_checks&&Object.entries(a.latest_health_checks).forEach(([e,l])=>{if(!l||!s.data.some(t=>t.model_info?.id===e))return;let a=l.error_message||void 0;t[e]={status:l.status||"unknown",lastCheck:l.checked_at?new Date(l.checked_at).toLocaleString():"None",lastSuccess:"healthy"===l.status&&l.checked_at?new Date(l.checked_at).toLocaleString():"None",loading:!1,error:a?E(a):void 0,fullError:a,successResponse:"healthy"===l.status?l:void 0}})}catch(e){console.warn("Failed to load health check history (using default states):",e)}j(t)})()},[e,s]);let E=e=>{if(!e)return"Health check failed";let t="string"==typeof e?e:JSON.stringify(e),l=t.match(/(\w+Error):\s*(\d{3})/i);if(l)return`${l[1]}: ${l[2]}`;let s=t.match(/(AuthenticationError|RateLimitError|BadRequestError|InternalServerError|TimeoutError|NotFoundError|ForbiddenError|ServiceUnavailableError|BadGatewayError|ContentPolicyViolationError|\w+Error)/i),a=t.match(/\b(400|401|403|404|408|429|500|502|503|504)\b/);if(s&&a)return`${s[1]}: ${a[1]}`;if(a){let e=a[1];return`${({400:"BadRequestError",401:"AuthenticationError",403:"ForbiddenError",404:"NotFoundError",408:"TimeoutError",429:"RateLimitError",500:"InternalServerError",502:"BadGatewayError",503:"ServiceUnavailableError",504:"GatewayTimeoutError"})[e]}: ${e}`}if(s){let e=s[1],t={AuthenticationError:"401",RateLimitError:"429",BadRequestError:"400",InternalServerError:"500",TimeoutError:"408",NotFoundError:"404",ForbiddenError:"403",ServiceUnavailableError:"503",BadGatewayError:"502",GatewayTimeoutError:"504",ContentPolicyViolationError:"400"}[e];return t?`${e}: ${t}`:e}for(let{pattern:e,replacement:l}of tX)if(e.test(t))return l;if(/missing.*api.*key|invalid.*key|unauthorized/i.test(t))return"AuthenticationError: 401";if(/rate.*limit|too.*many.*requests/i.test(t))return"RateLimitError: 429";if(/timeout|timed.*out/i.test(t))return"TimeoutError: 408";if(/not.*found/i.test(t))return"NotFoundError: 404";if(/forbidden|access.*denied/i.test(t))return"ForbiddenError: 403";if(/internal.*server.*error/i.test(t))return"InternalServerError: 500";let r=t.replace(/[\n\r]+/g," ").replace(/\s+/g," ").trim(),i=r.split(/[.!?]/),o=i[0]?.trim();return o&&o.length>0?o.length>100?o.substring(0,97)+"...":o:r.length>100?r.substring(0,97)+"...":r},L=async t=>{if(e){j(e=>({...e,[t]:{...e[t],loading:!0,status:"checking"}}));try{let s=await (0,l.individualModelHealthCheckCall)(e,t),a=new Date().toLocaleString();if(s.unhealthy_count>0&&s.unhealthy_endpoints&&s.unhealthy_endpoints.length>0){let e=s.unhealthy_endpoints[0]?.error||"Health check failed",l=E(e);j(s=>({...s,[t]:{status:"unhealthy",lastCheck:a,lastSuccess:s[t]?.lastSuccess||"None",loading:!1,error:l,fullError:e}}))}else j(e=>({...e,[t]:{status:"healthy",lastCheck:a,lastSuccess:a,loading:!1,successResponse:s}}));try{let s=await (0,l.latestHealthChecksCall)(e),a=s.latest_health_checks?.[t];if(a){let e=a.error_message||void 0;j(l=>({...l,[t]:{status:a.status||l[t]?.status||"unknown",lastCheck:a.checked_at?new Date(a.checked_at).toLocaleString():l[t]?.lastCheck||"None",lastSuccess:"healthy"===a.status&&a.checked_at?new Date(a.checked_at).toLocaleString():l[t]?.lastSuccess||"None",loading:!1,error:e?E(e):l[t]?.error,fullError:e||l[t]?.fullError,successResponse:"healthy"===a.status?a:l[t]?.successResponse}}))}}catch(e){}}catch(a){let e=new Date().toLocaleString(),l=a instanceof Error?a.message:String(a),s=E(l);j(a=>({...a,[t]:{status:"unhealthy",lastCheck:e,lastSuccess:a[t]?.lastSuccess||"None",loading:!1,error:s,fullError:l}}))}}},R=async()=>{let t=y.length>0?y:a,s=t.reduce((e,t)=>(e[t]={..._[t],loading:!0,status:"checking"},e),{});j(e=>({...e,...s}));let r={},i=t.map(async t=>{if(e)try{let s=await (0,l.individualModelHealthCheckCall)(e,t);r[t]=s;let a=new Date().toLocaleString();if(s.unhealthy_count>0&&s.unhealthy_endpoints&&s.unhealthy_endpoints.length>0){let e=s.unhealthy_endpoints[0]?.error||"Health check failed",l=E(e);j(s=>({...s,[t]:{status:"unhealthy",lastCheck:a,lastSuccess:s[t]?.lastSuccess||"None",loading:!1,error:l,fullError:e}}))}else j(e=>({...e,[t]:{status:"healthy",lastCheck:a,lastSuccess:a,loading:!1,successResponse:s}}))}catch(a){console.error(`Health check failed for model id ${t}:`,a);let e=new Date().toLocaleString(),l=a instanceof Error?a.message:String(a),s=E(l);j(a=>({...a,[t]:{status:"unhealthy",lastCheck:e,lastSuccess:a[t]?.lastSuccess||"None",loading:!1,error:s,fullError:l}}))}});await Promise.allSettled(i);try{if(!e)return;let s=await (0,l.latestHealthChecksCall)(e);s.latest_health_checks&&Object.entries(s.latest_health_checks).forEach(([e,l])=>{if(t.includes(e)&&l){let t=l.error_message||void 0;j(s=>{let a=s[e];return{...s,[e]:{status:l.status||a?.status||"unknown",lastCheck:l.checked_at?new Date(l.checked_at).toLocaleString():a?.lastCheck||"None",lastSuccess:"healthy"===l.status&&l.checked_at?new Date(l.checked_at).toLocaleString():a?.lastSuccess||"None",loading:!1,error:t?E(t):a?.error,fullError:t||a?.fullError,successResponse:"healthy"===l.status?l:a?.successResponse}}})}})}catch(e){console.warn("Failed to fetch updated health statuses from database (non-critical):",e)}},B=e=>{N(e),e?b(a):b([])},z=e=>{b([]),N(!1),j({}),u?.(e)},q=()=>{C(!1),S(null)},V=()=>{P(!1),A(null)},D=(s?.data??[]).map(e=>{let t=e.model_info?.id,l=(t?_[t]:null)||{status:"none",lastCheck:"None",loading:!1};return{model_name:e.model_name,model_info:e.model_info,provider:e.provider,litellm_model_name:e.litellm_model_name,health_status:l.status,last_check:l.lastCheck,last_success:l.lastSuccess||"None",health_loading:l.loading,health_error:l.error,health_full_error:l.fullError}}),H=!!(d&&u),G=d?.total_count??0,U=d?.total_pages??1,$=d?.current_page??c,K=d?.size??m,J=H&&G>0?($-1)*K+1:0,W=H?Math.min($*K,G):0;return(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"mb-6",children:(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(eu.Title,{children:"Model Health Status"}),(0,t.jsx)(em.Text,{className:"text-gray-600 mt-1",children:"Run health checks on individual models to verify they are working correctly"})]}),(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[y.length>0&&(0,t.jsx)(I.Button,{size:"sm",variant:"light",onClick:()=>B(!1),className:"px-3 py-1 text-sm",children:"Clear Selection"}),(0,t.jsx)(I.Button,{size:"sm",variant:"secondary",onClick:R,disabled:Object.values(_).some(e=>e.loading),className:"px-3 py-1 text-sm",children:y.length>0&&y.length0?`Showing ${J} - ${W} of ${G} results`:"Showing 0 results"}),(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("button",{onClick:()=>z(c-1),disabled:n||1===c,className:`px-3 py-1 text-sm border rounded-md ${n||1===c?"bg-gray-100 text-gray-400 cursor-not-allowed":"hover:bg-gray-50"}`,children:"Previous"}),(0,t.jsx)("button",{onClick:()=>z(c+1),disabled:n||c>=U,className:`px-3 py-1 text-sm border rounded-md ${n||c>=U?"bg-gray-100 text-gray-400 cursor-not-allowed":"hover:bg-gray-50"}`,children:"Next"})]})]}),(0,t.jsx)(tJ.ModelDataTable,{columns:(h=(e,t)=>{t?b(t=>[...t,e]):(b(t=>t.filter(t=>t!==e)),N(!1))},p=e=>{switch(e){case"healthy":return(0,t.jsx)(T.Badge,{color:"emerald",children:"healthy"});case"unhealthy":return(0,t.jsx)(T.Badge,{color:"red",children:"unhealthy"});case"checking":return(0,t.jsx)(T.Badge,{color:"blue",children:"checking"});case"none":return(0,t.jsx)(T.Badge,{color:"gray",children:"none"});default:return(0,t.jsx)(T.Badge,{color:"gray",children:"unknown"})}},g=(e,t,l)=>{S({modelName:e,cleanedError:t,fullError:l}),C(!0)},f=(e,t)=>{A({modelName:e,response:t}),P(!0)},[{header:()=>(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(tW.Checkbox,{checked:v,indeterminate:y.length>0&&!v,onChange:e=>B(e.target.checked),onClick:e=>e.stopPropagation()}),(0,t.jsx)("span",{children:"Model ID"})]}),accessorKey:"model_info.id",enableSorting:!0,sortingFn:"alphanumeric",cell:({row:e})=>{let l=e.original,s=l.model_info?.id??"",a=y.includes(s);return(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(tW.Checkbox,{checked:a,onChange:e=>h(s,e.target.checked),onClick:e=>e.stopPropagation()}),(0,t.jsx)(O.Tooltip,{title:l.model_info.id,children:(0,t.jsx)("div",{className:"font-mono text-blue-500 bg-blue-50 hover:bg-blue-100 text-xs font-normal px-2 py-0.5 text-left w-full truncate whitespace-nowrap cursor-pointer max-w-[15ch]",onClick:()=>i&&i(l.model_info.id),children:l.model_info.id})})]})}},{header:"Model Name",accessorKey:"model_name",enableSorting:!0,sortingFn:"alphanumeric",cell:({row:e})=>{let l=e.original,s=r(l)||l.model_name;return(0,t.jsx)("div",{className:"font-medium text-sm",children:(0,t.jsx)(O.Tooltip,{title:s,children:(0,t.jsx)("div",{className:"truncate max-w-[200px]",children:s})})})}},{header:"Team Alias",accessorKey:"model_info.team_id",enableSorting:!0,sortingFn:"alphanumeric",cell:({row:e})=>{let l=e.original,s=l.model_info?.team_id;if(!s)return(0,t.jsx)("span",{className:"text-gray-400 text-sm",children:"-"});let a=o?.find(e=>e.team_id===s),r=a?.team_alias||s;return(0,t.jsx)("div",{className:"text-sm",children:(0,t.jsx)(O.Tooltip,{title:r,children:(0,t.jsx)("div",{className:"truncate max-w-[150px]",children:r})})})}},{header:"Health Status",accessorKey:"health_status",enableSorting:!0,sortingFn:(e,t,l)=>{let s=e.getValue("health_status")||"unknown",a=t.getValue("health_status")||"unknown",r={healthy:0,checking:1,unknown:2,unhealthy:3};return(r[s]??4)-(r[a]??4)},cell:({row:e})=>{let l=e.original,s={status:l.health_status,loading:l.health_loading,error:l.health_error};if(s.loading)return(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsxs)("div",{className:"flex space-x-1",children:[(0,t.jsx)("div",{className:"w-2 h-2 bg-indigo-500 rounded-full animate-pulse"}),(0,t.jsx)("div",{className:"w-2 h-2 bg-indigo-500 rounded-full animate-pulse",style:{animationDelay:"0.2s"}}),(0,t.jsx)("div",{className:"w-2 h-2 bg-indigo-500 rounded-full animate-pulse",style:{animationDelay:"0.4s"}})]}),(0,t.jsx)(em.Text,{className:"text-gray-600 text-sm",children:"Checking..."})]});let a=l.model_info?.id??"",i=r(l)||l.model_name,o="healthy"===s.status&&_[a]?.successResponse;return(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[p(s.status),o&&f&&(0,t.jsx)(O.Tooltip,{title:"View response details",placement:"top",children:(0,t.jsx)("button",{onClick:()=>f(i,_[a]?.successResponse),className:"p-1 text-green-600 hover:text-green-800 hover:bg-green-50 rounded-sm cursor-pointer transition-colors",children:(0,t.jsx)(tQ.InformationCircleIcon,{className:"h-4 w-4"})})})]})}},{header:"Error Details",accessorKey:"health_error",enableSorting:!1,cell:({row:e})=>{let l=e.original,s=l.model_info?.id??"",a=r(l)||l.model_name,i=_[s];if(!i?.error)return(0,t.jsx)(em.Text,{className:"text-gray-400 text-sm",children:"No errors"});let o=i.error,n=i.fullError||i.error;return(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("div",{className:"max-w-[200px]",children:(0,t.jsx)(O.Tooltip,{title:o,placement:"top",children:(0,t.jsx)(em.Text,{className:"text-red-600 text-sm truncate",children:o})})}),g&&n!==o&&(0,t.jsx)(O.Tooltip,{title:"View full error details",placement:"top",children:(0,t.jsx)("button",{onClick:()=>g(a,o,n),className:"p-1 text-red-600 hover:text-red-800 hover:bg-red-50 rounded-sm cursor-pointer transition-colors",children:(0,t.jsx)(tQ.InformationCircleIcon,{className:"h-4 w-4"})})})]})}},{header:"Last Check",accessorKey:"last_check",enableSorting:!0,sortingFn:(e,t,l)=>{let s=e.getValue("last_check")||"Never checked",a=t.getValue("last_check")||"Never checked";if("Never checked"===s&&"Never checked"===a)return 0;if("Never checked"===s)return 1;if("Never checked"===a)return -1;if("Check in progress..."===s&&"Check in progress..."===a)return 0;if("Check in progress..."===s)return -1;if("Check in progress..."===a)return 1;let r=new Date(s),i=new Date(a);return isNaN(r.getTime())&&isNaN(i.getTime())?0:isNaN(r.getTime())?1:isNaN(i.getTime())?-1:i.getTime()-r.getTime()},cell:({row:e})=>{let l=e.original;return(0,t.jsx)(em.Text,{className:"text-gray-600 text-sm",children:l.health_loading?"Check in progress...":l.last_check})}},{header:"Last Success",accessorKey:"last_success",enableSorting:!0,sortingFn:(e,t,l)=>{let s=e.getValue("last_success")||"Never succeeded",a=t.getValue("last_success")||"Never succeeded";if("Never succeeded"===s&&"Never succeeded"===a)return 0;if("Never succeeded"===s)return 1;if("Never succeeded"===a)return -1;if("None"===s&&"None"===a)return 0;if("None"===s)return 1;if("None"===a)return -1;let r=new Date(s),i=new Date(a);return isNaN(r.getTime())&&isNaN(i.getTime())?0:isNaN(r.getTime())?1:isNaN(i.getTime())?-1:i.getTime()-r.getTime()},cell:({row:e})=>{let l=e.original,s=_[l.model_info?.id??""],a=s?.lastSuccess||"None";return(0,t.jsx)(em.Text,{className:"text-gray-600 text-sm",children:a})}},{header:"Actions",id:"actions",cell:({row:e})=>{let l=e.original,s=l.model_info?.id??"",a=l.health_status&&"none"!==l.health_status,r=l.health_loading?"Checking...":a?"Re-run Health Check":"Run Health Check";return(0,t.jsx)(O.Tooltip,{title:r,placement:"top",children:(0,t.jsx)("button",{"data-testid":"run-health-check-btn",className:`p-2 rounded-md transition-colors ${l.health_loading?"text-gray-400 cursor-not-allowed bg-gray-100":"text-indigo-600 hover:text-indigo-700 hover:bg-indigo-50"}`,onClick:()=>{l.health_loading||L(s)},disabled:l.health_loading,children:l.health_loading?(0,t.jsxs)("div",{className:"flex space-x-1",children:[(0,t.jsx)("div",{className:"w-1 h-1 bg-gray-400 rounded-full animate-pulse"}),(0,t.jsx)("div",{className:"w-1 h-1 bg-gray-400 rounded-full animate-pulse",style:{animationDelay:"0.2s"}}),(0,t.jsx)("div",{className:"w-1 h-1 bg-gray-400 rounded-full animate-pulse",style:{animationDelay:"0.4s"}})]}):a?(0,t.jsx)(e2.RefreshIcon,{className:"h-4 w-4"}):(0,t.jsx)(tY.PlayIcon,{className:"h-4 w-4"})})})},enableSorting:!1}]),data:D,isLoading:n})]}),(0,t.jsx)(es.Modal,{title:k?`Health Check Error - ${k.modelName}`:"Error Details",open:w,onCancel:q,footer:[(0,t.jsx)(Q.Button,{onClick:q,children:"Close"},"close")],width:800,children:k&&(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Error:"}),(0,t.jsx)("div",{className:"mt-2 p-3 bg-red-50 border border-red-200 rounded-md",children:(0,t.jsx)(em.Text,{className:"text-red-800",children:k.cleanedError})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Full Error Details:"}),(0,t.jsx)("div",{className:"mt-2 p-3 bg-gray-50 border border-gray-200 rounded-md max-h-96 overflow-y-auto",children:(0,t.jsx)("pre",{className:"text-sm text-gray-800 whitespace-pre-wrap",children:k.fullError})})]})]})}),(0,t.jsx)(es.Modal,{title:M?`Health Check Response - ${M.modelName}`:"Response Details",open:F,onCancel:V,footer:[(0,t.jsx)(Q.Button,{onClick:V,children:"Close"},"close")],width:800,children:M&&(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Status:"}),(0,t.jsx)("div",{className:"mt-2 p-3 bg-green-50 border border-green-200 rounded-md",children:(0,t.jsx)(em.Text,{className:"text-green-800",children:"Health check passed successfully"})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Response Details:"}),(0,t.jsx)("div",{className:"mt-2 p-3 bg-gray-50 border border-gray-200 rounded-md max-h-96 overflow-y-auto",children:(0,t.jsx)("pre",{className:"text-sm text-gray-800 whitespace-pre-wrap",children:JSON.stringify(M.response,null,2)})})]})]})})]})};var t0=e.i(250980),t1=e.i(797672),t2=e.i(871943),t4=e.i(502547);let t5=({accessToken:e,initialModelGroupAlias:s={},onAliasUpdate:a})=>{let[r,i]=(0,x.useState)([]),[o,n]=(0,x.useState)({aliasName:"",targetModelGroup:""}),[d,c]=(0,x.useState)(null),[m,u]=(0,x.useState)(!0);(0,x.useEffect)(()=>{i(Object.entries(s).map(([e,t],l)=>({id:`${l}-${e}`,aliasName:e,targetModelGroup:"string"==typeof t?t:t?.model??""})))},[s]);let h=async t=>{if(!e)return console.error("Access token is missing"),!1;try{let s={};return t.forEach(e=>{s[e.aliasName]=e.targetModelGroup}),await (0,l.setCallbacksCall)(e,{router_settings:{model_group_alias:s}}),a&&a(s),!0}catch(e){return console.error("Failed to save model group alias settings:",e),G.default.fromBackend("Failed to save model group alias settings"),!1}},p=async()=>{if(!o.aliasName||!o.targetModelGroup)return void G.default.fromBackend("Please provide both alias name and target model group");if(r.some(e=>e.aliasName===o.aliasName))return void G.default.fromBackend("An alias with this name already exists");let e=[...r,{id:`${Date.now()}-${o.aliasName}`,aliasName:o.aliasName,targetModelGroup:o.targetModelGroup}];await h(e)&&(i(e),n({aliasName:"",targetModelGroup:""}),G.default.success("Alias added successfully"))},v=async()=>{if(!d)return;if(!d.aliasName||!d.targetModelGroup)return void G.default.fromBackend("Please provide both alias name and target model group");if(r.some(e=>e.id!==d.id&&e.aliasName===d.aliasName))return void G.default.fromBackend("An alias with this name already exists");let e=r.map(e=>e.id===d.id?d:e);await h(e)&&(i(e),c(null),G.default.success("Alias updated successfully"))},N=()=>{c(null)},w=async e=>{let t=r.filter(t=>t.id!==e);await h(t)&&(i(t),G.default.success("Alias deleted successfully"))},C=r.reduce((e,t)=>(e[t.aliasName]=t.targetModelGroup,e),{});return(0,t.jsxs)(eL.Card,{className:"mb-6",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between cursor-pointer",onClick:()=>u(!m),children:[(0,t.jsxs)("div",{className:"flex flex-col",children:[(0,t.jsx)(eu.Title,{className:"mb-0",children:"Model Group Alias Settings"}),(0,t.jsx)("p",{className:"text-sm text-gray-500",children:"Create aliases for your model groups to simplify API calls. For example, you can create an alias 'gpt-4o' that points to 'gpt-4o-mini-openai' model group."})]}),(0,t.jsx)("div",{className:"flex items-center",children:m?(0,t.jsx)(t2.ChevronDownIcon,{className:"w-5 h-5 text-gray-500"}):(0,t.jsx)(t4.ChevronRightIcon,{className:"w-5 h-5 text-gray-500"})})]}),m&&(0,t.jsxs)("div",{className:"mt-4",children:[(0,t.jsxs)("div",{className:"mb-6",children:[(0,t.jsx)(em.Text,{className:"text-sm font-medium text-gray-700 mb-2",children:"Add New Alias"}),(0,t.jsxs)("div",{className:"grid grid-cols-3 gap-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Alias Name"}),(0,t.jsx)("input",{type:"text",value:o.aliasName,onChange:e=>n({...o,aliasName:e.target.value}),placeholder:"e.g., gpt-4o",className:"w-full px-3 py-2 border border-gray-300 rounded-md text-sm"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs text-gray-500 mb-1",children:"Target Model Group"}),(0,t.jsx)("input",{type:"text",value:o.targetModelGroup,onChange:e=>n({...o,targetModelGroup:e.target.value}),placeholder:"e.g., gpt-4o-mini-openai",className:"w-full px-3 py-2 border border-gray-300 rounded-md text-sm"})]}),(0,t.jsx)("div",{className:"flex items-end",children:(0,t.jsxs)("button",{onClick:p,disabled:!o.aliasName||!o.targetModelGroup,className:`flex items-center px-4 py-2 rounded-md text-sm ${!o.aliasName||!o.targetModelGroup?"bg-gray-300 text-gray-500 cursor-not-allowed":"bg-green-600 text-white hover:bg-green-700"}`,children:[(0,t.jsx)(t0.PlusCircleIcon,{className:"w-4 h-4 mr-1"}),"Add Alias"]})})]})]}),(0,t.jsx)(em.Text,{className:"text-sm font-medium text-gray-700 mb-2",children:"Manage Existing Aliases"}),(0,t.jsx)("div",{className:"rounded-lg custom-border relative mb-6",children:(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsxs)(g.Table,{className:"[&_td]:py-0.5 [&_th]:py-1",children:[(0,t.jsx)(f.TableHead,{children:(0,t.jsxs)(y.TableRow,{children:[(0,t.jsx)(_.TableHeaderCell,{className:"py-1 h-8",children:"Alias Name"}),(0,t.jsx)(_.TableHeaderCell,{className:"py-1 h-8",children:"Target Model Group"}),(0,t.jsx)(_.TableHeaderCell,{className:"py-1 h-8",children:"Actions"})]})}),(0,t.jsxs)(j.TableBody,{children:[r.map(e=>(0,t.jsx)(y.TableRow,{className:"h-8",children:d&&d.id===e.id?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(b.TableCell,{className:"py-0.5",children:(0,t.jsx)("input",{type:"text",value:d.aliasName,onChange:e=>c({...d,aliasName:e.target.value}),className:"w-full px-2 py-1 border border-gray-300 rounded-md text-sm"})}),(0,t.jsx)(b.TableCell,{className:"py-0.5",children:(0,t.jsx)("input",{type:"text",value:d.targetModelGroup,onChange:e=>c({...d,targetModelGroup:e.target.value}),className:"w-full px-2 py-1 border border-gray-300 rounded-md text-sm"})}),(0,t.jsx)(b.TableCell,{className:"py-0.5 whitespace-nowrap",children:(0,t.jsxs)("div",{className:"flex space-x-2",children:[(0,t.jsx)("button",{onClick:v,className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded-sm hover:bg-blue-100",children:"Save"}),(0,t.jsx)("button",{onClick:N,className:"text-xs bg-gray-50 text-gray-600 px-2 py-1 rounded-sm hover:bg-gray-100",children:"Cancel"})]})})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(b.TableCell,{className:"py-0.5 text-sm text-gray-900",children:e.aliasName}),(0,t.jsx)(b.TableCell,{className:"py-0.5 text-sm text-gray-500",children:e.targetModelGroup}),(0,t.jsx)(b.TableCell,{className:"py-0.5 whitespace-nowrap",children:(0,t.jsxs)("div",{className:"flex space-x-2",children:[(0,t.jsx)("button",{onClick:()=>{c({...e})},className:"text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded-sm hover:bg-blue-100",children:(0,t.jsx)(t1.PencilIcon,{className:"w-3 h-3"})}),(0,t.jsx)("button",{onClick:()=>w(e.id),className:"text-xs bg-red-50 text-red-600 px-2 py-1 rounded-sm hover:bg-red-100",children:(0,t.jsx)(S.TrashIcon,{className:"w-3 h-3"})})]})})]})},e.id)),0===r.length&&(0,t.jsx)(y.TableRow,{children:(0,t.jsx)(b.TableCell,{colSpan:3,className:"py-0.5 text-sm text-gray-500 text-center",children:"No aliases added yet. Add a new alias above."})})]})]})})}),(0,t.jsxs)(eL.Card,{children:[(0,t.jsx)(eu.Title,{className:"mb-4",children:"Configuration Example"}),(0,t.jsx)(em.Text,{className:"text-gray-600 mb-4",children:"Here's how your current aliases would look in the config.yaml:"}),(0,t.jsx)("div",{className:"bg-gray-100 rounded-lg p-4 font-mono text-sm",children:(0,t.jsxs)("div",{className:"text-gray-700",children:["router_settings:",(0,t.jsx)("br",{}),"  model_group_alias:",0===Object.keys(C).length?(0,t.jsxs)("span",{className:"text-gray-500",children:[(0,t.jsx)("br",{}),"    # No aliases configured yet"]}):Object.entries(C).map(([e,l])=>(0,t.jsxs)("span",{children:[(0,t.jsx)("br",{}),'    "',e,'": "',l,'"']},e))]})})]})]})]})};var t6=e.i(530212);let t3=x.forwardRef(function(e,t){return x.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),x.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"}))});var t8=e.i(678784),t7=e.i(118366),t9=e.i(500330);let le=({isVisible:e,onCancel:s,onSuccess:a,modelData:r,accessToken:i,userRole:o})=>{let[n]=el.Form.useForm(),[d,c]=(0,x.useState)(!1),[m,u]=(0,x.useState)([]),[h,p]=(0,x.useState)([]),[g,f]=(0,x.useState)(!1),[_,j]=(0,x.useState)(!1),[y,b]=(0,x.useState)(null);(0,x.useEffect)(()=>{e&&r&&v()},[e,r]),(0,x.useEffect)(()=>{let t=async()=>{if(i)try{let e=await (0,l.modelAvailableCall)(i,"","",!1,null,!0,!0);u(e.data.map(e=>e.id))}catch(e){console.error("Error fetching model access groups:",e)}},s=async()=>{if(i)try{let e=await (0,tr.fetchAvailableModels)(i);p(e)}catch(e){console.error("Error fetching model info:",e)}};e&&(t(),s())},[e,i]);let v=()=>{try{let e=null;r.litellm_params?.auto_router_config&&(e="string"==typeof r.litellm_params.auto_router_config?JSON.parse(r.litellm_params.auto_router_config):r.litellm_params.auto_router_config),b(e),n.setFieldsValue({auto_router_name:r.model_name,auto_router_default_model:r.litellm_params?.auto_router_default_model||"",auto_router_embedding_model:r.litellm_params?.auto_router_embedding_model||"",model_access_group:r.model_info?.access_groups||[]});let t=new Set(h.map(e=>e.model_group));f(!t.has(r.litellm_params?.auto_router_default_model)),j(!t.has(r.litellm_params?.auto_router_embedding_model))}catch(e){console.error("Error parsing auto router config:",e),G.default.fromBackend("Error loading auto router configuration")}},N=async()=>{try{c(!0);let e=await n.validateFields(),t={...r.litellm_params,auto_router_config:JSON.stringify(y),auto_router_default_model:e.auto_router_default_model,auto_router_embedding_model:e.auto_router_embedding_model||void 0},o={...r.model_info,access_groups:e.model_access_group||[]},d={model_name:e.auto_router_name,litellm_params:t,model_info:o};await (0,l.modelPatchUpdateCall)(i,d,r.model_info.id);let m={...r,model_name:e.auto_router_name,litellm_params:t,model_info:o};G.default.success("Auto router configuration updated successfully"),a(m),s()}catch(e){console.error("Error updating auto router:",e),G.default.fromBackend("Failed to update auto router configuration")}finally{c(!1)}},w=h.map(e=>({value:e.model_group,label:e.model_group}));return(0,t.jsx)(es.Modal,{title:"Edit Auto Router Configuration",open:e,onCancel:s,footer:[(0,t.jsx)(Q.Button,{onClick:s,children:"Cancel"},"cancel"),(0,t.jsx)(Q.Button,{loading:d,onClick:N,children:"Save Changes"},"submit")],width:1e3,destroyOnHidden:!0,children:(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsx)(em.Text,{className:"text-gray-600",children:"Edit the auto router configuration including routing logic, default models, and access settings."}),(0,t.jsxs)(el.Form,{form:n,layout:"vertical",className:"space-y-4",children:[(0,t.jsx)(el.Form.Item,{label:"Auto Router Name",name:"auto_router_name",rules:[{required:!0,message:"Auto router name is required"}],children:(0,t.jsx)(eO.TextInput,{placeholder:"e.g., auto_router_1, smart_routing"})}),(0,t.jsx)("div",{className:"w-full",children:(0,t.jsx)(tu,{modelInfo:h,value:y,onChange:e=>{b(e)}})}),(0,t.jsx)(el.Form.Item,{label:"Default Model",name:"auto_router_default_model",rules:[{required:!0,message:"Default model is required"}],children:(0,t.jsx)(Y.Select,{placeholder:"Select a default model",onChange:e=>{f("custom"===e)},options:[...w,{value:"custom",label:"Enter custom model name"}],showSearch:!0})}),(0,t.jsx)(el.Form.Item,{label:"Embedding Model",name:"auto_router_embedding_model",children:(0,t.jsx)(Y.Select,{placeholder:"Select an embedding model (optional)",onChange:e=>{j("custom"===e)},options:[...w,{value:"custom",label:"Enter custom model name"}],showSearch:!0,allowClear:!0})}),"Admin"===o&&(0,t.jsx)(el.Form.Item,{label:"Model Access Groups",name:"model_access_group",tooltip:"Control who can access this auto router",children:(0,t.jsx)(Y.Select,{mode:"tags",showSearch:!0,placeholder:"Select existing groups or type to create new ones",optionFilterProp:"children",tokenSeparators:[","],options:m.map(e=>({value:e,label:e})),maxTagCount:"responsive",allowClear:!0})})]})]})})},{Title:lt,Link:ll}=R.Typography,ls=({isVisible:e,onCancel:l,onAddCredential:s,existingCredential:a,setIsCredentialModalOpen:r})=>{let[i]=el.Form.useForm();return(0,t.jsx)(es.Modal,{title:"Reuse Credentials",open:e,onCancel:()=>{l(),i.resetFields()},footer:null,width:600,children:(0,t.jsxs)(el.Form,{form:i,onFinish:e=>{s(e),i.resetFields(),r(!1)},layout:"vertical",children:[(0,t.jsx)(el.Form.Item,{label:"Credential Name:",name:"credential_name",rules:[{required:!0,message:"Credential name is required"}],initialValue:a?.credential_name,children:(0,t.jsx)(eO.TextInput,{placeholder:"Enter a friendly name for these credentials"})}),Object.entries(a?.credential_values||{}).map(([e,l])=>(0,t.jsx)(el.Form.Item,{label:e,name:e,initialValue:l,children:(0,t.jsx)(eO.TextInput,{placeholder:`Enter ${e}`,disabled:!0})},e)),(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsx)(O.Tooltip,{title:"Get help on our github",children:(0,t.jsx)(ll,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})}),(0,t.jsxs)("div",{children:[(0,t.jsx)(Q.Button,{onClick:()=>{l(),i.resetFields()},style:{marginRight:10},children:"Cancel"}),(0,t.jsx)(Q.Button,{htmlType:"submit",children:"Reuse Credentials"})]})]})]})})},{Text:la}=R.Typography;function lr({open:e,onCancel:s,accessToken:a,modelId:r,onUpdated:i}){let[o]=el.Form.useForm(),[n,d]=(0,x.useState)(!1),c=()=>{o.resetFields(),s()},m=async e=>{let t=e.api_key?.trim();if(!t)return void G.default.fromBackend("Enter a new API key");d(!0);try{await (0,l.modelPatchUpdateCall)(a,{litellm_params:{api_key:t},model_info:{id:r}},r),G.default.success("API key updated"),o.resetFields(),i(),s()}catch(e){console.error("Error updating API key:",e),G.default.fromBackend("Failed to update API key")}finally{d(!1)}};return(0,t.jsxs)(es.Modal,{title:"Update API Key",open:e,onCancel:c,footer:null,width:520,destroyOnHidden:!0,children:[(0,t.jsx)(la,{className:"block mb-4 text-gray-500",children:"Update this model's API key. Only the new key is sent; the rest of the deployment configuration is left untouched."}),(0,t.jsx)(tw.Alert,{type:"warning",showIcon:!0,className:"mb-4",message:"Only the API key is rotated here. Models that authenticate with an Azure AD token, AWS credentials, or a Vertex service-account JSON aren't supported yet; update those from the model's LiteLLM Params for now."}),(0,t.jsxs)(el.Form,{form:o,onFinish:m,layout:"vertical",children:[(0,t.jsx)(el.Form.Item,{label:"New API Key",name:"api_key",rules:[{required:!0,message:"Enter a new API key"}],children:(0,t.jsx)(eV.Input.Password,{placeholder:"Enter the new API key",autoComplete:"new-password"})}),(0,t.jsxs)("div",{className:"flex justify-end items-center mt-4",children:[(0,t.jsx)(Q.Button,{onClick:c,style:{marginRight:10},children:"Cancel"}),(0,t.jsx)(Q.Button,{type:"primary",htmlType:"submit",loading:n,children:"Update API Key"})]})]})]})}let li=e=>"string"==typeof e&&/\*{2,}/.test(e);function lo({modelId:e,onClose:s,accessToken:a,userID:r,userRole:i,onModelUpdate:o,modelAccessGroups:c}){let m,[u]=el.Form.useForm(),h=(0,$.useQueryClient)(),[p,g]=(0,x.useState)(null),[f,_]=(0,x.useState)(!1),[j,y]=(0,x.useState)(!1),[b,v]=(0,x.useState)(!1),[N,w]=(0,x.useState)(!1),[k,T]=(0,x.useState)(!1),[F,P]=(0,x.useState)(!1),[M,A]=(0,x.useState)(!1),[E,L]=(0,x.useState)(null),[R,B]=(0,x.useState)(!1),[z,q]=(0,x.useState)({}),[V,U]=(0,x.useState)(!1),[W,X]=(0,x.useState)([]),[Z,ee]=(0,x.useState)({}),[et,ea]=(0,x.useState)([]),{data:er,isLoading:eo}=(0,d.useModelsInfo)(1,50,void 0,e),{data:en}=(0,n.useModelCostMap)(),{data:ed}=(0,d.useModelHub)(),ec=e=>null!=en&&"object"==typeof en&&e in en?en[e].litellm_provider:"openai",eh=(0,x.useMemo)(()=>er?.data&&0!==er.data.length&&ei(er,ec).data[0]||null,[er,en]),ep=("Admin"===i||eh?.model_info?.created_by===r)&&eh?.model_info?.db_model,ex="Admin"===i,eg=eh?.litellm_params?.auto_router_config!=null,ef=eh?.litellm_params?.litellm_credential_name!=null&&eh?.litellm_params?.litellm_credential_name!=void 0;(0,x.useEffect)(()=>{if(eh&&!p){let e=eh;e.litellm_model_name||(e={...e,litellm_model_name:e?.litellm_params?.litellm_model_name??e?.litellm_params?.model??e?.model_info?.key??null}),g(e),e?.litellm_params?.cache_control_injection_points&&B(!0)}},[eh,p]),(0,x.useEffect)(()=>{let t=async()=>{if(!a||eh)return;let t=(await (0,l.modelInfoV1Call)(a,e)).data[0];t&&!t.litellm_model_name&&(t={...t,litellm_model_name:t?.litellm_params?.litellm_model_name??t?.litellm_params?.model??t?.model_info?.key??null}),g(t),t?.litellm_params?.cache_control_injection_points&&B(!0)},s=async()=>{if(a)try{let e=(await (0,l.getGuardrailsList)(a)).guardrails.map(e=>e.guardrail_name);X(e)}catch(e){console.error("Failed to fetch guardrails:",e)}},r=async()=>{if(a)try{let e=await (0,l.tagListCall)(a);ee(e)}catch(e){console.error("Failed to fetch tags:",e)}},i=async()=>{if(a)try{let e=await (0,l.credentialListCall)(a);ea(e.credentials||[])}catch(e){console.error("Failed to fetch credentials:",e)}};(async()=>{if(!a||ef)return;let t=await (0,l.credentialGetCall)(a,null,e);L({credential_name:t.credential_name,credential_values:t.credential_values,credential_info:t.credential_info})})(),t(),s(),r(),i()},[a,e]);let e_=async t=>{if(!a)return;let s={credential_name:t.credential_name,model_id:e,credential_info:{custom_llm_provider:p.litellm_params?.custom_llm_provider}};G.default.info("Storing credential.."),await (0,l.credentialCreateCall)(a,s),G.default.success("Credential stored successfully")},ej=async t=>{try{let s;if(!a)return;P(!0);let r={};try{r=t.litellm_extra_params?JSON.parse(t.litellm_extra_params):{},delete r.litellm_credential_name}catch(e){G.default.fromBackend("Invalid JSON in LiteLLM Params"),P(!1);return}let i={...t.litellm_params,...r,model:t.litellm_model_name,api_base:t.api_base,custom_llm_provider:t.custom_llm_provider,organization:t.organization,tpm:t.tpm,rpm:t.rpm,max_retries:t.max_retries,timeout:t.timeout,stream_timeout:t.stream_timeout,tags:t.tags};u.isFieldTouched("input_cost")&&(void 0!==t.input_cost&&null!==t.input_cost&&""!==t.input_cost?i.input_cost_per_token=Number(t.input_cost)/1e6:i.input_cost_per_token=null),u.isFieldTouched("output_cost")&&(void 0!==t.output_cost&&null!==t.output_cost&&""!==t.output_cost?i.output_cost_per_token=Number(t.output_cost)/1e6:i.output_cost_per_token=null),(u.isFieldTouched("cache_read_cost")||u.isFieldTouched("input_cost"))&&(void 0!==t.cache_read_cost&&null!==t.cache_read_cost&&""!==t.cache_read_cost?i.cache_read_input_token_cost=Number(t.cache_read_cost)/1e6:u.isFieldTouched("cache_read_cost")?i.cache_read_input_token_cost=null:void 0!==i.input_cost_per_token&&null!==i.input_cost_per_token&&(i.cache_read_input_token_cost=i.input_cost_per_token)),u.isFieldTouched("cache_write_cost")&&(void 0!==t.cache_write_cost&&null!==t.cache_write_cost&&""!==t.cache_write_cost?i.cache_creation_input_token_cost=Number(t.cache_write_cost)/1e6:i.cache_creation_input_token_cost=null),t.litellm_credential_name?i.litellm_credential_name=t.litellm_credential_name:delete i.litellm_credential_name,t.guardrails&&(i.guardrails=t.guardrails),t.vector_store_ids?.length>0?i.vector_store_ids=t.vector_store_ids:void 0!==t.vector_store_ids?i.vector_store_ids=[]:delete i.vector_store_ids,t.cache_control&&t.cache_control_injection_points?.length>0?i.cache_control_injection_points=t.cache_control_injection_points:delete i.cache_control_injection_points;try{s=t.model_info?JSON.parse(t.model_info):eh.model_info,t.model_access_group&&(s={...s,access_groups:t.model_access_group}),void 0!==t.health_check_model&&(s={...s,health_check_model:t.health_check_model})}catch(e){G.default.fromBackend("Invalid JSON in Model Info");return}let n=Object.fromEntries(Object.entries(i).filter(([,e])=>!li(e))),d={model_name:t.model_name,litellm_params:n,model_info:s};await (0,l.modelPatchUpdateCall)(a,d,e);let c={...p,model_name:t.model_name,litellm_model_name:t.litellm_model_name,litellm_params:n,model_info:s};g(c),o&&o(c),G.default.success("Model settings updated successfully"),T(!1),A(!1)}catch(e){console.error("Error updating model:",e),G.default.fromBackend("Failed to update model settings")}finally{P(!1)}};if(eo)return(0,t.jsxs)("div",{className:"p-4",children:[(0,t.jsx)(I.Button,{icon:t6.ArrowLeftIcon,variant:"light",onClick:s,className:"mb-4",children:"Back to Models"}),(0,t.jsx)(em.Text,{children:"Loading..."})]});if(!eh)return(0,t.jsxs)("div",{className:"p-4",children:[(0,t.jsx)(I.Button,{icon:t6.ArrowLeftIcon,variant:"light",onClick:s,className:"mb-4",children:"Back to Models"}),(0,t.jsx)(em.Text,{children:"Model not found"})]});let ey=async()=>{if(a)try{G.default.info("Testing connection...");let e=await (0,l.testConnectionRequest)(a,{custom_llm_provider:p.litellm_params.custom_llm_provider,litellm_credential_name:p.litellm_params.litellm_credential_name,model:p.litellm_model_name},{id:p.model_info?.id,mode:p.model_info?.mode},p.model_info?.mode);if("success"===e.status)G.default.success("Connection test successful!");else throw Error(e?.result?.error||e?.message||"Unknown error")}catch(e){e instanceof Error?G.default.error("Error testing connection: "+(0,tL.truncateString)(e.message,100)):G.default.error("Error testing connection: "+String(e))}},eb=async()=>{try{if(y(!0),!a)return;await (0,l.modelDeleteCall)(a,e),G.default.success("Model deleted successfully"),o&&o({deleted:!0,model_info:{id:e}}),s()}catch(e){console.error("Error deleting the model:",e),G.default.fromBackend("Failed to delete model")}finally{y(!1),_(!1)}},ev=async(e,t)=>{await (0,t9.copyToClipboard)(e)&&(q(e=>({...e,[t]:!0})),setTimeout(()=>{q(e=>({...e,[t]:!1}))},2e3))},eN=eh.litellm_model_name.includes("*");return(0,t.jsxs)("div",{className:"p-4",children:[(0,t.jsxs)("div",{className:"flex justify-between items-center mb-6",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(I.Button,{icon:t6.ArrowLeftIcon,variant:"light",onClick:s,className:"mb-4",children:"Back to Models"}),(0,t.jsxs)(eu.Title,{children:["Public Model Name: ",D(eh)]}),(0,t.jsxs)("div",{className:"flex items-center cursor-pointer",children:[(0,t.jsx)(em.Text,{className:"text-gray-500 font-mono",children:eh.model_info.id}),(0,t.jsx)(Q.Button,{type:"text",size:"small",icon:z["model-id"]?(0,t.jsx)(t8.CheckIcon,{size:12}):(0,t.jsx)(t7.CopyIcon,{size:12}),onClick:()=>ev(eh.model_info.id,"model-id"),className:`left-2 z-10 transition-all duration-200 ${z["model-id"]?"text-green-600 bg-green-50 border-green-200":"text-gray-500 hover:text-gray-700 hover:bg-gray-100"}`})]})]}),(0,t.jsxs)("div",{className:"flex gap-2",children:[(0,t.jsx)(Q.Button,{icon:(0,t.jsx)(e2.RefreshIcon,{className:"h-4 w-4"}),onClick:ey,className:"flex items-center gap-2","data-testid":"test-connection-button",children:"Test Connection"}),(0,t.jsx)(Q.Button,{icon:(0,t.jsx)(t3,{className:"h-4 w-4"}),onClick:()=>w(!0),className:"flex items-center",disabled:!ep,"data-testid":"update-api-key-button",children:"Update API Key"}),(0,t.jsx)(Q.Button,{icon:(0,t.jsx)(t3,{className:"h-4 w-4"}),onClick:()=>v(!0),className:"flex items-center",disabled:!ex,"data-testid":"reuse-credentials-button",children:"Re-use Credentials"}),(0,t.jsx)(Q.Button,{danger:!0,icon:(0,t.jsx)(S.TrashIcon,{className:"h-4 w-4"}),onClick:()=>_(!0),className:"flex items-center",disabled:!ep,"data-testid":"delete-model-button",children:"Delete Model"})]})]}),(0,t.jsxs)(e6.TabGroup,{children:[(0,t.jsxs)(e3.TabList,{className:"mb-6",children:[(0,t.jsx)(e5.Tab,{children:"Overview"}),(0,t.jsx)(e5.Tab,{children:"Raw JSON"})]}),(0,t.jsxs)(e8.TabPanels,{children:[(0,t.jsxs)(J.TabPanel,{children:[(0,t.jsxs)(K.Grid,{numItems:1,numItemsSm:2,numItemsLg:3,className:"gap-6 mb-6",children:[(0,t.jsxs)(eL.Card,{children:[(0,t.jsx)(em.Text,{children:"Provider"}),(0,t.jsxs)("div",{className:"mt-2 flex items-center space-x-2",children:[eh.provider&&(0,t.jsx)("img",{src:(0,eP.getProviderLogoAndName)(eh.provider).logo,alt:`${eh.provider} logo`,className:"w-4 h-4",onError:e=>{let t=e.currentTarget,l=t.parentElement;if(l&&l.contains(t))try{let e=document.createElement("div");e.className="w-4 h-4 rounded-full bg-gray-200 flex items-center justify-center text-xs",e.textContent=eh.provider?.charAt(0)||"-",l.replaceChild(e,t)}catch(e){console.error("Failed to replace provider logo fallback:",e)}}}),(0,t.jsx)(eu.Title,{children:eh.provider||"Not Set"})]})]}),(0,t.jsxs)(eL.Card,{children:[(0,t.jsx)(em.Text,{children:"LiteLLM Model"}),(0,t.jsx)("div",{className:"mt-2 overflow-hidden",children:(0,t.jsx)(O.Tooltip,{title:eh.litellm_model_name||"Not Set",children:(0,t.jsx)("div",{className:"break-all text-sm font-medium leading-relaxed cursor-pointer",children:eh.litellm_model_name||"Not Set"})})})]}),(0,t.jsxs)(eL.Card,{children:[(0,t.jsx)(em.Text,{children:"Pricing"}),(0,t.jsxs)("div",{className:"mt-2",children:[(0,t.jsxs)(em.Text,{children:["Input: $",eh.input_cost,"/1M tokens"]}),(0,t.jsxs)(em.Text,{children:["Output: $",eh.output_cost,"/1M tokens"]})]})]})]}),(0,t.jsxs)("div",{className:"mb-6 text-sm text-gray-500 flex items-center gap-x-6",children:[(0,t.jsxs)("div",{className:"flex items-center gap-x-2",children:[(0,t.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"})}),"Created At"," ",eh.model_info.created_at?new Date(eh.model_info.created_at).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}):"Not Set"]}),(0,t.jsxs)("div",{className:"flex items-center gap-x-2",children:[(0,t.jsx)("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"})}),"Created By ",eh.model_info.created_by||"Not Set"]})]}),(0,t.jsxs)(eL.Card,{children:[(0,t.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,t.jsx)(eu.Title,{children:"Model Settings"}),(0,t.jsxs)("div",{className:"flex gap-2",children:[eg&&ep&&!M&&(0,t.jsx)(I.Button,{onClick:()=>U(!0),className:"flex items-center",children:"Edit Auto Router"}),ep?!M&&(0,t.jsx)(I.Button,{onClick:()=>A(!0),className:"flex items-center",children:"Edit Settings"}):(0,t.jsx)(O.Tooltip,{title:"Only DB models can be edited. You must be an admin or the creator of the model to edit it.",children:(0,t.jsx)(C.InfoCircleOutlined,{})})]})]}),p?(0,t.jsx)(el.Form,{form:u,onFinish:ej,initialValues:{model_name:p.model_name,litellm_model_name:p.litellm_model_name,api_base:p.litellm_params.api_base,custom_llm_provider:p.litellm_params.custom_llm_provider,organization:p.litellm_params.organization,tpm:p.litellm_params.tpm,rpm:p.litellm_params.rpm,max_retries:p.litellm_params.max_retries,timeout:p.litellm_params.timeout,stream_timeout:p.litellm_params.stream_timeout,input_cost:p.litellm_params.input_cost_per_token?1e6*p.litellm_params.input_cost_per_token:p.model_info?.input_cost_per_token*1e6||null,output_cost:p.litellm_params?.output_cost_per_token?1e6*p.litellm_params.output_cost_per_token:p.model_info?.output_cost_per_token*1e6||null,cache_read_cost:p.litellm_params?.cache_read_input_token_cost!==void 0&&p.litellm_params?.cache_read_input_token_cost!==null?1e6*p.litellm_params.cache_read_input_token_cost:p.model_info?.cache_read_input_token_cost!==void 0&&p.model_info?.cache_read_input_token_cost!==null?1e6*p.model_info.cache_read_input_token_cost:null,cache_write_cost:p.litellm_params?.cache_creation_input_token_cost!==void 0&&p.litellm_params?.cache_creation_input_token_cost!==null?1e6*p.litellm_params.cache_creation_input_token_cost:p.model_info?.cache_creation_input_token_cost!==void 0&&p.model_info?.cache_creation_input_token_cost!==null?1e6*p.model_info.cache_creation_input_token_cost:null,cache_control:!!p.litellm_params?.cache_control_injection_points,cache_control_injection_points:p.litellm_params?.cache_control_injection_points||[],model_access_group:Array.isArray(p.model_info?.access_groups)?p.model_info.access_groups:[],guardrails:Array.isArray(p.litellm_params?.guardrails)?p.litellm_params.guardrails:[],vector_store_ids:Array.isArray(p.litellm_params?.vector_store_ids)&&p.litellm_params.vector_store_ids.length>0?p.litellm_params.vector_store_ids:void 0,tags:Array.isArray(p.litellm_params?.tags)?p.litellm_params.tags:[],health_check_model:eN?p.model_info?.health_check_model:null,litellm_credential_name:p.litellm_params?.litellm_credential_name||"",litellm_extra_params:JSON.stringify(Object.fromEntries(Object.entries(p.litellm_params||{}).filter(([e,t])=>"litellm_credential_name"!==e&&!li(t))),null,2)},layout:"vertical",onValuesChange:()=>T(!0),children:(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Model Name"}),M?(0,t.jsx)(el.Form.Item,{name:"model_name",className:"mb-0",children:(0,t.jsx)(eO.TextInput,{placeholder:"Enter model name"})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.model_name})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"LiteLLM Model Name"}),M?(0,t.jsx)(el.Form.Item,{name:"litellm_model_name",className:"mb-0",children:(0,t.jsx)(eO.TextInput,{placeholder:"Enter LiteLLM model name"})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.litellm_model_name})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Input Cost (per 1M tokens)"}),M?(0,t.jsx)(el.Form.Item,{name:"input_cost",className:"mb-0",children:(0,t.jsx)(tP.default,{placeholder:"Enter input cost"})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p?.litellm_params?.input_cost_per_token?(p.litellm_params?.input_cost_per_token*1e6).toFixed(4):p?.model_info?.input_cost_per_token?(1e6*p.model_info.input_cost_per_token).toFixed(4):"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Output Cost (per 1M tokens)"}),M?(0,t.jsx)(el.Form.Item,{name:"output_cost",className:"mb-0",children:(0,t.jsx)(tP.default,{placeholder:"Enter output cost"})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p?.litellm_params?.output_cost_per_token?(1e6*p.litellm_params.output_cost_per_token).toFixed(4):p?.model_info?.output_cost_per_token?(1e6*p.model_info.output_cost_per_token).toFixed(4):"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Cache Read Cost (per 1M tokens)"}),M?(0,t.jsx)(el.Form.Item,{name:"cache_read_cost",className:"mb-0",tooltip:"If left blank on save, defaults to Input Cost.",children:(0,t.jsx)(tP.default,{placeholder:"Defaults to Input Cost if blank"})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p?.litellm_params?.cache_read_input_token_cost!==void 0&&p?.litellm_params?.cache_read_input_token_cost!==null?(1e6*p.litellm_params.cache_read_input_token_cost).toFixed(4):p?.model_info?.cache_read_input_token_cost!==void 0&&p?.model_info?.cache_read_input_token_cost!==null?(1e6*p.model_info.cache_read_input_token_cost).toFixed(4):"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Cache Write Cost (per 1M tokens)"}),M?(0,t.jsx)(el.Form.Item,{name:"cache_write_cost",className:"mb-0",tooltip:"If left blank on save, defaults to Input Cost (backend falls back to input_cost_per_token).",children:(0,t.jsx)(tP.default,{placeholder:"Defaults to Input Cost if blank"})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p?.litellm_params?.cache_creation_input_token_cost!==void 0&&p?.litellm_params?.cache_creation_input_token_cost!==null?(1e6*p.litellm_params.cache_creation_input_token_cost).toFixed(4):p?.model_info?.cache_creation_input_token_cost!==void 0&&p?.model_info?.cache_creation_input_token_cost!==null?(1e6*p.model_info.cache_creation_input_token_cost).toFixed(4):"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"API Base"}),M?(0,t.jsx)(el.Form.Item,{name:"api_base",className:"mb-0",children:(0,t.jsx)(eO.TextInput,{placeholder:"Enter API base"})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.litellm_params?.api_base||"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Custom LLM Provider"}),M?(0,t.jsx)(el.Form.Item,{name:"custom_llm_provider",className:"mb-0",children:(0,t.jsx)(eO.TextInput,{placeholder:"Enter custom LLM provider"})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.litellm_params?.custom_llm_provider||"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Organization"}),M?(0,t.jsx)(el.Form.Item,{name:"organization",className:"mb-0",children:(0,t.jsx)(eO.TextInput,{placeholder:"Enter organization"})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.litellm_params?.organization||"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"TPM (Tokens per Minute)"}),M?(0,t.jsx)(el.Form.Item,{name:"tpm",className:"mb-0",children:(0,t.jsx)(tP.default,{placeholder:"Enter TPM"})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.litellm_params?.tpm||"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"RPM (Requests per Minute)"}),M?(0,t.jsx)(el.Form.Item,{name:"rpm",className:"mb-0",children:(0,t.jsx)(tP.default,{placeholder:"Enter RPM"})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.litellm_params?.rpm||"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Max Retries"}),M?(0,t.jsx)(el.Form.Item,{name:"max_retries",className:"mb-0",children:(0,t.jsx)(tP.default,{placeholder:"Enter max retries"})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.litellm_params?.max_retries||"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Timeout (seconds)"}),M?(0,t.jsx)(el.Form.Item,{name:"timeout",className:"mb-0",children:(0,t.jsx)(tP.default,{placeholder:"Enter timeout"})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.litellm_params?.timeout||"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Stream Timeout (seconds)"}),M?(0,t.jsx)(el.Form.Item,{name:"stream_timeout",className:"mb-0",children:(0,t.jsx)(tP.default,{placeholder:"Enter stream timeout"})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.litellm_params?.stream_timeout||"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Model Access Groups"}),M?(0,t.jsx)(el.Form.Item,{name:"model_access_group",className:"mb-0",children:(0,t.jsx)(Y.Select,{mode:"tags",showSearch:!0,placeholder:"Select existing groups or type to create new ones",optionFilterProp:"children",tokenSeparators:[","],maxTagCount:"responsive",allowClear:!0,style:{width:"100%"},options:c?.map(e=>({value:e,label:e}))})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.model_info?.access_groups?Array.isArray(p.model_info.access_groups)?p.model_info.access_groups.length>0?(0,t.jsx)("div",{className:"flex flex-wrap gap-1",children:p.model_info.access_groups.map((e,l)=>(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800",children:e},l))}):"No groups assigned":p.model_info.access_groups:"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsxs)(em.Text,{className:"font-medium",children:["Guardrails",(0,t.jsx)(O.Tooltip,{title:"Apply safety guardrails to this model to filter content or enforce policies",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/guardrails/quick_start",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(C.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),M?(0,t.jsx)(el.Form.Item,{name:"guardrails",className:"mb-0",children:(0,t.jsx)(Y.Select,{mode:"tags",showSearch:!0,placeholder:"Select existing guardrails or type to create new ones",optionFilterProp:"children",tokenSeparators:[","],maxTagCount:"responsive",allowClear:!0,style:{width:"100%"},options:W.map(e=>({value:e,label:e}))})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.litellm_params?.guardrails?Array.isArray(p.litellm_params.guardrails)?p.litellm_params.guardrails.length>0?(0,t.jsx)("div",{className:"flex flex-wrap gap-1",children:p.litellm_params.guardrails.map((e,l)=>(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800",children:e},l))}):"No guardrails assigned":p.litellm_params.guardrails:"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsxs)(em.Text,{className:"font-medium",children:["Attached Knowledge Bases (RAG)",(0,t.jsx)(O.Tooltip,{title:"Vector stores used for RAG. Every request to this model will automatically retrieve context from these knowledge bases.",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/completion/knowledgebase",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(C.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),M?(0,t.jsx)(el.Form.Item,{name:"vector_store_ids",className:"mb-0",children:(0,t.jsx)(tE.default,{onChange:()=>{},accessToken:a||"",placeholder:"Select knowledge bases (optional)"})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.litellm_params?.vector_store_ids?Array.isArray(p.litellm_params.vector_store_ids)?p.litellm_params.vector_store_ids.length>0?(0,t.jsx)("div",{className:"flex flex-wrap gap-1",children:p.litellm_params.vector_store_ids.map((e,l)=>(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800",children:e},l))}):"No knowledge bases attached":String(p.litellm_params.vector_store_ids):"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Tags"}),M?(0,t.jsx)(el.Form.Item,{name:"tags",className:"mb-0",children:(0,t.jsx)(Y.Select,{mode:"tags",showSearch:!0,placeholder:"Select existing tags or type to create new ones",optionFilterProp:"children",tokenSeparators:[","],maxTagCount:"responsive",allowClear:!0,style:{width:"100%"},options:Object.values(Z).map(e=>({value:e.name,label:e.name,title:e.description||e.name}))})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.litellm_params?.tags?Array.isArray(p.litellm_params.tags)?p.litellm_params.tags.length>0?(0,t.jsx)("div",{className:"flex flex-wrap gap-1",children:p.litellm_params.tags.map((e,l)=>(0,t.jsx)("span",{className:"inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-purple-100 text-purple-800",children:e},l))}):"No tags assigned":p.litellm_params.tags:"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Existing Credentials"}),M?(0,t.jsx)(el.Form.Item,{name:"litellm_credential_name",className:"mb-0",children:(0,t.jsx)(Y.Select,{showSearch:!0,placeholder:"Select or search for existing credentials",optionFilterProp:"children",filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase()),options:[{value:"",label:"None"},...et.map(e=>({value:e.credential_name,label:e.credential_name}))],allowClear:!0})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.litellm_params?.litellm_credential_name||"Manual"})]}),eN&&(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Health Check Model"}),M?(0,t.jsx)(el.Form.Item,{name:"health_check_model",className:"mb-0",children:(0,t.jsx)(Y.Select,{showSearch:!0,placeholder:"Select existing health check model",optionFilterProp:"children",allowClear:!0,options:(m=eh.litellm_model_name.split("/")[0],ed?.data?.filter(e=>e.providers?.includes(m)&&e.model_group!==eh.litellm_model_name).map(e=>({value:e.model_group,label:e.model_group}))||[])})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.model_info?.health_check_model||"Not Set"})]}),M?(0,t.jsx)(tA,{form:u,showCacheControl:R,onCacheControlChange:e=>B(e)}):(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Cache Control"}),(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:p.litellm_params?.cache_control_injection_points?(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{children:"Enabled"}),(0,t.jsx)("div",{className:"mt-2",children:p.litellm_params.cache_control_injection_points.map((e,l)=>(0,t.jsxs)("div",{className:"text-sm text-gray-600 mb-1",children:["Location: ",e.location,",",e.role&&(0,t.jsxs)("span",{children:[" Role: ",e.role]}),void 0!==e.index&&(0,t.jsxs)("span",{children:[" Index: ",e.index]})]},l))})]}):"Disabled"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Model Info"}),M?(0,t.jsx)(el.Form.Item,{name:"model_info",className:"mb-0",children:(0,t.jsx)(eV.Input.TextArea,{rows:4,placeholder:'{"gpt-4": 100, "claude-v1": 200}',defaultValue:JSON.stringify(eh.model_info,null,2)})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:(0,t.jsx)("pre",{className:"bg-gray-100 p-2 rounded-sm text-xs overflow-auto mt-1",children:JSON.stringify(p.model_info,null,2)})})]}),(0,t.jsxs)("div",{children:[(0,t.jsxs)(em.Text,{className:"font-medium",children:["LiteLLM Params",(0,t.jsx)(O.Tooltip,{title:"Optional litellm params used for making a litellm.completion() call. Some params are automatically added by LiteLLM.",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),children:(0,t.jsx)(C.InfoCircleOutlined,{style:{marginLeft:"4px"}})})})]}),M?(0,t.jsx)(el.Form.Item,{name:"litellm_extra_params",rules:[{validator:tL.formItemValidateJSON}],children:(0,t.jsx)(eV.Input.TextArea,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}):(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:(0,t.jsx)("pre",{className:"bg-gray-100 p-2 rounded-sm text-xs overflow-auto mt-1",children:JSON.stringify(p.litellm_params,null,2)})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Team ID"}),(0,t.jsx)("div",{className:"mt-1 p-2 bg-gray-50 rounded-sm",children:eh.model_info.team_id||"Not Set"})]})]}),M&&(0,t.jsxs)("div",{className:"mt-6 flex justify-end gap-2",children:[(0,t.jsx)(I.Button,{variant:"secondary",onClick:()=>{u.resetFields(),T(!1),A(!1)},disabled:F,children:"Cancel"}),(0,t.jsx)(I.Button,{variant:"primary",onClick:()=>u.submit(),loading:F,children:"Save Changes"})]})]})}):(0,t.jsx)(em.Text,{children:"Loading..."})]})]}),(0,t.jsx)(J.TabPanel,{children:(0,t.jsx)(eL.Card,{children:(0,t.jsx)("pre",{className:"bg-gray-100 p-4 rounded-sm text-xs overflow-auto",children:JSON.stringify(eh,null,2)})})})]})]}),(0,t.jsx)(H.default,{isOpen:f,title:"Delete Model",alertMessage:"This action cannot be undone.",message:"Are you sure you want to delete this model?",resourceInformationTitle:"Model Information",resourceInformation:[{label:"Model Name",value:eh?.model_name||"Not Set"},{label:"LiteLLM Model Name",value:eh?.litellm_model_name||"Not Set"},{label:"Provider",value:eh?.provider||"Not Set"},{label:"Created By",value:eh?.model_info?.created_by||"Not Set"}],onCancel:()=>_(!1),onOk:eb,confirmLoading:j}),b&&!ef?(0,t.jsx)(ls,{isVisible:b,onCancel:()=>v(!1),onAddCredential:e_,existingCredential:E,setIsCredentialModalOpen:v}):(0,t.jsx)(es.Modal,{open:b,onCancel:()=>v(!1),title:"Using Existing Credential",children:(0,t.jsx)(em.Text,{children:eh.litellm_params.litellm_credential_name})}),N&&a&&(0,t.jsx)(lr,{open:N,onCancel:()=>w(!1),accessToken:a,modelId:e,onUpdated:()=>{h.invalidateQueries({queryKey:["models","list"]})}}),(0,t.jsx)(le,{isVisible:V,onCancel:()=>U(!1),onSuccess:e=>{g(e),o&&o(e)},modelData:p||eh,accessToken:a||"",userRole:i||""})]})}var ln=e.i(37091),ld=e.i(218129);let lc=({value:e={},onChange:l})=>{let[s,a]=(0,x.useState)(Object.entries(e)),r=(e,t,r)=>{let i=[...s];i[e]=[t,r],a(i),l?.(Object.fromEntries(i))};return(0,t.jsxs)("div",{children:[s.map(([e,i],o)=>(0,t.jsxs)(E.Space,{style:{display:"flex",marginBottom:8},align:"center",children:[(0,t.jsx)(eO.TextInput,{placeholder:"Header Name",value:e,onChange:e=>r(o,e.target.value,i)}),(0,t.jsx)(eO.TextInput,{placeholder:"Header Value",value:i,onChange:t=>r(o,e,t.target.value)}),(0,t.jsx)("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",height:"100%"},children:(0,t.jsx)(tF.MinusCircleOutlined,{onClick:()=>{let e;a(e=s.filter((e,t)=>t!==o)),l?.(Object.fromEntries(e))},style:{cursor:"pointer"}})})]},o)),(0,t.jsx)(Q.Button,{type:"dashed",onClick:()=>{a([...s,["",""]])},icon:(0,t.jsx)(to.PlusOutlined,{}),children:"Add Header"})]})},lm=({value:e={},onChange:l})=>{let[s,a]=(0,x.useState)(Object.entries(e)),r=(e,t,r)=>{let i=[...s];i[e]=[t,r],a(i),l?.(Object.fromEntries(i))};return(0,t.jsxs)("div",{children:[s.map(([e,i],o)=>(0,t.jsxs)(E.Space,{style:{display:"flex",marginBottom:8},align:"center",children:[(0,t.jsx)(eO.TextInput,{placeholder:"Parameter Name (e.g., version)",value:e,onChange:e=>r(o,e.target.value,i)}),(0,t.jsx)(eO.TextInput,{placeholder:"Parameter Value (e.g., v1)",value:i,onChange:t=>r(o,e,t.target.value)}),(0,t.jsx)("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",height:"100%"},children:(0,t.jsx)(tF.MinusCircleOutlined,{onClick:()=>{let e;a(e=s.filter((e,t)=>t!==o)),l?.(Object.fromEntries(e))},style:{cursor:"pointer"}})})]},o)),(0,t.jsx)(Q.Button,{type:"dashed",onClick:()=>{a([...s,["",""]])},icon:(0,t.jsx)(to.PlusOutlined,{}),children:"Add Query Parameter"})]})};var lu=e.i(240647);let{Title:lh,Text:lp}=R.Typography,lx=({pathValue:e,targetValue:s,includeSubpath:a})=>{let r=(0,l.getProxyBaseUrl)();return e&&s?(0,t.jsxs)(e_.Card,{className:"p-5",children:[(0,t.jsx)(lh,{level:5,className:"text-lg font-semibold text-gray-900 mb-2",children:"Route Preview"}),(0,t.jsx)(lp,{type:"secondary",className:"text-gray-600 mb-5",style:{display:"block"},children:"How your requests will be routed"}),(0,t.jsxs)("div",{className:"space-y-5",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-base font-semibold text-gray-900 mb-3",children:"Basic routing:"}),(0,t.jsxs)("div",{className:"flex items-center gap-4",children:[(0,t.jsxs)("div",{className:"flex-1 bg-gray-50 border border-gray-200 rounded-lg p-3",children:[(0,t.jsx)("div",{className:"text-sm text-gray-600 mb-2",children:"Your endpoint"}),(0,t.jsx)("code",{className:"font-mono text-sm text-gray-900",children:e?`${r}${e}`:""})]}),(0,t.jsx)("div",{className:"text-gray-400",children:(0,t.jsx)(lu.RightOutlined,{className:"text-lg"})}),(0,t.jsxs)("div",{className:"flex-1 bg-gray-50 border border-gray-200 rounded-lg p-3",children:[(0,t.jsx)("div",{className:"text-sm text-gray-600 mb-2",children:"Forwards to"}),(0,t.jsx)("code",{className:"font-mono text-sm text-gray-900",children:s})]})]})]}),a&&(0,t.jsx)(t.Fragment,{children:(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-base font-semibold text-gray-900 mb-3",children:"With subpaths:"}),(0,t.jsxs)("div",{className:"flex items-center gap-4",children:[(0,t.jsxs)("div",{className:"flex-1 bg-gray-50 border border-gray-200 rounded-lg p-3",children:[(0,t.jsx)("div",{className:"text-sm text-gray-600 mb-2",children:"Your endpoint + subpath"}),(0,t.jsxs)("code",{className:"font-mono text-sm text-gray-900",children:[e&&`${r}${e}`,(0,t.jsx)("span",{className:"text-blue-600",children:"/v1/text-to-image/base/model"})]})]}),(0,t.jsx)("div",{className:"text-gray-400",children:(0,t.jsx)(lu.RightOutlined,{className:"text-lg"})}),(0,t.jsxs)("div",{className:"flex-1 bg-gray-50 border border-gray-200 rounded-lg p-3",children:[(0,t.jsx)("div",{className:"text-sm text-gray-600 mb-2",children:"Forwards to"}),(0,t.jsxs)("code",{className:"font-mono text-sm text-gray-900",children:[s,(0,t.jsx)("span",{className:"text-blue-600",children:"/v1/text-to-image/base/model"})]})]})]}),(0,t.jsxs)("div",{className:"mt-3 text-sm text-gray-600",children:["Any path after ",e," will be appended to the target URL"]})]})}),!a&&(0,t.jsx)("div",{className:"mt-4 p-3 bg-blue-50 rounded-md border border-blue-200",children:(0,t.jsxs)("div",{className:"flex items-start",children:[(0,t.jsx)(C.InfoCircleOutlined,{className:"text-blue-500 mt-0.5 mr-2 shrink-0"}),(0,t.jsxs)("div",{className:"text-sm text-blue-700",children:[(0,t.jsx)("span",{className:"font-medium",children:"Not seeing the routing you wanted?"})," Try enabling - Include Subpaths - above - this allows subroutes like"," ",(0,t.jsx)("code",{className:"bg-blue-100 px-1 py-0.5 rounded-sm font-mono text-xs",children:"/api/v1/models"})," to be forwarded automatically."]})]})})]})]}):null},lg=({premiumUser:e,authEnabled:l,onAuthChange:s})=>(0,t.jsxs)(eL.Card,{className:"p-6",children:[(0,t.jsx)(eu.Title,{className:"text-lg font-semibold text-gray-900 mb-2",children:"Security"}),(0,t.jsx)(ln.Subtitle,{className:"text-gray-600 mb-4",children:"When enabled, requests to this endpoint will require a valid LiteLLM Virtual Key"}),e?(0,t.jsx)(el.Form.Item,{name:"auth",valuePropName:"checked",className:"mb-0",children:(0,t.jsx)(L.Switch,{checked:l,onChange:e=>{s(e)}})}):(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center mb-3",children:[(0,t.jsx)(L.Switch,{disabled:!0,checked:!1,style:{outline:"2px solid #d1d5db",outlineOffset:"2px"}}),(0,t.jsx)("span",{className:"ml-2 text-sm text-gray-400",children:"Authentication (Premium)"})]}),(0,t.jsx)("div",{className:"p-3 bg-yellow-50 border border-yellow-200 rounded-lg",children:(0,t.jsxs)(em.Text,{className:"text-sm text-yellow-800",children:["Setting authentication for pass-through endpoints is a LiteLLM Enterprise feature. Get a trial key"," ",(0,t.jsx)("a",{href:"https://www.litellm.ai/#pricing",target:"_blank",rel:"noopener noreferrer",className:"underline",children:"here"}),"."]})})]})]});var lf=e.i(891547);let l_=({accessToken:e,value:l={},onChange:s,disabled:a=!1})=>{let[r,i]=(0,x.useState)(Object.keys(l)),[o,n]=(0,x.useState)(l);(0,x.useEffect)(()=>{n(l),i(Object.keys(l))},[l]);let d=(e,t,l)=>{let a=o[e]||{},r={...o,[e]:{...a,[t]:l.length>0?l:void 0}};r[e]?.request_fields||r[e]?.response_fields||(r[e]=null),n(r),s&&s(r)};return(0,t.jsxs)(eL.Card,{className:"p-6",children:[(0,t.jsx)(eu.Title,{className:"text-lg font-semibold text-gray-900 mb-2",children:"Guardrails"}),(0,t.jsx)(ln.Subtitle,{className:"text-gray-600 mb-6",children:"Configure guardrails to enforce policies on requests and responses. Guardrails are opt-in for passthrough endpoints."}),(0,t.jsx)(tw.Alert,{message:(0,t.jsxs)("span",{children:["Field-Level Targeting"," ",(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/pass_through_guardrails#field-level-targeting",target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:text-blue-800 underline",children:"(Learn More)"})]}),description:(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("div",{children:"Optionally specify which fields to check. If left empty, the entire request/response is sent to the guardrail."}),(0,t.jsxs)("div",{className:"text-xs space-y-1 mt-2",children:[(0,t.jsx)("div",{className:"font-medium",children:"Common Examples:"}),(0,t.jsxs)("div",{children:["• ",(0,t.jsx)("code",{className:"bg-gray-100 px-1 rounded-sm",children:"query"})," - Single field"]}),(0,t.jsxs)("div",{children:["• ",(0,t.jsx)("code",{className:"bg-gray-100 px-1 rounded-sm",children:"documents[*].text"})," - All text in documents array"]}),(0,t.jsxs)("div",{children:["• ",(0,t.jsx)("code",{className:"bg-gray-100 px-1 rounded-sm",children:"messages[*].content"})," - All message contents"]})]})]}),type:"info",showIcon:!0,className:"mb-4"}),(0,t.jsx)(el.Form.Item,{label:(0,t.jsxs)("span",{className:"text-sm font-medium text-gray-700 flex items-center",children:["Select Guardrails",(0,t.jsx)(O.Tooltip,{title:"Choose which guardrails should run on this endpoint. Org/team/key level guardrails will also be included.",children:(0,t.jsx)(C.InfoCircleOutlined,{className:"ml-2 text-blue-400 hover:text-blue-600 cursor-help"})})]}),children:(0,t.jsx)(lf.default,{accessToken:e,value:r,onChange:e=>{i(e);let t={};e.forEach(e=>{t[e]=o[e]||null}),n(t),s&&s(t)},disabled:a})}),r.length>0&&(0,t.jsxs)("div",{className:"mt-6 space-y-4",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-3",children:[(0,t.jsx)("div",{className:"text-sm font-medium text-gray-700",children:"Field Targeting (Optional)"}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"💡 Tip: Leave empty to check entire payload"})]}),r.map(e=>(0,t.jsxs)(eL.Card,{className:"p-4 bg-gray-50",children:[(0,t.jsx)("div",{className:"text-sm font-medium text-gray-900 mb-3",children:e}),(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-1",children:[(0,t.jsxs)("label",{className:"text-xs text-gray-600 flex items-center",children:["Request Fields (pre_call)",(0,t.jsx)(O.Tooltip,{title:(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"font-medium mb-1",children:"Specify which request fields to check"}),(0,t.jsxs)("div",{className:"text-xs space-y-1",children:[(0,t.jsx)("div",{children:"Examples:"}),(0,t.jsx)("div",{children:"• query"}),(0,t.jsx)("div",{children:"• documents[*].text"}),(0,t.jsx)("div",{children:"• messages[*].content"})]})]}),children:(0,t.jsx)(C.InfoCircleOutlined,{className:"ml-1 text-gray-400"})})]}),(0,t.jsxs)("div",{className:"flex gap-1",children:[(0,t.jsx)("button",{type:"button",onClick:()=>{let t=o[e]?.request_fields||[];d(e,"request_fields",[...t,"query"])},className:"text-xs px-2 py-1 bg-white border border-gray-300 rounded-sm hover:bg-gray-50",disabled:a,children:"+ query"}),(0,t.jsx)("button",{type:"button",onClick:()=>{let t=o[e]?.request_fields||[];d(e,"request_fields",[...t,"documents[*]"])},className:"text-xs px-2 py-1 bg-white border border-gray-300 rounded-sm hover:bg-gray-50",disabled:a,children:"+ documents[*]"})]})]}),(0,t.jsx)(Y.Select,{mode:"tags",style:{width:"100%"},placeholder:"Type field name or use + buttons above (e.g., query, documents[*].text)",value:o[e]?.request_fields||[],onChange:t=>d(e,"request_fields",t),disabled:a,tokenSeparators:[","]})]}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-1",children:[(0,t.jsxs)("label",{className:"text-xs text-gray-600 flex items-center",children:["Response Fields (post_call)",(0,t.jsx)(O.Tooltip,{title:(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"font-medium mb-1",children:"Specify which response fields to check"}),(0,t.jsxs)("div",{className:"text-xs space-y-1",children:[(0,t.jsx)("div",{children:"Examples:"}),(0,t.jsx)("div",{children:"• results[*].text"}),(0,t.jsx)("div",{children:"• choices[*].message.content"})]})]}),children:(0,t.jsx)(C.InfoCircleOutlined,{className:"ml-1 text-gray-400"})})]}),(0,t.jsx)("div",{className:"flex gap-1",children:(0,t.jsx)("button",{type:"button",onClick:()=>{let t=o[e]?.response_fields||[];d(e,"response_fields",[...t,"results[*]"])},className:"text-xs px-2 py-1 bg-white border border-gray-300 rounded-sm hover:bg-gray-50",disabled:a,children:"+ results[*]"})})]}),(0,t.jsx)(Y.Select,{mode:"tags",style:{width:"100%"},placeholder:"Type field name or use + buttons above (e.g., results[*].text)",value:o[e]?.response_fields||[],onChange:t=>d(e,"response_fields",t),disabled:a,tokenSeparators:[","]})]})]})]},e))]})]})},{Option:lj}=Y.Select,ly=["GET","POST","PUT","DELETE","PATCH"],lb=({accessToken:e,setPassThroughItems:s,passThroughItems:a,premiumUser:r=!1})=>{let[i]=el.Form.useForm(),[o,n]=(0,x.useState)(!1),[d,c]=(0,x.useState)(!1),[m,u]=(0,x.useState)(""),[h,p]=(0,x.useState)(""),[g,f]=(0,x.useState)(""),[_,j]=(0,x.useState)(!0),[y,b]=(0,x.useState)(!1),[v,N]=(0,x.useState)([]),[w,k]=(0,x.useState)({}),S=()=>{i.resetFields(),p(""),f(""),j(!0),N([]),k({}),n(!1)},T=async t=>{c(!0);try{!r&&"auth"in t&&delete t.auth,w&&Object.keys(w).length>0&&(t.guardrails=w),v&&v.length>0&&(t.methods=v);let o=(await (0,l.createPassThroughEndpoint)(e,t)).endpoints[0],d=[...a,o];s(d),G.default.success("Pass-through endpoint created successfully"),i.resetFields(),p(""),f(""),j(!0),N([]),k({}),n(!1)}catch(e){G.default.fromBackend("Error creating pass-through endpoint: "+e)}finally{c(!1)}};return(0,t.jsxs)("div",{children:[(0,t.jsx)(I.Button,{className:"mx-auto mb-4 mt-4",onClick:()=>n(!0),children:"+ Add Pass-Through Endpoint"}),(0,t.jsx)(es.Modal,{title:(0,t.jsxs)("div",{className:"flex items-center space-x-3 pb-4 border-b border-gray-100",children:[(0,t.jsx)(ld.ApiOutlined,{className:"text-xl text-blue-500"}),(0,t.jsx)("h2",{className:"text-xl font-semibold text-gray-900",children:"Add Pass-Through Endpoint"})]}),open:o,width:1e3,onCancel:S,footer:null,className:"top-8",styles:{body:{padding:"24px"},header:{padding:"24px 24px 0 24px",border:"none"}},children:(0,t.jsxs)("div",{className:"mt-6",children:[(0,t.jsx)(tw.Alert,{message:"What is a Pass-Through Endpoint?",description:"Route requests from your LiteLLM proxy to any external API. Perfect for custom models, image generation APIs, or any service you want to proxy through LiteLLM.",type:"info",showIcon:!0,className:"mb-6"}),(0,t.jsxs)(el.Form,{form:i,onFinish:T,layout:"vertical",className:"space-y-6",initialValues:{include_subpath:!0,path:h,target:g},children:[(0,t.jsxs)(eL.Card,{className:"p-5",children:[(0,t.jsx)(eu.Title,{className:"text-lg font-semibold text-gray-900 mb-2",children:"Route Configuration"}),(0,t.jsx)(ln.Subtitle,{className:"text-gray-600 mb-5",children:"Configure how requests to your domain will be forwarded to the target API"}),(0,t.jsxs)("div",{className:"space-y-5",children:[(0,t.jsx)(el.Form.Item,{label:(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Path Prefix"}),name:"path",rules:[{required:!0,message:"Path is required",pattern:/^\//}],extra:(0,t.jsx)("div",{className:"text-xs text-gray-500 mt-1",children:"Example: /bria, /adobe-photoshop, /elasticsearch"}),className:"mb-4",children:(0,t.jsx)("div",{className:"flex items-center",children:(0,t.jsx)(eO.TextInput,{placeholder:"bria",value:h,onChange:e=>{var t;let l;return l=t=e.target.value,void(t&&!t.startsWith("/")&&(l="/"+t),p(l),i.setFieldsValue({path:l}))},className:"flex-1"})})}),(0,t.jsx)(el.Form.Item,{label:(0,t.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Target URL"}),name:"target",rules:[{required:!0,message:"Target URL is required"},{type:"url",message:"Please enter a valid URL"}],extra:(0,t.jsx)("div",{className:"text-xs text-gray-500 mt-1",children:"Example:https://engine.prod.bria-api.com"}),className:"mb-4",children:(0,t.jsx)(eO.TextInput,{placeholder:"https://engine.prod.bria-api.com",value:g,onChange:e=>{f(e.target.value),i.setFieldsValue({target:e.target.value})}})}),(0,t.jsx)(el.Form.Item,{label:(0,t.jsxs)("span",{className:"text-sm font-medium text-gray-700 flex items-center",children:["HTTP Methods (Optional)",(0,t.jsx)(O.Tooltip,{title:"Select specific HTTP methods. Leave empty to support all methods (GET, POST, PUT, DELETE, PATCH). Useful when the same path needs different targets for different methods.",children:(0,t.jsx)(C.InfoCircleOutlined,{className:"ml-2 text-blue-400 hover:text-blue-600 cursor-help"})})]}),name:"methods",extra:(0,t.jsx)("div",{className:"text-xs text-gray-500 mt-1",children:0===v.length?"All HTTP methods supported (default)":`Only ${v.join(", ")} requests will be routed to this endpoint`}),className:"mb-4",children:(0,t.jsx)(Y.Select,{mode:"multiple",placeholder:"Select methods (leave empty for all)",value:v,onChange:N,allowClear:!0,style:{width:"100%"},children:ly.map(e=>(0,t.jsx)(lj,{value:e,children:e},e))})}),(0,t.jsxs)("div",{className:"flex items-center justify-between py-3",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-sm font-medium text-gray-700",children:"Include Subpaths"}),(0,t.jsx)("div",{className:"text-xs text-gray-500 mt-0.5",children:"Forward all subpaths to the target API (recommended for REST APIs)"})]}),(0,t.jsx)(el.Form.Item,{name:"include_subpath",valuePropName:"checked",className:"mb-0",children:(0,t.jsx)(tN.Switch,{checked:_,onChange:j})})]})]})]}),(0,t.jsx)(lx,{pathValue:h,targetValue:g,includeSubpath:_}),(0,t.jsxs)(eL.Card,{className:"p-6",children:[(0,t.jsx)(eu.Title,{className:"text-lg font-semibold text-gray-900 mb-2",children:"Headers"}),(0,t.jsx)(ln.Subtitle,{className:"text-gray-600 mb-6",children:"Add headers that will be sent with every request to the target API"}),(0,t.jsx)(el.Form.Item,{label:(0,t.jsxs)("span",{className:"text-sm font-medium text-gray-700 flex items-center",children:["Authentication Headers",(0,t.jsx)(O.Tooltip,{title:"Authentication and other headers to forward with requests",children:(0,t.jsx)(C.InfoCircleOutlined,{className:"ml-2 text-blue-400 hover:text-blue-600 cursor-help"})})]}),name:"headers",rules:[{required:!0,message:"Please configure the headers"}],extra:(0,t.jsxs)("div",{className:"text-xs text-gray-500 mt-2",children:[(0,t.jsx)("div",{className:"font-medium mb-1",children:"Add authentication tokens and other required headers"}),(0,t.jsx)("div",{children:"Common examples: auth_token, Authorization, x-api-key"})]}),children:(0,t.jsx)(lc,{})})]}),(0,t.jsxs)(eL.Card,{className:"p-6",children:[(0,t.jsx)(eu.Title,{className:"text-lg font-semibold text-gray-900 mb-2",children:"Default Query Parameters"}),(0,t.jsx)(ln.Subtitle,{className:"text-gray-600 mb-6",children:"Add query parameters that will be automatically sent with every request to the target API"}),(0,t.jsx)(el.Form.Item,{label:(0,t.jsxs)("span",{className:"text-sm font-medium text-gray-700 flex items-center",children:["Default Query Parameters (Optional)",(0,t.jsx)(O.Tooltip,{title:"Query parameters that will be added to all requests. Clients can override these by providing their own values.",children:(0,t.jsx)(C.InfoCircleOutlined,{className:"ml-2 text-blue-400 hover:text-blue-600 cursor-help"})})]}),name:"default_query_params",extra:(0,t.jsxs)("div",{className:"text-xs text-gray-500 mt-2",children:[(0,t.jsx)("div",{className:"font-medium mb-1",children:"Parameters are sent with all GET, POST, PUT, PATCH requests"}),(0,t.jsx)("div",{children:"Client parameters override defaults. Examples: version=v1, format=json, key=default"})]}),children:(0,t.jsx)(lm,{})})]}),(0,t.jsx)(lg,{premiumUser:r,authEnabled:y,onAuthChange:e=>{b(e),i.setFieldsValue({auth:e})}}),(0,t.jsx)(l_,{accessToken:e,value:w,onChange:k}),(0,t.jsxs)(eL.Card,{className:"p-6",children:[(0,t.jsx)(eu.Title,{className:"text-lg font-semibold text-gray-900 mb-2",children:"Performance"}),(0,t.jsx)(ln.Subtitle,{className:"text-gray-600 mb-6",children:"Configure upstream request timeout for this endpoint"}),(0,t.jsx)(el.Form.Item,{label:(0,t.jsxs)("span",{className:"text-sm font-medium text-gray-700 flex items-center",children:["Request Timeout (seconds)",(0,t.jsx)(O.Tooltip,{title:"Max time to wait for the upstream API to respond. Leave empty to use general_settings.pass_through_request_timeout (default 600s).",children:(0,t.jsx)(C.InfoCircleOutlined,{className:"ml-2 text-gray-400 hover:text-gray-600"})})]}),name:"timeout",extra:(0,t.jsx)("div",{className:"text-xs text-gray-500 mt-2",children:"Use a higher value for slow upstream APIs (e.g. 1200 for long-running LLM calls)"}),children:(0,t.jsx)(tP.default,{min:1,step:1,precision:0,placeholder:"600",size:"large"})})]}),(0,t.jsxs)(eL.Card,{className:"p-6",children:[(0,t.jsx)(eu.Title,{className:"text-lg font-semibold text-gray-900 mb-2",children:"Billing"}),(0,t.jsx)(ln.Subtitle,{className:"text-gray-600 mb-6",children:"Optional cost tracking for this endpoint"}),(0,t.jsx)(el.Form.Item,{label:(0,t.jsxs)("span",{className:"text-sm font-medium text-gray-700 flex items-center",children:["Cost Per Request (USD)",(0,t.jsx)(O.Tooltip,{title:"Optional: Track costs for requests to this endpoint",children:(0,t.jsx)(C.InfoCircleOutlined,{className:"ml-2 text-gray-400 hover:text-gray-600"})})]}),name:"cost_per_request",extra:(0,t.jsx)("div",{className:"text-xs text-gray-500 mt-2",children:"The cost charged for each request through this endpoint"}),children:(0,t.jsx)(tP.default,{min:0,step:.001,precision:4,placeholder:"2.0000",size:"large"})})]}),(0,t.jsxs)("div",{className:"flex items-center justify-end space-x-3 pt-6 border-t border-gray-100",children:[(0,t.jsx)(I.Button,{variant:"secondary",onClick:S,children:"Cancel"}),(0,t.jsx)(I.Button,{variant:"primary",loading:d,onClick:()=>{i.submit()},children:d?"Creating...":"Add Pass-Through Endpoint"})]})]})]})})]})};var lv=e.i(286536),lN=e.i(77705);let lw=["GET","POST","PUT","DELETE","PATCH"],{Option:lC}=Y.Select,lk=({value:e})=>{let[l,s]=(0,x.useState)(!1),a=JSON.stringify(e,null,2);return(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("pre",{className:"font-mono text-xs bg-gray-50 p-2 rounded-sm max-w-md overflow-auto",children:l?a:"••••••••"}),(0,t.jsx)("button",{onClick:()=>s(!l),className:"p-1 hover:bg-gray-100 rounded-sm",type:"button",children:l?(0,t.jsx)(lN.EyeOff,{className:"w-4 h-4 text-gray-500"}):(0,t.jsx)(lv.Eye,{className:"w-4 h-4 text-gray-500"})})]})},lS=({endpointData:e,onClose:s,accessToken:a,isAdmin:r,premiumUser:i=!1,onEndpointUpdated:o})=>{let[n,d]=(0,x.useState)(e),[c,m]=(0,x.useState)(!1),[u,h]=(0,x.useState)(!1),[p,g]=(0,x.useState)(e?.auth||!1),[f,_]=(0,x.useState)(e?.methods||[]),[j,y]=(0,x.useState)(e?.guardrails||{}),[b]=el.Form.useForm(),v=async e=>{try{if(!a||!n?.id)return;let t={};if(e.headers)try{t="string"==typeof e.headers?JSON.parse(e.headers):e.headers}catch(e){G.default.fromBackend("Invalid JSON format for headers");return}let s={path:n.path,target:e.target,headers:t,include_subpath:e.include_subpath,cost_per_request:e.cost_per_request,timeout:e.timeout,auth:i?e.auth:void 0,methods:f&&f.length>0?f:void 0,guardrails:j&&Object.keys(j).length>0?j:void 0};await (0,l.updatePassThroughEndpoint)(a,n.id,s),d({...n,...s}),h(!1),o&&o()}catch(e){console.error("Error updating endpoint:",e),G.default.fromBackend("Failed to update pass through endpoint")}},N=async()=>{try{if(!a||!n?.id)return;await (0,l.deletePassThroughEndpointsCall)(a,n.id),G.default.success("Pass through endpoint deleted successfully"),s(),o&&o()}catch(e){console.error("Error deleting endpoint:",e),G.default.fromBackend("Failed to delete pass through endpoint")}};return c?(0,t.jsx)("div",{className:"p-4",children:"Loading..."}):n?(0,t.jsxs)("div",{className:"p-4",children:[(0,t.jsx)("div",{className:"flex justify-between items-center mb-6",children:(0,t.jsxs)("div",{children:[(0,t.jsx)(Q.Button,{onClick:s,className:"mb-4",children:"← Back"}),(0,t.jsxs)(eu.Title,{children:["Pass Through Endpoint: ",n.path]}),(0,t.jsx)(em.Text,{className:"text-gray-500 font-mono",children:n.id})]})}),(0,t.jsxs)(e6.TabGroup,{children:[(0,t.jsxs)(e3.TabList,{className:"mb-4",children:[(0,t.jsx)(e5.Tab,{children:"Overview"},"overview"),r?(0,t.jsx)(e5.Tab,{children:"Settings"},"settings"):(0,t.jsx)(t.Fragment,{})]}),(0,t.jsxs)(e8.TabPanels,{children:[(0,t.jsxs)(J.TabPanel,{children:[(0,t.jsxs)(K.Grid,{numItems:1,numItemsSm:2,numItemsLg:3,className:"gap-6",children:[(0,t.jsxs)(eL.Card,{children:[(0,t.jsx)(em.Text,{children:"Path"}),(0,t.jsx)("div",{className:"mt-2",children:(0,t.jsx)(eu.Title,{className:"font-mono",children:n.path})})]}),(0,t.jsxs)(eL.Card,{children:[(0,t.jsx)(em.Text,{children:"Target"}),(0,t.jsx)("div",{className:"mt-2",children:(0,t.jsx)(eu.Title,{children:n.target})})]}),(0,t.jsxs)(eL.Card,{children:[(0,t.jsx)(em.Text,{children:"Configuration"}),(0,t.jsxs)("div",{className:"mt-2 space-y-2",children:[(0,t.jsx)("div",{children:(0,t.jsx)(T.Badge,{color:n.include_subpath?"green":"gray",children:n.include_subpath?"Include Subpath":"Exact Path"})}),(0,t.jsx)("div",{children:(0,t.jsx)(T.Badge,{color:n.auth?"blue":"gray",children:n.auth?"Auth Required":"No Auth"})}),n.methods&&n.methods.length>0&&(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"text-xs text-gray-500",children:"HTTP Methods:"}),(0,t.jsx)("div",{className:"flex flex-wrap gap-1 mt-1",children:n.methods.map(e=>(0,t.jsx)(T.Badge,{color:"indigo",size:"sm",children:e},e))})]}),(!n.methods||0===n.methods.length)&&(0,t.jsx)("div",{children:(0,t.jsx)(em.Text,{className:"text-xs text-gray-500",children:"All HTTP methods supported"})}),void 0!==n.cost_per_request&&(0,t.jsx)("div",{children:(0,t.jsxs)(em.Text,{children:["Cost per request: $",n.cost_per_request]})})]})]})]}),(0,t.jsx)("div",{className:"mt-6",children:(0,t.jsx)(lx,{pathValue:n.path,targetValue:n.target,includeSubpath:n.include_subpath||!1})}),n.headers&&Object.keys(n.headers).length>0&&(0,t.jsxs)(eL.Card,{className:"mt-6",children:[(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Headers"}),(0,t.jsxs)(T.Badge,{color:"blue",children:[Object.keys(n.headers).length," headers configured"]})]}),(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(lk,{value:n.headers})})]}),n.guardrails&&Object.keys(n.guardrails).length>0&&(0,t.jsxs)(eL.Card,{className:"mt-6",children:[(0,t.jsxs)("div",{className:"flex justify-between items-center",children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Guardrails"}),(0,t.jsxs)(T.Badge,{color:"purple",children:[Object.keys(n.guardrails).length," guardrails configured"]})]}),(0,t.jsx)("div",{className:"mt-4 space-y-2",children:Object.entries(n.guardrails).map(([e,l])=>(0,t.jsxs)("div",{className:"p-3 bg-gray-50 rounded-sm",children:[(0,t.jsx)("div",{className:"font-medium text-sm",children:e}),l&&(l.request_fields||l.response_fields)&&(0,t.jsxs)("div",{className:"mt-2 text-xs text-gray-600 space-y-1",children:[l.request_fields&&(0,t.jsxs)("div",{children:["Request fields: ",l.request_fields.join(", ")]}),l.response_fields&&(0,t.jsxs)("div",{children:["Response fields: ",l.response_fields.join(", ")]})]}),!l&&(0,t.jsx)("div",{className:"text-xs text-gray-600 mt-1",children:"Uses entire payload"})]},e))})]})]}),r&&(0,t.jsx)(J.TabPanel,{children:(0,t.jsxs)(eL.Card,{children:[(0,t.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,t.jsx)(eu.Title,{children:"Pass Through Endpoint Settings"}),(0,t.jsx)("div",{className:"space-x-2",children:!u&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(I.Button,{onClick:()=>h(!0),children:"Edit Settings"}),(0,t.jsx)(I.Button,{onClick:N,variant:"secondary",color:"red",children:"Delete Endpoint"})]})})]}),u?(0,t.jsxs)(el.Form,{form:b,onFinish:v,initialValues:{target:n.target,headers:n.headers?JSON.stringify(n.headers,null,2):"",include_subpath:n.include_subpath||!1,cost_per_request:n.cost_per_request,timeout:n.timeout,auth:n.auth||!1,methods:n.methods||[]},layout:"vertical",children:[(0,t.jsx)(el.Form.Item,{label:"Target URL",name:"target",rules:[{required:!0,message:"Please input a target URL"}],children:(0,t.jsx)(eO.TextInput,{placeholder:"https://api.example.com"})}),(0,t.jsx)(el.Form.Item,{label:"Headers (JSON)",name:"headers",children:(0,t.jsx)(eV.Input.TextArea,{rows:5,placeholder:'{"Authorization": "Bearer your-token", "Content-Type": "application/json"}'})}),(0,t.jsx)(el.Form.Item,{label:"HTTP Methods (Optional)",name:"methods",extra:0===f.length?"All HTTP methods supported (default)":`Only ${f.join(", ")} requests will be routed to this endpoint`,children:(0,t.jsx)(Y.Select,{mode:"multiple",placeholder:"Select methods (leave empty for all)",value:f,onChange:_,allowClear:!0,style:{width:"100%"},children:lw.map(e=>(0,t.jsx)(lC,{value:e,children:e},e))})}),(0,t.jsx)(el.Form.Item,{label:"Include Subpath",name:"include_subpath",valuePropName:"checked",children:(0,t.jsx)(L.Switch,{})}),(0,t.jsx)(el.Form.Item,{label:"Cost per Request",name:"cost_per_request",children:(0,t.jsx)(eh.InputNumber,{min:0,step:.01,precision:2,placeholder:"0.00",addonBefore:"$"})}),(0,t.jsx)(el.Form.Item,{label:"Request Timeout (seconds)",name:"timeout",extra:"Max time to wait for upstream response. Leave empty to use the global pass_through_request_timeout (default 600s).",children:(0,t.jsx)(eh.InputNumber,{min:1,step:1,precision:0,placeholder:"600",style:{width:"100%"}})}),(0,t.jsx)(lg,{premiumUser:i,authEnabled:p,onAuthChange:e=>{g(e),b.setFieldsValue({auth:e})}}),(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsx)(l_,{accessToken:a||"",value:j,onChange:y})}),(0,t.jsxs)("div",{className:"flex justify-end gap-2 mt-6",children:[(0,t.jsx)(Q.Button,{onClick:()=>h(!1),children:"Cancel"}),(0,t.jsx)(I.Button,{children:"Save Changes"})]})]}):(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Path"}),(0,t.jsx)("div",{className:"font-mono",children:n.path})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Target URL"}),(0,t.jsx)("div",{children:n.target})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Include Subpath"}),(0,t.jsx)(T.Badge,{color:n.include_subpath?"green":"gray",children:n.include_subpath?"Yes":"No"})]}),void 0!==n.cost_per_request&&(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Cost per Request"}),(0,t.jsxs)("div",{children:["$",n.cost_per_request]})]}),void 0!==n.timeout&&null!==n.timeout&&(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Request Timeout"}),(0,t.jsxs)("div",{children:[n.timeout,"s"]})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Authentication Required"}),(0,t.jsx)(T.Badge,{color:n.auth?"green":"gray",children:n.auth?"Yes":"No"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(em.Text,{className:"font-medium",children:"Headers"}),n.headers&&Object.keys(n.headers).length>0?(0,t.jsx)("div",{className:"mt-2",children:(0,t.jsx)(lk,{value:n.headers})}):(0,t.jsx)("div",{className:"text-gray-500",children:"No headers configured"})]})]})]})})]})]})]}):(0,t.jsx)("div",{className:"p-4",children:"Pass through endpoint not found"})};var lT=e.i(149121);let lI=({value:e})=>{let[l,s]=(0,x.useState)(!1),a=JSON.stringify(e);return(0,t.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,t.jsx)("span",{className:"font-mono text-xs",children:l?a:"••••••••"}),(0,t.jsx)("button",{onClick:()=>s(!l),className:"p-1 hover:bg-gray-100 rounded-sm",type:"button",children:l?(0,t.jsx)(lN.EyeOff,{className:"w-4 h-4 text-gray-500"}):(0,t.jsx)(lv.Eye,{className:"w-4 h-4 text-gray-500"})})]})},lF=({accessToken:e,userRole:s,userID:a,modelData:r,premiumUser:i})=>{let[o,n]=(0,x.useState)([]),[d,c]=(0,x.useState)(null),[m,u]=(0,x.useState)(!1),[h,p]=(0,x.useState)(null);(0,x.useEffect)(()=>{e&&s&&a&&(0,l.getPassThroughEndpointsCall)(e).then(e=>{n(e.endpoints)})},[e,s,a]);let g=async e=>{p(e),u(!0)},f=async()=>{if(null!=h&&e){try{await (0,l.deletePassThroughEndpointsCall)(e,h);let t=o.filter(e=>e.id!==h);n(t),G.default.success("Endpoint deleted successfully.")}catch(e){console.error("Error deleting the endpoint:",e),G.default.fromBackend("Error deleting the endpoint: "+e)}u(!1),p(null)}},_=[{header:"ID",accessorKey:"id",cell:e=>(0,t.jsx)(O.Tooltip,{title:e.row.original.id,children:(0,t.jsx)("div",{className:"font-mono text-blue-500 bg-blue-50 hover:bg-blue-100 text-xs font-normal px-2 py-0.5 text-left w-full truncate whitespace-nowrap cursor-pointer max-w-[15ch]",onClick:()=>e.row.original.id&&c(e.row.original.id),children:e.row.original.id})})},{header:"Path",accessorKey:"path"},{header:"Target",accessorKey:"target",cell:e=>(0,t.jsx)(em.Text,{children:e.getValue()})},{header:()=>(0,t.jsxs)("div",{className:"flex items-center gap-1",children:[(0,t.jsx)("span",{children:"Methods"}),(0,t.jsx)(O.Tooltip,{title:"HTTP methods supported by this endpoint",children:(0,t.jsx)(tQ.InformationCircleIcon,{className:"w-4 h-4 text-gray-400 cursor-help"})})]}),accessorKey:"methods",cell:e=>{let l=e.getValue();return l&&0!==l.length?(0,t.jsx)("div",{className:"flex flex-wrap gap-1",children:l.map(e=>(0,t.jsx)(W.Badge,{color:"indigo",className:"text-xs",children:e},e))}):(0,t.jsx)(W.Badge,{color:"blue",children:"ALL"})}},{header:()=>(0,t.jsxs)("div",{className:"flex items-center gap-1",children:[(0,t.jsx)("span",{children:"Authentication"}),(0,t.jsx)(O.Tooltip,{title:"LiteLLM Virtual Key required to call endpoint",children:(0,t.jsx)(tQ.InformationCircleIcon,{className:"w-4 h-4 text-gray-400 cursor-help"})})]}),accessorKey:"auth",cell:e=>(0,t.jsx)(W.Badge,{color:e.getValue()?"green":"gray",children:e.getValue()?"Yes":"No"})},{header:"Headers",accessorKey:"headers",cell:e=>(0,t.jsx)(lI,{value:e.getValue()||{}})},{header:"Actions",id:"actions",cell:({row:e})=>(0,t.jsxs)("div",{className:"flex space-x-1",children:[(0,t.jsx)(F.Icon,{icon:eE.PencilAltIcon,size:"sm",onClick:()=>e.original.id&&c(e.original.id),title:"Edit"}),(0,t.jsx)(F.Icon,{icon:S.TrashIcon,size:"sm",onClick:()=>{var t;return t=e.original.id,e.index,void g(t)},title:"Delete"})]})}];if(!e)return null;if(d){let a=o.find(e=>e.id===d);return a?(0,t.jsx)(lS,{endpointData:a,onClose:()=>c(null),accessToken:e,isAdmin:"Admin"===s||"admin"===s,premiumUser:i,onEndpointUpdated:()=>{e&&(0,l.getPassThroughEndpointsCall)(e).then(e=>{n(e.endpoints)})}}):(0,t.jsx)("div",{children:"Endpoint not found"})}return(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(eu.Title,{children:"Pass Through Endpoints"}),(0,t.jsx)(em.Text,{className:"text-tremor-content",children:"Configure and manage your pass-through endpoints"})]}),(0,t.jsx)(lb,{accessToken:e,setPassThroughItems:n,passThroughItems:o,premiumUser:i}),(0,t.jsx)(lT.DataTable,{data:o,columns:_,renderSubComponent:()=>(0,t.jsx)("div",{}),getRowCanExpand:()=>!1,isLoading:!1,noDataMessage:"No pass-through endpoints configured"}),m&&(0,t.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,t.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,t.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,t.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,t.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:"​"}),(0,t.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,t.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,t.jsx)("div",{className:"sm:flex sm:items-start",children:(0,t.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,t.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Pass-Through Endpoint"}),(0,t.jsx)("div",{className:"mt-2",children:(0,t.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this pass-through endpoint? This action cannot be undone."})})]})})}),(0,t.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,t.jsx)(I.Button,{onClick:f,color:"red",className:"ml-2",children:"Delete"}),(0,t.jsx)(I.Button,{onClick:()=>{u(!1),p(null)},children:"Cancel"})]})]})]})})]})};var lP=e.i(56567);let lM=({premiumUser:e,teams:s})=>{let a,i,{accessToken:u,token:h,userRole:p,userId:g}=(0,r.default)(),[f]=el.Form.useForm(),[_,j]=(0,x.useState)(""),[y,b]=(0,x.useState)([]),[v,N]=(0,x.useState)(eP.Providers.Anthropic),[w,C]=(0,x.useState)(null),[k,S]=(0,x.useState)("global"),[T,I]=(0,x.useState)(null),[P,M]=(0,x.useState)(null),[A,E]=(0,x.useState)(0),[L,O]=(0,x.useState)({}),[R,B]=(0,x.useState)(!1),[z,q]=(0,x.useState)(null),[V,H]=(0,x.useState)(null),[U,W]=(0,x.useState)(0),[Q,Y]=(0,x.useState)(1),[X,Z]=(0,x.useState)(()=>"true"!==localStorage.getItem("hideMissingProviderBanner")),ee=(0,$.useQueryClient)(),{data:et,isLoading:es,refetch:ea}=(0,d.useModelsInfo)(),{data:er,isLoading:eo}=(0,d.useModelsInfo)(Q,50),{data:ed,isLoading:ec}=(0,n.useModelCostMap)(),{data:em,isLoading:eu}=o(),eh=em?.credentials||[],{data:ep,isLoading:eg}=(0,c.useUISettings)(),ef=(0,m.useMutation)({mutationFn:async e=>{if(!u)throw Error("Access token is required");return(0,l.setCallbacksCall)(u,{router_settings:e})}}),e_=(0,x.useMemo)(()=>{if(!et?.data)return[];let e=new Set;for(let t of et.data)e.add(t.model_name);return Array.from(e).sort()},[et?.data]),ej=(0,x.useMemo)(()=>{if(!et?.data)return[];let e=new Set;for(let t of et.data){let l=t.model_info;if(l?.access_groups)for(let t of l.access_groups)e.add(t)}return Array.from(e)},[et?.data]),ey=(0,x.useMemo)(()=>et?.data?et.data.map(e=>e.model_name):[],[et?.data]),eb=(0,x.useMemo)(()=>er?.data?er.data.map(e=>e.model_info?.id).filter(e=>!!e):[],[er?.data]),ev=e=>null!=ed&&"object"==typeof ed&&e in ed?ed[e].litellm_provider:"openai",eN=(0,x.useMemo)(()=>et?.data?ei(et,ev):{data:[]},[et?.data,ev]),ew=(0,x.useMemo)(()=>er?.data?ei(er,ev):{data:[]},[er?.data,ev]),eC=(0,x.useMemo)(()=>({total_count:er?.total_count??0,current_page:er?.current_page??Q,total_pages:er?.total_pages??1,size:er?.size??50}),[er,Q]),ek=p&&(0,e0.isProxyAdminRole)(p),eS=p&&e0.internalUserRoles.includes(p),eT=g&&(0,e0.isUserTeamAdminForAnyTeam)(s,g),eI=eS&&ep?.values?.disable_model_add_for_internal_users===!0,eM={name:"file",accept:".json",pastable:!1,beforeUpload:e=>{if("application/json"===e.type){let t=new FileReader;t.onload=e=>{if(e.target){let t=e.target.result;f.setFieldsValue({vertex_credentials:t})}},t.readAsText(e)}return!1},onChange(e){"done"===e.file.status?G.default.success(`${e.file.name} file uploaded successfully`):"error"===e.file.status&&G.default.fromBackend(`${e.file.name} file upload failed.`)}},eE=()=>{j(new Date().toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})),Y(1),ee.invalidateQueries({queryKey:["models","list"]}),ea()},eL=(0,x.useCallback)(async()=>{if(!u||!g||!p)return null;try{return(await (0,l.getCallbacksCall)(u,g,p)).router_settings}catch(e){return console.error("Error fetching model data:",e),null}},[u,g,p]),eO=(0,x.useCallback)(e=>{I(e.model_group_retry_policy??null),M(e.retry_policy??null),E(e.num_retries??2),O(e.model_group_alias||{})},[]),eR=(0,x.useCallback)(async()=>{let e=await eL();e&&eO(e)},[eL,eO]);(0,x.useEffect)(()=>{if(!u||!h||!p||!g||!et)return;let e=!0;return(async()=>{let t=await eL();e&&t&&eO(t)})(),()=>{e=!1}},[u,h,p,g,et,eL,eO]);let eB=async()=>{try{let e=await f.validateFields();await eA(e,u,f,eE)}catch(t){let e=t.errorFields?.map(e=>`${e.name.join(".")}: ${e.errors.join(", ")}`).join(" | ")||"Unknown validation error";G.default.fromBackend(`Please fill in the following required fields: ${e}`)}};return(Object.keys(eP.Providers).find(e=>eP.Providers[e]===v),V)?(0,t.jsx)("div",{className:"w-full h-full",children:(0,t.jsx)(lP.default,{teamId:V,onClose:()=>H(null),accessToken:u,is_team_admin:"Admin"===p,is_proxy_admin:"Proxy Admin"===p,userModels:ey,editTeam:!1,onUpdate:eE,premiumUser:e})}):(0,t.jsx)("div",{className:"w-full mx-4 h-[75vh]",children:(0,t.jsx)(K.Grid,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:(0,t.jsxs)(e4.Col,{numColSpan:1,className:"flex flex-col gap-2",children:[(0,t.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("h2",{className:"text-lg font-semibold",children:"Model Management"}),e0.all_admin_roles.includes(p)?(0,t.jsx)("p",{className:"text-sm text-gray-600",children:"Add and manage models for the proxy"}):(0,t.jsx)("p",{className:"text-sm text-gray-600",children:"Add models for teams you are an admin for."})]}),!X&&(0,t.jsxs)("a",{href:"https://models.litellm.ai/?request=true",target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-[#6366f1] hover:text-[#5558e3] border border-[#6366f1] hover:border-[#5558e3] rounded-lg transition-colors",children:[(0,t.jsx)(e7.PlusCircleOutlined,{style:{fontSize:"12px"}}),"Request Provider"]})]}),X&&(0,t.jsxs)("div",{className:"mb-4 px-4 py-3 bg-blue-50 rounded-lg border border-blue-100 flex items-center gap-4",children:[(0,t.jsx)("div",{className:"shrink-0 w-10 h-10 bg-white rounded-full flex items-center justify-center border border-blue-200",children:(0,t.jsx)(e7.PlusCircleOutlined,{style:{fontSize:"18px",color:"#6366f1"}})}),(0,t.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,t.jsx)("h4",{className:"text-gray-900 font-semibold text-sm m-0",children:"Missing a provider?"}),(0,t.jsx)("p",{className:"text-gray-500 text-xs m-0 mt-0.5",children:"The LiteLLM engineering team is constantly adding support for new LLM models, providers, endpoints. If you don't see the one you need, let us know and we'll prioritize it."})]}),(0,t.jsxs)("a",{href:"https://models.litellm.ai/?request=true",target:"_blank",rel:"noopener noreferrer",className:"shrink-0 inline-flex items-center gap-2 px-4 py-2 bg-[#6366f1] hover:bg-[#5558e3] text-white text-sm font-medium rounded-lg transition-colors",children:["Request Provider",(0,t.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"})})]}),(0,t.jsx)("button",{onClick:()=>{Z(!1),localStorage.setItem("hideMissingProviderBanner","true")},className:"shrink-0 p-1 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-full transition-colors","aria-label":"Dismiss banner",children:(0,t.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]}),z&&!(es||ec||eu||eg)?(0,t.jsx)(lo,{modelId:z,onClose:()=>{q(null)},accessToken:u,userID:g,userRole:p,onModelUpdate:e=>{ee.invalidateQueries({queryKey:["models","list"]}),eE()},modelAccessGroups:ej}):(a=e0.all_admin_roles.includes(p),i=[{tab:(0,t.jsx)(e5.Tab,{children:a?"All Models":"Your Models"},"all-models"),panel:(0,t.jsx)(en,{selectedModelGroup:w,setSelectedModelGroup:C,availableModelGroups:e_,availableModelAccessGroups:ej,setSelectedModelId:q,setSelectedTeamId:H},"all-models")}],(ek||!eI&&eT)&&i.push({tab:(0,t.jsx)(e5.Tab,{children:"Add Model"},"add-model"),panel:(0,t.jsx)(J.TabPanel,{className:"h-full",children:(0,t.jsx)(tK,{form:f,handleOk:eB,selectedProvider:v,setSelectedProvider:N,providerModels:y,setProviderModelsFn:e=>{b((0,eP.getProviderModels)(e,ed))},getPlaceholder:eP.getPlaceholder,uploadProps:eM,showAdvancedSettings:R,setShowAdvancedSettings:B,teams:s,credentials:eh,accessToken:u,userRole:p})},"add-model")}),a&&i.push({tab:(0,t.jsx)(e5.Tab,{children:"LLM Credentials"},"llm-credentials"),panel:(0,t.jsx)(J.TabPanel,{children:(0,t.jsx)(e1,{uploadProps:eM})},"llm-credentials")},{tab:(0,t.jsx)(e5.Tab,{children:"Pass-Through Endpoints"},"pass-through"),panel:(0,t.jsx)(J.TabPanel,{children:(0,t.jsx)(lF,{accessToken:u,userRole:p,userID:g,modelData:eN,premiumUser:e})},"pass-through")},{tab:(0,t.jsx)(e5.Tab,{children:"Health Status"},"health-status"),panel:(0,t.jsx)(J.TabPanel,{children:(0,t.jsx)(tZ,{accessToken:u,modelData:ew,all_models_on_proxy:eb,getDisplayModelName:D,setSelectedModelId:q,teams:s,isLoading:eo,paginationMeta:eC,currentPage:Q,pageSize:50,onPageChange:Y})},"health-status")},{tab:(0,t.jsx)(e5.Tab,{children:"Model Retry Settings"},"model-retry-settings"),panel:(0,t.jsx)(ex,{selectedModelGroup:k,setSelectedModelGroup:S,availableModelGroups:e_,globalRetryPolicy:P,setGlobalRetryPolicy:M,defaultRetry:A,modelGroupRetryPolicy:T,setModelGroupRetryPolicy:I,handleSaveRetrySettings:()=>{ef.mutate({retry_policy:P,model_group_retry_policy:T},{onSuccess:()=>{G.default.success("Retry settings saved successfully"),eR()},onError:()=>{G.default.fromBackend("Failed to save retry settings")}})},isSaving:ef.isPending},"model-retry-settings")},{tab:(0,t.jsx)(e5.Tab,{children:"Model Group Alias"},"model-group-alias"),panel:(0,t.jsx)(J.TabPanel,{children:(0,t.jsx)(t5,{accessToken:u,initialModelGroupAlias:L,onAliasUpdate:O})},"model-group-alias")},{tab:(0,t.jsx)(e5.Tab,{children:"Price Data Reload"},"price-data-reload"),panel:(0,t.jsx)(eF,{},"price-data-reload")}),(0,t.jsxs)(e6.TabGroup,{index:U,onIndexChange:W,className:"gap-2 h-[75vh] w-full ",children:[(0,t.jsxs)(e3.TabList,{className:"flex justify-between mt-2 w-full items-center",children:[(0,t.jsx)("div",{className:"flex",children:i.map(e=>e.tab)}),(0,t.jsxs)("div",{className:"flex items-center space-x-2 self-center",children:[_&&(0,t.jsxs)("span",{className:"text-xs text-gray-500",children:["Last Refreshed: ",_]}),(0,t.jsx)(F.Icon,{icon:e2.RefreshIcon,variant:"shadow",size:"xs",className:"cursor-pointer",onClick:eE})]})]}),(0,t.jsx)(e8.TabPanels,{children:i.map(e=>e.panel)})]}))]})})})};e.s(["default",0,function(){let{premiumUser:e}=(0,r.default)(),{data:l}=(0,u.useTeams)();return(0,t.jsx)(lM,{premiumUser:e,teams:l??null})}],664307)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/036wlkuzplhfz.js b/litellm/proxy/_experimental/out/_next/static/chunks/036wlkuzplhfz.js new file mode 100644 index 00000000000..e090152ea51 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/036wlkuzplhfz.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,649222,(e,a,t)=>{e.e,e.r(166540).defineLocale("af",{months:"Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember".split("_"),monthsShort:"Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des".split("_"),weekdays:"Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag".split("_"),weekdaysShort:"Son_Maa_Din_Woe_Don_Vry_Sat".split("_"),weekdaysMin:"So_Ma_Di_Wo_Do_Vr_Sa".split("_"),meridiemParse:/vm|nm/i,isPM:function(e){return/^nm$/i.test(e)},meridiem:function(e,a,t){return e<12?t?"vm":"VM":t?"nm":"NM"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Vandag om] LT",nextDay:"[Môre om] LT",nextWeek:"dddd [om] LT",lastDay:"[Gister om] LT",lastWeek:"[Laas] dddd [om] LT",sameElse:"L"},relativeTime:{future:"oor %s",past:"%s gelede",s:"'n paar sekondes",ss:"%d sekondes",m:"'n minuut",mm:"%d minute",h:"'n uur",hh:"%d ure",d:"'n dag",dd:"%d dae",M:"'n maand",MM:"%d maande",y:"'n jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(e){return e+(1===e||8===e||e>=20?"ste":"de")},week:{dow:1,doy:4}})},50997,(e,a,t)=>{e.e,function(e){"use strict";var a=function(e){return 0===e?0:1===e?1:2===e?2:e%100>=3&&e%100<=10?3:e%100>=11?4:5},t={s:["أقل من ثانية","ثانية واحدة",["ثانيتان","ثانيتين"],"%d ثوان","%d ثانية","%d ثانية"],m:["أقل من دقيقة","دقيقة واحدة",["دقيقتان","دقيقتين"],"%d دقائق","%d دقيقة","%d دقيقة"],h:["أقل من ساعة","ساعة واحدة",["ساعتان","ساعتين"],"%d ساعات","%d ساعة","%d ساعة"],d:["أقل من يوم","يوم واحد",["يومان","يومين"],"%d أيام","%d يومًا","%d يوم"],M:["أقل من شهر","شهر واحد",["شهران","شهرين"],"%d أشهر","%d شهرا","%d شهر"],y:["أقل من عام","عام واحد",["عامان","عامين"],"%d أعوام","%d عامًا","%d عام"]},s=function(e){return function(s,n,r,d){var i=a(s),_=t[e][a(s)];return 2===i&&(_=_[+!n]),_.replace(/%d/i,s)}},n=["جانفي","فيفري","مارس","أفريل","ماي","جوان","جويلية","أوت","سبتمبر","أكتوبر","نوفمبر","ديسمبر"];e.defineLocale("ar-dz",{months:n,monthsShort:n,weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/‏M/‏YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(e){return"م"===e},meridiem:function(e,a,t){return e<12?"ص":"م"},calendar:{sameDay:"[اليوم عند الساعة] LT",nextDay:"[غدًا عند الساعة] LT",nextWeek:"dddd [عند الساعة] LT",lastDay:"[أمس عند الساعة] LT",lastWeek:"dddd [عند الساعة] LT",sameElse:"L"},relativeTime:{future:"بعد %s",past:"منذ %s",s:s("s"),ss:s("s"),m:s("m"),mm:s("m"),h:s("h"),hh:s("h"),d:s("d"),dd:s("d"),M:s("M"),MM:s("M"),y:s("y"),yy:s("y")},postformat:function(e){return e.replace(/,/g,"،")},week:{dow:0,doy:4}})}(e.r(166540))},818181,(e,a,t)=>{e.e,e.r(166540).defineLocale("ar-kw",{months:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),weekdays:"الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",ss:"%d ثانية",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:0,doy:12}})},392472,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",0:"0"},t=function(e){return 0===e?0:1===e?1:2===e?2:e%100>=3&&e%100<=10?3:e%100>=11?4:5},s={s:["أقل من ثانية","ثانية واحدة",["ثانيتان","ثانيتين"],"%d ثوان","%d ثانية","%d ثانية"],m:["أقل من دقيقة","دقيقة واحدة",["دقيقتان","دقيقتين"],"%d دقائق","%d دقيقة","%d دقيقة"],h:["أقل من ساعة","ساعة واحدة",["ساعتان","ساعتين"],"%d ساعات","%d ساعة","%d ساعة"],d:["أقل من يوم","يوم واحد",["يومان","يومين"],"%d أيام","%d يومًا","%d يوم"],M:["أقل من شهر","شهر واحد",["شهران","شهرين"],"%d أشهر","%d شهرا","%d شهر"],y:["أقل من عام","عام واحد",["عامان","عامين"],"%d أعوام","%d عامًا","%d عام"]},n=function(e){return function(a,n,r,d){var i=t(a),_=s[e][t(a)];return 2===i&&(_=_[+!n]),_.replace(/%d/i,a)}},r=["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"];e.defineLocale("ar-ly",{months:r,monthsShort:r,weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/‏M/‏YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(e){return"م"===e},meridiem:function(e,a,t){return e<12?"ص":"م"},calendar:{sameDay:"[اليوم عند الساعة] LT",nextDay:"[غدًا عند الساعة] LT",nextWeek:"dddd [عند الساعة] LT",lastDay:"[أمس عند الساعة] LT",lastWeek:"dddd [عند الساعة] LT",sameElse:"L"},relativeTime:{future:"بعد %s",past:"منذ %s",s:n("s"),ss:n("s"),m:n("m"),mm:n("m"),h:n("h"),hh:n("h"),d:n("d"),dd:n("d"),M:n("M"),MM:n("M"),y:n("y"),yy:n("y")},preparse:function(e){return e.replace(/،/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]}).replace(/,/g,"،")},week:{dow:6,doy:12}})}(e.r(166540))},48840,(e,a,t)=>{e.e,e.r(166540).defineLocale("ar-ma",{months:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",ss:"%d ثانية",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:1,doy:4}})},561871,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},t={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"};e.defineLocale("ar-ps",{months:"كانون الثاني_شباط_آذار_نيسان_أيّار_حزيران_تمّوز_آب_أيلول_تشري الأوّل_تشرين الثاني_كانون الأوّل".split("_"),monthsShort:"ك٢_شباط_آذار_نيسان_أيّار_حزيران_تمّوز_آب_أيلول_ت١_ت٢_ك١".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(e){return"م"===e},meridiem:function(e,a,t){return e<12?"ص":"م"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",ss:"%d ثانية",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},preparse:function(e){return e.replace(/[٣٤٥٦٧٨٩٠]/g,function(e){return t[e]}).split("").reverse().join("").replace(/[١٢](?![\u062a\u0643])/g,function(e){return t[e]}).split("").reverse().join("").replace(/،/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]}).replace(/,/g,"،")},week:{dow:0,doy:6}})}(e.r(166540))},566848,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},t={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"};e.defineLocale("ar-sa",{months:"يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(e){return"م"===e},meridiem:function(e,a,t){return e<12?"ص":"م"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",ss:"%d ثانية",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},preparse:function(e){return e.replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(e){return t[e]}).replace(/،/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]}).replace(/,/g,"،")},week:{dow:0,doy:6}})}(e.r(166540))},892109,(e,a,t)=>{e.e,e.r(166540).defineLocale("ar-tn",{months:"جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:"جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",ss:"%d ثانية",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:1,doy:4}})},617209,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},t={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"},s=function(e){return 0===e?0:1===e?1:2===e?2:e%100>=3&&e%100<=10?3:e%100>=11?4:5},n={s:["أقل من ثانية","ثانية واحدة",["ثانيتان","ثانيتين"],"%d ثوان","%d ثانية","%d ثانية"],m:["أقل من دقيقة","دقيقة واحدة",["دقيقتان","دقيقتين"],"%d دقائق","%d دقيقة","%d دقيقة"],h:["أقل من ساعة","ساعة واحدة",["ساعتان","ساعتين"],"%d ساعات","%d ساعة","%d ساعة"],d:["أقل من يوم","يوم واحد",["يومان","يومين"],"%d أيام","%d يومًا","%d يوم"],M:["أقل من شهر","شهر واحد",["شهران","شهرين"],"%d أشهر","%d شهرا","%d شهر"],y:["أقل من عام","عام واحد",["عامان","عامين"],"%d أعوام","%d عامًا","%d عام"]},r=function(e){return function(a,t,r,d){var i=s(a),_=n[e][s(a)];return 2===i&&(_=_[+!t]),_.replace(/%d/i,a)}},d=["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"];e.defineLocale("ar",{months:d,monthsShort:d,weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/‏M/‏YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(e){return"م"===e},meridiem:function(e,a,t){return e<12?"ص":"م"},calendar:{sameDay:"[اليوم عند الساعة] LT",nextDay:"[غدًا عند الساعة] LT",nextWeek:"dddd [عند الساعة] LT",lastDay:"[أمس عند الساعة] LT",lastWeek:"dddd [عند الساعة] LT",sameElse:"L"},relativeTime:{future:"بعد %s",past:"منذ %s",s:r("s"),ss:r("s"),m:r("m"),mm:r("m"),h:r("h"),hh:r("h"),d:r("d"),dd:r("d"),M:r("M"),MM:r("M"),y:r("y"),yy:r("y")},preparse:function(e){return e.replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(e){return t[e]}).replace(/،/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]}).replace(/,/g,"،")},week:{dow:6,doy:12}})}(e.r(166540))},627551,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"-inci",5:"-inci",8:"-inci",70:"-inci",80:"-inci",2:"-nci",7:"-nci",20:"-nci",50:"-nci",3:"-üncü",4:"-üncü",100:"-üncü",6:"-ncı",9:"-uncu",10:"-uncu",30:"-uncu",60:"-ıncı",90:"-ıncı"};e.defineLocale("az",{months:"yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr".split("_"),monthsShort:"yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek".split("_"),weekdays:"Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə".split("_"),weekdaysShort:"Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən".split("_"),weekdaysMin:"Bz_BE_ÇA_Çə_CA_Cü_Şə".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bugün saat] LT",nextDay:"[sabah saat] LT",nextWeek:"[gələn həftə] dddd [saat] LT",lastDay:"[dünən] LT",lastWeek:"[keçən həftə] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s əvvəl",s:"bir neçə saniyə",ss:"%d saniyə",m:"bir dəqiqə",mm:"%d dəqiqə",h:"bir saat",hh:"%d saat",d:"bir gün",dd:"%d gün",M:"bir ay",MM:"%d ay",y:"bir il",yy:"%d il"},meridiemParse:/gecə|səhər|gündüz|axşam/,isPM:function(e){return/^(gündüz|axşam)$/.test(e)},meridiem:function(e,a,t){return e<4?"gecə":e<12?"səhər":e<17?"gündüz":"axşam"},dayOfMonthOrdinalParse:/\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,ordinal:function(e){if(0===e)return e+"-ıncı";var t=e%10;return e+(a[t]||a[e%100-t]||a[e>=100?100:null])},week:{dow:1,doy:7}})}(e.r(166540))},416502,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t){var s,n,r;return"m"===t?a?"хвіліна":"хвіліну":"h"===t?a?"гадзіна":"гадзіну":e+" "+(s=({ss:a?"секунда_секунды_секунд":"секунду_секунды_секунд",mm:a?"хвіліна_хвіліны_хвілін":"хвіліну_хвіліны_хвілін",hh:a?"гадзіна_гадзіны_гадзін":"гадзіну_гадзіны_гадзін",dd:"дзень_дні_дзён",MM:"месяц_месяцы_месяцаў",yy:"год_гады_гадоў"})[t],n=+e,r=s.split("_"),n%10==1&&n%100!=11?r[0]:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?r[1]:r[2])}e.defineLocale("be",{months:{format:"студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня".split("_"),standalone:"студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань".split("_")},monthsShort:"студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж".split("_"),weekdays:{format:"нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу".split("_"),standalone:"нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота".split("_"),isFormat:/\[ ?[Ууў] ?(?:мінулую|наступную)? ?\] ?dddd/},weekdaysShort:"нд_пн_ат_ср_чц_пт_сб".split("_"),weekdaysMin:"нд_пн_ат_ср_чц_пт_сб".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY г.",LLL:"D MMMM YYYY г., HH:mm",LLLL:"dddd, D MMMM YYYY г., HH:mm"},calendar:{sameDay:"[Сёння ў] LT",nextDay:"[Заўтра ў] LT",lastDay:"[Учора ў] LT",nextWeek:function(){return"[У] dddd [ў] LT"},lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return"[У мінулую] dddd [ў] LT";case 1:case 2:case 4:return"[У мінулы] dddd [ў] LT"}},sameElse:"L"},relativeTime:{future:"праз %s",past:"%s таму",s:"некалькі секунд",m:a,mm:a,h:a,hh:a,d:"дзень",dd:a,M:"месяц",MM:a,y:"год",yy:a},meridiemParse:/ночы|раніцы|дня|вечара/,isPM:function(e){return/^(дня|вечара)$/.test(e)},meridiem:function(e,a,t){return e<4?"ночы":e<12?"раніцы":e<17?"дня":"вечара"},dayOfMonthOrdinalParse:/\d{1,2}-(і|ы|га)/,ordinal:function(e,a){switch(a){case"M":case"d":case"DDD":case"w":case"W":return(e%10==2||e%10==3)&&e%100!=12&&e%100!=13?e+"-і":e+"-ы";case"D":return e+"-га";default:return e}},week:{dow:1,doy:7}})}(e.r(166540))},231241,(e,a,t)=>{e.e,e.r(166540).defineLocale("bg",{months:"януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември".split("_"),monthsShort:"яну_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек".split("_"),weekdays:"неделя_понеделник_вторник_сряда_четвъртък_петък_събота".split("_"),weekdaysShort:"нед_пон_вто_сря_чет_пет_съб".split("_"),weekdaysMin:"нд_пн_вт_ср_чт_пт_сб".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[Днес в] LT",nextDay:"[Утре в] LT",nextWeek:"dddd [в] LT",lastDay:"[Вчера в] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[Миналата] dddd [в] LT";case 1:case 2:case 4:case 5:return"[Миналия] dddd [в] LT"}},sameElse:"L"},relativeTime:{future:"след %s",past:"преди %s",s:"няколко секунди",ss:"%d секунди",m:"минута",mm:"%d минути",h:"час",hh:"%d часа",d:"ден",dd:"%d дена",w:"седмица",ww:"%d седмици",M:"месец",MM:"%d месеца",y:"година",yy:"%d години"},dayOfMonthOrdinalParse:/\d{1,2}-(ев|ен|ти|ви|ри|ми)/,ordinal:function(e){var a=e%10,t=e%100;if(0===e)return e+"-ев";if(0===t)return e+"-ен";if(t>10&&t<20)return e+"-ти";if(1===a)return e+"-ви";if(2===a)return e+"-ри";else if(7===a||8===a)return e+"-ми";else return e+"-ти"},week:{dow:1,doy:7}})},909549,(e,a,t)=>{e.e,e.r(166540).defineLocale("bm",{months:"Zanwuyekalo_Fewuruyekalo_Marisikalo_Awirilikalo_Mɛkalo_Zuwɛnkalo_Zuluyekalo_Utikalo_Sɛtanburukalo_ɔkutɔburukalo_Nowanburukalo_Desanburukalo".split("_"),monthsShort:"Zan_Few_Mar_Awi_Mɛ_Zuw_Zul_Uti_Sɛt_ɔku_Now_Des".split("_"),weekdays:"Kari_Ntɛnɛn_Tarata_Araba_Alamisa_Juma_Sibiri".split("_"),weekdaysShort:"Kar_Ntɛ_Tar_Ara_Ala_Jum_Sib".split("_"),weekdaysMin:"Ka_Nt_Ta_Ar_Al_Ju_Si".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"MMMM [tile] D [san] YYYY",LLL:"MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm",LLLL:"dddd MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm"},calendar:{sameDay:"[Bi lɛrɛ] LT",nextDay:"[Sini lɛrɛ] LT",nextWeek:"dddd [don lɛrɛ] LT",lastDay:"[Kunu lɛrɛ] LT",lastWeek:"dddd [tɛmɛnen lɛrɛ] LT",sameElse:"L"},relativeTime:{future:"%s kɔnɔ",past:"a bɛ %s bɔ",s:"sanga dama dama",ss:"sekondi %d",m:"miniti kelen",mm:"miniti %d",h:"lɛrɛ kelen",hh:"lɛrɛ %d",d:"tile kelen",dd:"tile %d",M:"kalo kelen",MM:"kalo %d",y:"san kelen",yy:"san %d"},week:{dow:1,doy:4}})},939441,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"১",2:"২",3:"৩",4:"৪",5:"৫",6:"৬",7:"৭",8:"৮",9:"৯",0:"০"},t={"১":"1","২":"2","৩":"3","৪":"4","৫":"5","৬":"6","৭":"7","৮":"8","৯":"9","০":"0"};e.defineLocale("bn-bd",{months:"জানুয়ারি_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর".split("_"),monthsShort:"জানু_ফেব্রু_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্ট_অক্টো_নভে_ডিসে".split("_"),weekdays:"রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার".split("_"),weekdaysShort:"রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি".split("_"),weekdaysMin:"রবি_সোম_মঙ্গল_বুধ_বৃহ_শুক্র_শনি".split("_"),longDateFormat:{LT:"A h:mm সময়",LTS:"A h:mm:ss সময়",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm সময়",LLLL:"dddd, D MMMM YYYY, A h:mm সময়"},calendar:{sameDay:"[আজ] LT",nextDay:"[আগামীকাল] LT",nextWeek:"dddd, LT",lastDay:"[গতকাল] LT",lastWeek:"[গত] dddd, LT",sameElse:"L"},relativeTime:{future:"%s পরে",past:"%s আগে",s:"কয়েক সেকেন্ড",ss:"%d সেকেন্ড",m:"এক মিনিট",mm:"%d মিনিট",h:"এক ঘন্টা",hh:"%d ঘন্টা",d:"এক দিন",dd:"%d দিন",M:"এক মাস",MM:"%d মাস",y:"এক বছর",yy:"%d বছর"},preparse:function(e){return e.replace(/[১২৩৪৫৬৭৮৯০]/g,function(e){return t[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]})},meridiemParse:/রাত|ভোর|সকাল|দুপুর|বিকাল|সন্ধ্যা|রাত/,meridiemHour:function(e,a){if(12===e&&(e=0),"রাত"===a)return e<4?e:e+12;if("ভোর"===a)return e;if("সকাল"===a)return e;if("দুপুর"===a)return e>=3?e:e+12;if("বিকাল"===a)return e+12;else if("সন্ধ্যা"===a)return e+12},meridiem:function(e,a,t){if(e<4)return"রাত";if(e<6)return"ভোর";if(e<12)return"সকাল";if(e<15)return"দুপুর";if(e<18)return"বিকাল";else if(e<20)return"সন্ধ্যা";else return"রাত"},week:{dow:0,doy:6}})}(e.r(166540))},557613,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"১",2:"২",3:"৩",4:"৪",5:"৫",6:"৬",7:"৭",8:"৮",9:"৯",0:"০"},t={"১":"1","২":"2","৩":"3","৪":"4","৫":"5","৬":"6","৭":"7","৮":"8","৯":"9","০":"0"};e.defineLocale("bn",{months:"জানুয়ারি_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর".split("_"),monthsShort:"জানু_ফেব্রু_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্ট_অক্টো_নভে_ডিসে".split("_"),weekdays:"রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার".split("_"),weekdaysShort:"রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি".split("_"),weekdaysMin:"রবি_সোম_মঙ্গল_বুধ_বৃহ_শুক্র_শনি".split("_"),longDateFormat:{LT:"A h:mm সময়",LTS:"A h:mm:ss সময়",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm সময়",LLLL:"dddd, D MMMM YYYY, A h:mm সময়"},calendar:{sameDay:"[আজ] LT",nextDay:"[আগামীকাল] LT",nextWeek:"dddd, LT",lastDay:"[গতকাল] LT",lastWeek:"[গত] dddd, LT",sameElse:"L"},relativeTime:{future:"%s পরে",past:"%s আগে",s:"কয়েক সেকেন্ড",ss:"%d সেকেন্ড",m:"এক মিনিট",mm:"%d মিনিট",h:"এক ঘন্টা",hh:"%d ঘন্টা",d:"এক দিন",dd:"%d দিন",M:"এক মাস",MM:"%d মাস",y:"এক বছর",yy:"%d বছর"},preparse:function(e){return e.replace(/[১২৩৪৫৬৭৮৯০]/g,function(e){return t[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]})},meridiemParse:/রাত|সকাল|দুপুর|বিকাল|রাত/,meridiemHour:function(e,a){return(12===e&&(e=0),"রাত"===a&&e>=4||"দুপুর"===a&&e<5||"বিকাল"===a)?e+12:e},meridiem:function(e,a,t){return e<4?"রাত":e<10?"সকাল":e<17?"দুপুর":e<20?"বিকাল":"রাত"},week:{dow:0,doy:6}})}(e.r(166540))},447113,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"༡",2:"༢",3:"༣",4:"༤",5:"༥",6:"༦",7:"༧",8:"༨",9:"༩",0:"༠"},t={"༡":"1","༢":"2","༣":"3","༤":"4","༥":"5","༦":"6","༧":"7","༨":"8","༩":"9","༠":"0"};e.defineLocale("bo",{months:"ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ".split("_"),monthsShort:"ཟླ་1_ཟླ་2_ཟླ་3_ཟླ་4_ཟླ་5_ཟླ་6_ཟླ་7_ཟླ་8_ཟླ་9_ཟླ་10_ཟླ་11_ཟླ་12".split("_"),monthsShortRegex:/^(ཟླ་\d{1,2})/,monthsParseExact:!0,weekdays:"གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་".split("_"),weekdaysShort:"ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་".split("_"),weekdaysMin:"ཉི_ཟླ_མིག_ལྷག_ཕུར_སངས_སྤེན".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[དི་རིང] LT",nextDay:"[སང་ཉིན] LT",nextWeek:"[བདུན་ཕྲག་རྗེས་མ], LT",lastDay:"[ཁ་སང] LT",lastWeek:"[བདུན་ཕྲག་མཐའ་མ] dddd, LT",sameElse:"L"},relativeTime:{future:"%s ལ་",past:"%s སྔན་ལ",s:"ལམ་སང",ss:"%d སྐར་ཆ།",m:"སྐར་མ་གཅིག",mm:"%d སྐར་མ",h:"ཆུ་ཚོད་གཅིག",hh:"%d ཆུ་ཚོད",d:"ཉིན་གཅིག",dd:"%d ཉིན་",M:"ཟླ་བ་གཅིག",MM:"%d ཟླ་བ",y:"ལོ་གཅིག",yy:"%d ལོ"},preparse:function(e){return e.replace(/[༡༢༣༤༥༦༧༨༩༠]/g,function(e){return t[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]})},meridiemParse:/མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,meridiemHour:function(e,a){return(12===e&&(e=0),"མཚན་མོ"===a&&e>=4||"ཉིན་གུང"===a&&e<5||"དགོང་དག"===a)?e+12:e},meridiem:function(e,a,t){return e<4?"མཚན་མོ":e<10?"ཞོགས་ཀས":e<17?"ཉིན་གུང":e<20?"དགོང་དག":"མཚན་མོ"},week:{dow:0,doy:6}})}(e.r(166540))},964028,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t){var s,n,r;return e+" "+(s=({mm:"munutenn",MM:"miz",dd:"devezh"})[t],2===e?void 0===(r={m:"v",b:"v",d:"z"})[(n=s).charAt(0)]?n:r[n.charAt(0)]+n.substring(1):s)}var t=[/^gen/i,/^c[ʼ\']hwe/i,/^meu/i,/^ebr/i,/^mae/i,/^(mez|eve)/i,/^gou/i,/^eos/i,/^gwe/i,/^her/i,/^du/i,/^ker/i],s=/^(genver|c[ʼ\']hwevrer|meurzh|ebrel|mae|mezheven|gouere|eost|gwengolo|here|du|kerzu|gen|c[ʼ\']hwe|meu|ebr|mae|eve|gou|eos|gwe|her|du|ker)/i,n=[/^Su/i,/^Lu/i,/^Me([^r]|$)/i,/^Mer/i,/^Ya/i,/^Gw/i,/^Sa/i];e.defineLocale("br",{months:"Genver_Cʼhwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu".split("_"),monthsShort:"Gen_Cʼhwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker".split("_"),weekdays:"Sul_Lun_Meurzh_Mercʼher_Yaou_Gwener_Sadorn".split("_"),weekdaysShort:"Sul_Lun_Meu_Mer_Yao_Gwe_Sad".split("_"),weekdaysMin:"Su_Lu_Me_Mer_Ya_Gw_Sa".split("_"),weekdaysParse:n,fullWeekdaysParse:[/^sul/i,/^lun/i,/^meurzh/i,/^merc[ʼ\']her/i,/^yaou/i,/^gwener/i,/^sadorn/i],shortWeekdaysParse:[/^Sul/i,/^Lun/i,/^Meu/i,/^Mer/i,/^Yao/i,/^Gwe/i,/^Sad/i],minWeekdaysParse:n,monthsRegex:s,monthsShortRegex:s,monthsStrictRegex:/^(genver|c[ʼ\']hwevrer|meurzh|ebrel|mae|mezheven|gouere|eost|gwengolo|here|du|kerzu)/i,monthsShortStrictRegex:/^(gen|c[ʼ\']hwe|meu|ebr|mae|eve|gou|eos|gwe|her|du|ker)/i,monthsParse:t,longMonthsParse:t,shortMonthsParse:t,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [a viz] MMMM YYYY",LLL:"D [a viz] MMMM YYYY HH:mm",LLLL:"dddd, D [a viz] MMMM YYYY HH:mm"},calendar:{sameDay:"[Hiziv da] LT",nextDay:"[Warcʼhoazh da] LT",nextWeek:"dddd [da] LT",lastDay:"[Decʼh da] LT",lastWeek:"dddd [paset da] LT",sameElse:"L"},relativeTime:{future:"a-benn %s",past:"%s ʼzo",s:"un nebeud segondennoù",ss:"%d eilenn",m:"ur vunutenn",mm:a,h:"un eur",hh:"%d eur",d:"un devezh",dd:a,M:"ur miz",MM:a,y:"ur bloaz",yy:function(e){switch(function e(a){return a>9?e(a%10):a}(e)){case 1:case 3:case 4:case 5:case 9:return e+" bloaz";default:return e+" vloaz"}}},dayOfMonthOrdinalParse:/\d{1,2}(añ|vet)/,ordinal:function(e){return e+(1===e?"añ":"vet")},week:{dow:1,doy:4},meridiemParse:/a.m.|g.m./,isPM:function(e){return"g.m."===e},meridiem:function(e,a,t){return e<12?"a.m.":"g.m."}})}(e.r(166540))},529619,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t){var s=e+" ";switch(t){case"ss":return 1===e?s+="sekunda":2===e||3===e||4===e?s+="sekunde":s+="sekundi",s;case"mm":return 1===e?s+="minuta":2===e||3===e||4===e?s+="minute":s+="minuta",s;case"h":return"jedan sat";case"hh":return 1===e?s+="sat":2===e||3===e||4===e?s+="sata":s+="sati",s;case"dd":return 1===e?s+="dan":s+="dana",s;case"MM":return 1===e?s+="mjesec":2===e||3===e||4===e?s+="mjeseca":s+="mjeseci",s;case"yy":return 1===e?s+="godina":2===e||3===e||4===e?s+="godine":s+="godina",s}}e.defineLocale("bs",{months:"januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[jučer u] LT",lastWeek:function(){switch(this.day()){case 0:case 3:return"[prošlu] dddd [u] LT";case 6:return"[prošle] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[prošli] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",ss:a,m:function(e,a,t,s){if("m"===t)return a?"jedna minuta":s?"jednu minutu":"jedne minute"},mm:a,h:a,hh:a,d:"dan",dd:a,M:"mjesec",MM:a,y:"godinu",yy:a},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(e.r(166540))},586721,(e,a,t)=>{e.e,e.r(166540).defineLocale("ca",{months:{standalone:"gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"),format:"de gener_de febrer_de març_d'abril_de maig_de juny_de juliol_d'agost_de setembre_d'octubre_de novembre_de desembre".split("_"),isFormat:/D[oD]?(\s)+MMMM/},monthsShort:"gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.".split("_"),monthsParseExact:!0,weekdays:"diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"),weekdaysShort:"dg._dl._dt._dc._dj._dv._ds.".split("_"),weekdaysMin:"dg_dl_dt_dc_dj_dv_ds".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [de] YYYY",ll:"D MMM YYYY",LLL:"D MMMM [de] YYYY [a les] H:mm",lll:"D MMM YYYY, H:mm",LLLL:"dddd D MMMM [de] YYYY [a les] H:mm",llll:"ddd D MMM YYYY, H:mm"},calendar:{sameDay:function(){return"[avui a "+(1!==this.hours()?"les":"la")+"] LT"},nextDay:function(){return"[demà a "+(1!==this.hours()?"les":"la")+"] LT"},nextWeek:function(){return"dddd [a "+(1!==this.hours()?"les":"la")+"] LT"},lastDay:function(){return"[ahir a "+(1!==this.hours()?"les":"la")+"] LT"},lastWeek:function(){return"[el] dddd [passat a "+(1!==this.hours()?"les":"la")+"] LT"},sameElse:"L"},relativeTime:{future:"d'aquí %s",past:"fa %s",s:"uns segons",ss:"%d segons",m:"un minut",mm:"%d minuts",h:"una hora",hh:"%d hores",d:"un dia",dd:"%d dies",M:"un mes",MM:"%d mesos",y:"un any",yy:"%d anys"},dayOfMonthOrdinalParse:/\d{1,2}(r|n|t|è|a)/,ordinal:function(e,a){var t=1===e?"r":2===e?"n":3===e?"r":4===e?"t":"è";return("w"===a||"W"===a)&&(t="a"),e+t},week:{dow:1,doy:4}})},586162,(e,a,t)=>{e.e,function(e){"use strict";var a=[/^led/i,/^úno/i,/^bře/i,/^dub/i,/^kvě/i,/^(čvn|červen$|června)/i,/^(čvc|červenec|července)/i,/^srp/i,/^zář/i,/^říj/i,/^lis/i,/^pro/i],t=/^(leden|únor|březen|duben|květen|červenec|července|červen|června|srpen|září|říjen|listopad|prosinec|led|úno|bře|dub|kvě|čvn|čvc|srp|zář|říj|lis|pro)/i;function s(e){return e>1&&e<5&&1!=~~(e/10)}function n(e,a,t,n){var r=e+" ";switch(t){case"s":return a||n?"pár sekund":"pár sekundami";case"ss":if(a||n)return r+(s(e)?"sekundy":"sekund");return r+"sekundami";case"m":return a?"minuta":n?"minutu":"minutou";case"mm":if(a||n)return r+(s(e)?"minuty":"minut");return r+"minutami";case"h":return a?"hodina":n?"hodinu":"hodinou";case"hh":if(a||n)return r+(s(e)?"hodiny":"hodin");return r+"hodinami";case"d":return a||n?"den":"dnem";case"dd":if(a||n)return r+(s(e)?"dny":"dní");return r+"dny";case"M":return a||n?"měsíc":"měsícem";case"MM":if(a||n)return r+(s(e)?"měsíce":"měsíců");return r+"měsíci";case"y":return a||n?"rok":"rokem";case"yy":if(a||n)return r+(s(e)?"roky":"let");return r+"lety"}}e.defineLocale("cs",{months:{standalone:"leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec".split("_"),format:"ledna_února_března_dubna_května_června_července_srpna_září_října_listopadu_prosince".split("_"),isFormat:/DD?[o.]?(\[[^\[\]]*\]|\s)+MMMM/},monthsShort:"led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro".split("_"),monthsRegex:t,monthsShortRegex:t,monthsStrictRegex:/^(leden|ledna|února|únor|březen|března|duben|dubna|květen|května|červenec|července|červen|června|srpen|srpna|září|říjen|října|listopadu|listopad|prosinec|prosince)/i,monthsShortStrictRegex:/^(led|úno|bře|dub|kvě|čvn|čvc|srp|zář|říj|lis|pro)/i,monthsParse:a,longMonthsParse:a,shortMonthsParse:a,weekdays:"neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota".split("_"),weekdaysShort:"ne_po_út_st_čt_pá_so".split("_"),weekdaysMin:"ne_po_út_st_čt_pá_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm",l:"D. M. YYYY"},calendar:{sameDay:"[dnes v] LT",nextDay:"[zítra v] LT",nextWeek:function(){switch(this.day()){case 0:return"[v neděli v] LT";case 1:case 2:return"[v] dddd [v] LT";case 3:return"[ve středu v] LT";case 4:return"[ve čtvrtek v] LT";case 5:return"[v pátek v] LT";case 6:return"[v sobotu v] LT"}},lastDay:"[včera v] LT",lastWeek:function(){switch(this.day()){case 0:return"[minulou neděli v] LT";case 1:case 2:return"[minulé] dddd [v] LT";case 3:return"[minulou středu v] LT";case 4:case 5:return"[minulý] dddd [v] LT";case 6:return"[minulou sobotu v] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"před %s",s:n,ss:n,m:n,mm:n,h:n,hh:n,d:n,dd:n,M:n,MM:n,y:n,yy:n},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e.r(166540))},745143,(e,a,t)=>{e.e,e.r(166540).defineLocale("cv",{months:"кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав".split("_"),monthsShort:"кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш".split("_"),weekdays:"вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун".split("_"),weekdaysShort:"выр_тун_ытл_юн_кӗҫ_эрн_шӑм".split("_"),weekdaysMin:"вр_тн_ыт_юн_кҫ_эр_шм".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]",LLL:"YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm",LLLL:"dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm"},calendar:{sameDay:"[Паян] LT [сехетре]",nextDay:"[Ыран] LT [сехетре]",lastDay:"[Ӗнер] LT [сехетре]",nextWeek:"[Ҫитес] dddd LT [сехетре]",lastWeek:"[Иртнӗ] dddd LT [сехетре]",sameElse:"L"},relativeTime:{future:function(e){var a=/сехет$/i.exec(e)?"рен":/ҫул$/i.exec(e)?"тан":"ран";return e+a},past:"%s каялла",s:"пӗр-ик ҫеккунт",ss:"%d ҫеккунт",m:"пӗр минут",mm:"%d минут",h:"пӗр сехет",hh:"%d сехет",d:"пӗр кун",dd:"%d кун",M:"пӗр уйӑх",MM:"%d уйӑх",y:"пӗр ҫул",yy:"%d ҫул"},dayOfMonthOrdinalParse:/\d{1,2}-мӗш/,ordinal:"%d-мӗш",week:{dow:1,doy:7}})},608170,(e,a,t)=>{e.e,e.r(166540).defineLocale("cy",{months:"Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr".split("_"),monthsShort:"Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag".split("_"),weekdays:"Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn".split("_"),weekdaysShort:"Sul_Llun_Maw_Mer_Iau_Gwe_Sad".split("_"),weekdaysMin:"Su_Ll_Ma_Me_Ia_Gw_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Heddiw am] LT",nextDay:"[Yfory am] LT",nextWeek:"dddd [am] LT",lastDay:"[Ddoe am] LT",lastWeek:"dddd [diwethaf am] LT",sameElse:"L"},relativeTime:{future:"mewn %s",past:"%s yn ôl",s:"ychydig eiliadau",ss:"%d eiliad",m:"munud",mm:"%d munud",h:"awr",hh:"%d awr",d:"diwrnod",dd:"%d diwrnod",M:"mis",MM:"%d mis",y:"blwyddyn",yy:"%d flynedd"},dayOfMonthOrdinalParse:/\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,ordinal:function(e){var a="";return e>20?a=40===e||50===e||60===e||80===e||100===e?"fed":"ain":e>0&&(a=["","af","il","ydd","ydd","ed","ed","ed","fed","fed","fed","eg","fed","eg","eg","fed","eg","eg","fed","eg","fed"][e]),e+a},week:{dow:1,doy:4}})},596740,(e,a,t)=>{e.e,e.r(166540).defineLocale("da",{months:"januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),weekdaysShort:"søn_man_tir_ons_tor_fre_lør".split("_"),weekdaysMin:"sø_ma_ti_on_to_fr_lø".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd [d.] D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[i dag kl.] LT",nextDay:"[i morgen kl.] LT",nextWeek:"på dddd [kl.] LT",lastDay:"[i går kl.] LT",lastWeek:"[i] dddd[s kl.] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"få sekunder",ss:"%d sekunder",m:"et minut",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dage",M:"en måned",MM:"%d måneder",y:"et år",yy:"%d år"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})},346346,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t,s){var n={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[e+" Tage",e+" Tagen"],w:["eine Woche","einer Woche"],M:["ein Monat","einem Monat"],MM:[e+" Monate",e+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[e+" Jahre",e+" Jahren"]};return a?n[t][0]:n[t][1]}e.defineLocale("de-at",{months:"Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jän._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:a,mm:"%d Minuten",h:a,hh:"%d Stunden",d:a,dd:a,w:a,ww:"%d Wochen",M:a,MM:a,y:a,yy:a},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e.r(166540))},700088,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t,s){var n={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[e+" Tage",e+" Tagen"],w:["eine Woche","einer Woche"],M:["ein Monat","einem Monat"],MM:[e+" Monate",e+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[e+" Jahre",e+" Jahren"]};return a?n[t][0]:n[t][1]}e.defineLocale("de-ch",{months:"Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:a,mm:"%d Minuten",h:a,hh:"%d Stunden",d:a,dd:a,w:a,ww:"%d Wochen",M:a,MM:a,y:a,yy:a},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e.r(166540))},486428,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t,s){var n={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[e+" Tage",e+" Tagen"],w:["eine Woche","einer Woche"],M:["ein Monat","einem Monat"],MM:[e+" Monate",e+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[e+" Jahre",e+" Jahren"]};return a?n[t][0]:n[t][1]}e.defineLocale("de",{months:"Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:a,mm:"%d Minuten",h:a,hh:"%d Stunden",d:a,dd:a,w:a,ww:"%d Wochen",M:a,MM:a,y:a,yy:a},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e.r(166540))},31113,(e,a,t)=>{e.e,function(e){"use strict";var a=["ޖެނުއަރީ","ފެބްރުއަރީ","މާރިޗު","އޭޕްރީލު","މޭ","ޖޫން","ޖުލައި","އޯގަސްޓު","ސެޕްޓެމްބަރު","އޮކްޓޯބަރު","ނޮވެމްބަރު","ޑިސެމްބަރު"],t=["އާދިއްތަ","ހޯމަ","އަންގާރަ","ބުދަ","ބުރާސްފަތި","ހުކުރު","ހޮނިހިރު"];e.defineLocale("dv",{months:a,monthsShort:a,weekdays:t,weekdaysShort:t,weekdaysMin:"އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/M/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/މކ|މފ/,isPM:function(e){return"މފ"===e},meridiem:function(e,a,t){return e<12?"މކ":"މފ"},calendar:{sameDay:"[މިއަދު] LT",nextDay:"[މާދަމާ] LT",nextWeek:"dddd LT",lastDay:"[އިއްޔެ] LT",lastWeek:"[ފާއިތުވި] dddd LT",sameElse:"L"},relativeTime:{future:"ތެރޭގައި %s",past:"ކުރިން %s",s:"ސިކުންތުކޮޅެއް",ss:"d% ސިކުންތު",m:"މިނިޓެއް",mm:"މިނިޓު %d",h:"ގަޑިއިރެއް",hh:"ގަޑިއިރު %d",d:"ދުވަހެއް",dd:"ދުވަސް %d",M:"މަހެއް",MM:"މަސް %d",y:"އަހަރެއް",yy:"އަހަރު %d"},preparse:function(e){return e.replace(/،/g,",")},postformat:function(e){return e.replace(/,/g,"،")},week:{dow:7,doy:12}})}(e.r(166540))},550841,(e,a,t)=>{e.e,e.r(166540).defineLocale("el",{monthsNominativeEl:"Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος".split("_"),monthsGenitiveEl:"Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου".split("_"),months:function(e,a){return e?"string"==typeof a&&/D/.test(a.substring(0,a.indexOf("MMMM")))?this._monthsGenitiveEl[e.month()]:this._monthsNominativeEl[e.month()]:this._monthsNominativeEl},monthsShort:"Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ".split("_"),weekdays:"Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο".split("_"),weekdaysShort:"Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ".split("_"),weekdaysMin:"Κυ_Δε_Τρ_Τε_Πε_Πα_Σα".split("_"),meridiem:function(e,a,t){return e>11?t?"μμ":"ΜΜ":t?"πμ":"ΠΜ"},isPM:function(e){return"μ"===(e+"").toLowerCase()[0]},meridiemParse:/[ΠΜ]\.?Μ?\.?/i,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendarEl:{sameDay:"[Σήμερα {}] LT",nextDay:"[Αύριο {}] LT",nextWeek:"dddd [{}] LT",lastDay:"[Χθες {}] LT",lastWeek:function(){return 6===this.day()?"[το προηγούμενο] dddd [{}] LT":"[την προηγούμενη] dddd [{}] LT"},sameElse:"L"},calendar:function(e,a){var t,s=this._calendarEl[e],n=a&&a.hours();return t=s,("u">typeof Function&&t instanceof Function||"[object Function]"===Object.prototype.toString.call(t))&&(s=s.apply(a)),s.replace("{}",n%12==1?"στη":"στις")},relativeTime:{future:"σε %s",past:"%s πριν",s:"λίγα δευτερόλεπτα",ss:"%d δευτερόλεπτα",m:"ένα λεπτό",mm:"%d λεπτά",h:"μία ώρα",hh:"%d ώρες",d:"μία μέρα",dd:"%d μέρες",M:"ένας μήνας",MM:"%d μήνες",y:"ένας χρόνος",yy:"%d χρόνια"},dayOfMonthOrdinalParse:/\d{1,2}η/,ordinal:"%dη",week:{dow:1,doy:4}})},884432,(e,a,t)=>{e.e,e.r(166540).defineLocale("en-au",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var a=e%10,t=1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th";return e+t},week:{dow:0,doy:4}})},448736,(e,a,t)=>{e.e,e.r(166540).defineLocale("en-ca",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"YYYY-MM-DD",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var a=e%10,t=1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th";return e+t}})},828502,(e,a,t)=>{e.e,e.r(166540).defineLocale("en-gb",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var a=e%10,t=1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th";return e+t},week:{dow:1,doy:4}})},421205,(e,a,t)=>{e.e,e.r(166540).defineLocale("en-ie",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var a=e%10,t=1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th";return e+t},week:{dow:1,doy:4}})},621015,(e,a,t)=>{e.e,e.r(166540).defineLocale("en-il",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var a=e%10,t=1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th";return e+t}})},162743,(e,a,t)=>{e.e,e.r(166540).defineLocale("en-in",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var a=e%10,t=1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th";return e+t},week:{dow:0,doy:6}})},370661,(e,a,t)=>{e.e,e.r(166540).defineLocale("en-nz",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var a=e%10,t=1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th";return e+t},week:{dow:1,doy:4}})},113826,(e,a,t)=>{e.e,e.r(166540).defineLocale("en-sg",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var a=e%10,t=1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th";return e+t},week:{dow:1,doy:4}})},633517,(e,a,t)=>{e.e,e.r(166540).defineLocale("eo",{months:"januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro".split("_"),monthsShort:"jan_feb_mart_apr_maj_jun_jul_aŭg_sept_okt_nov_dec".split("_"),weekdays:"dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato".split("_"),weekdaysShort:"dim_lun_mard_merk_ĵaŭ_ven_sab".split("_"),weekdaysMin:"di_lu_ma_me_ĵa_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"[la] D[-an de] MMMM, YYYY",LLL:"[la] D[-an de] MMMM, YYYY HH:mm",LLLL:"dddd[n], [la] D[-an de] MMMM, YYYY HH:mm",llll:"ddd, [la] D[-an de] MMM, YYYY HH:mm"},meridiemParse:/[ap]\.t\.m/i,isPM:function(e){return"p"===e.charAt(0).toLowerCase()},meridiem:function(e,a,t){return e>11?t?"p.t.m.":"P.T.M.":t?"a.t.m.":"A.T.M."},calendar:{sameDay:"[Hodiaŭ je] LT",nextDay:"[Morgaŭ je] LT",nextWeek:"dddd[n je] LT",lastDay:"[Hieraŭ je] LT",lastWeek:"[pasintan] dddd[n je] LT",sameElse:"L"},relativeTime:{future:"post %s",past:"antaŭ %s",s:"kelkaj sekundoj",ss:"%d sekundoj",m:"unu minuto",mm:"%d minutoj",h:"unu horo",hh:"%d horoj",d:"unu tago",dd:"%d tagoj",M:"unu monato",MM:"%d monatoj",y:"unu jaro",yy:"%d jaroj"},dayOfMonthOrdinalParse:/\d{1,2}a/,ordinal:"%da",week:{dow:1,doy:7}})},954e3,(e,a,t)=>{e.e,function(e){"use strict";var a="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),t="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),s=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],n=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;e.defineLocale("es-do",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(e,s){return e?/-MMM-/.test(s)?t[e.month()]:a[e.month()]:a},monthsRegex:n,monthsShortRegex:n,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:s,longMonthsParse:s,shortMonthsParse:s,weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY h:mm A",LLLL:"dddd, D [de] MMMM [de] YYYY h:mm A"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",w:"una semana",ww:"%d semanas",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})}(e.r(166540))},120137,(e,a,t)=>{e.e,function(e){"use strict";var a="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),t="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),s=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],n=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;e.defineLocale("es-mx",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(e,s){return e?/-MMM-/.test(s)?t[e.month()]:a[e.month()]:a},monthsRegex:n,monthsShortRegex:n,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:s,longMonthsParse:s,shortMonthsParse:s,weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",w:"una semana",ww:"%d semanas",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:0,doy:4},invalidDate:"Fecha inválida"})}(e.r(166540))},528845,(e,a,t)=>{e.e,function(e){"use strict";var a="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),t="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),s=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],n=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;e.defineLocale("es-us",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(e,s){return e?/-MMM-/.test(s)?t[e.month()]:a[e.month()]:a},monthsRegex:n,monthsShortRegex:n,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:s,longMonthsParse:s,shortMonthsParse:s,weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"MM/DD/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY h:mm A",LLLL:"dddd, D [de] MMMM [de] YYYY h:mm A"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",w:"una semana",ww:"%d semanas",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:0,doy:6}})}(e.r(166540))},753818,(e,a,t)=>{e.e,function(e){"use strict";var a="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),t="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),s=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],n=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;e.defineLocale("es",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(e,s){return e?/-MMM-/.test(s)?t[e.month()]:a[e.month()]:a},monthsRegex:n,monthsShortRegex:n,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:s,longMonthsParse:s,shortMonthsParse:s,weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",w:"una semana",ww:"%d semanas",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4},invalidDate:"Fecha inválida"})}(e.r(166540))},54306,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t,s){var n={s:["mõne sekundi","mõni sekund","paar sekundit"],ss:[e+"sekundi",e+"sekundit"],m:["ühe minuti","üks minut"],mm:[e+" minuti",e+" minutit"],h:["ühe tunni","tund aega","üks tund"],hh:[e+" tunni",e+" tundi"],d:["ühe päeva","üks päev"],M:["kuu aja","kuu aega","üks kuu"],MM:[e+" kuu",e+" kuud"],y:["ühe aasta","aasta","üks aasta"],yy:[e+" aasta",e+" aastat"]};return a?n[t][2]?n[t][2]:n[t][1]:s?n[t][0]:n[t][1]}e.defineLocale("et",{months:"jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember".split("_"),monthsShort:"jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets".split("_"),weekdays:"pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev".split("_"),weekdaysShort:"P_E_T_K_N_R_L".split("_"),weekdaysMin:"P_E_T_K_N_R_L".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[Täna,] LT",nextDay:"[Homme,] LT",nextWeek:"[Järgmine] dddd LT",lastDay:"[Eile,] LT",lastWeek:"[Eelmine] dddd LT",sameElse:"L"},relativeTime:{future:"%s pärast",past:"%s tagasi",s:a,ss:a,m:a,mm:a,h:a,hh:a,d:a,dd:"%d päeva",M:a,MM:a,y:a,yy:a},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e.r(166540))},430810,(e,a,t)=>{e.e,e.r(166540).defineLocale("eu",{months:"urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua".split("_"),monthsShort:"urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.".split("_"),monthsParseExact:!0,weekdays:"igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata".split("_"),weekdaysShort:"ig._al._ar._az._og._ol._lr.".split("_"),weekdaysMin:"ig_al_ar_az_og_ol_lr".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY[ko] MMMM[ren] D[a]",LLL:"YYYY[ko] MMMM[ren] D[a] HH:mm",LLLL:"dddd, YYYY[ko] MMMM[ren] D[a] HH:mm",l:"YYYY-M-D",ll:"YYYY[ko] MMM D[a]",lll:"YYYY[ko] MMM D[a] HH:mm",llll:"ddd, YYYY[ko] MMM D[a] HH:mm"},calendar:{sameDay:"[gaur] LT[etan]",nextDay:"[bihar] LT[etan]",nextWeek:"dddd LT[etan]",lastDay:"[atzo] LT[etan]",lastWeek:"[aurreko] dddd LT[etan]",sameElse:"L"},relativeTime:{future:"%s barru",past:"duela %s",s:"segundo batzuk",ss:"%d segundo",m:"minutu bat",mm:"%d minutu",h:"ordu bat",hh:"%d ordu",d:"egun bat",dd:"%d egun",M:"hilabete bat",MM:"%d hilabete",y:"urte bat",yy:"%d urte"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})},374902,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"۱",2:"۲",3:"۳",4:"۴",5:"۵",6:"۶",7:"۷",8:"۸",9:"۹",0:"۰"},t={"۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","۰":"0"};e.defineLocale("fa",{months:"ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر".split("_"),monthsShort:"ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر".split("_"),weekdays:"یک‌شنبه_دوشنبه_سه‌شنبه_چهارشنبه_پنج‌شنبه_جمعه_شنبه".split("_"),weekdaysShort:"یک‌شنبه_دوشنبه_سه‌شنبه_چهارشنبه_پنج‌شنبه_جمعه_شنبه".split("_"),weekdaysMin:"ی_د_س_چ_پ_ج_ش".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/قبل از ظهر|بعد از ظهر/,isPM:function(e){return/بعد از ظهر/.test(e)},meridiem:function(e,a,t){return e<12?"قبل از ظهر":"بعد از ظهر"},calendar:{sameDay:"[امروز ساعت] LT",nextDay:"[فردا ساعت] LT",nextWeek:"dddd [ساعت] LT",lastDay:"[دیروز ساعت] LT",lastWeek:"dddd [پیش] [ساعت] LT",sameElse:"L"},relativeTime:{future:"در %s",past:"%s پیش",s:"چند ثانیه",ss:"%d ثانیه",m:"یک دقیقه",mm:"%d دقیقه",h:"یک ساعت",hh:"%d ساعت",d:"یک روز",dd:"%d روز",M:"یک ماه",MM:"%d ماه",y:"یک سال",yy:"%d سال"},preparse:function(e){return e.replace(/[۰-۹]/g,function(e){return t[e]}).replace(/،/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]}).replace(/,/g,"،")},dayOfMonthOrdinalParse:/\d{1,2}م/,ordinal:"%dم",week:{dow:6,doy:12}})}(e.r(166540))},412450,(e,a,t)=>{e.e,function(e){"use strict";var a="nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän".split(" "),t=["nolla","yhden","kahden","kolmen","neljän","viiden","kuuden",a[7],a[8],a[9]];function s(e,s,n,r){var d,i,_="";switch(n){case"s":return r?"muutaman sekunnin":"muutama sekunti";case"ss":_=r?"sekunnin":"sekuntia";break;case"m":return r?"minuutin":"minuutti";case"mm":_=r?"minuutin":"minuuttia";break;case"h":return r?"tunnin":"tunti";case"hh":_=r?"tunnin":"tuntia";break;case"d":return r?"päivän":"päivä";case"dd":_=r?"päivän":"päivää";break;case"M":return r?"kuukauden":"kuukausi";case"MM":_=r?"kuukauden":"kuukautta";break;case"y":return r?"vuoden":"vuosi";case"yy":_=r?"vuoden":"vuotta"}return d=e,i=r,(d<10?i?t[d]:a[d]:d)+" "+_}e.defineLocale("fi",{months:"tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),monthsShort:"tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu".split("_"),weekdays:"sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),weekdaysShort:"su_ma_ti_ke_to_pe_la".split("_"),weekdaysMin:"su_ma_ti_ke_to_pe_la".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"Do MMMM[ta] YYYY",LLL:"Do MMMM[ta] YYYY, [klo] HH.mm",LLLL:"dddd, Do MMMM[ta] YYYY, [klo] HH.mm",l:"D.M.YYYY",ll:"Do MMM YYYY",lll:"Do MMM YYYY, [klo] HH.mm",llll:"ddd, Do MMM YYYY, [klo] HH.mm"},calendar:{sameDay:"[tänään] [klo] LT",nextDay:"[huomenna] [klo] LT",nextWeek:"dddd [klo] LT",lastDay:"[eilen] [klo] LT",lastWeek:"[viime] dddd[na] [klo] LT",sameElse:"L"},relativeTime:{future:"%s päästä",past:"%s sitten",s:s,ss:s,m:s,mm:s,h:s,hh:s,d:s,dd:s,M:s,MM:s,y:s,yy:s},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e.r(166540))},321329,(e,a,t)=>{e.e,e.r(166540).defineLocale("fil",{months:"Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre".split("_"),monthsShort:"Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis".split("_"),weekdays:"Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado".split("_"),weekdaysShort:"Lin_Lun_Mar_Miy_Huw_Biy_Sab".split("_"),weekdaysMin:"Li_Lu_Ma_Mi_Hu_Bi_Sab".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"MM/D/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY HH:mm",LLLL:"dddd, MMMM DD, YYYY HH:mm"},calendar:{sameDay:"LT [ngayong araw]",nextDay:"[Bukas ng] LT",nextWeek:"LT [sa susunod na] dddd",lastDay:"LT [kahapon]",lastWeek:"LT [noong nakaraang] dddd",sameElse:"L"},relativeTime:{future:"sa loob ng %s",past:"%s ang nakalipas",s:"ilang segundo",ss:"%d segundo",m:"isang minuto",mm:"%d minuto",h:"isang oras",hh:"%d oras",d:"isang araw",dd:"%d araw",M:"isang buwan",MM:"%d buwan",y:"isang taon",yy:"%d taon"},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:function(e){return e},week:{dow:1,doy:4}})},473679,(e,a,t)=>{e.e,e.r(166540).defineLocale("fo",{months:"januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),weekdays:"sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur".split("_"),weekdaysShort:"sun_mán_týs_mik_hós_frí_ley".split("_"),weekdaysMin:"su_má_tý_mi_hó_fr_le".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D. MMMM, YYYY HH:mm"},calendar:{sameDay:"[Í dag kl.] LT",nextDay:"[Í morgin kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[Í gjár kl.] LT",lastWeek:"[síðstu] dddd [kl] LT",sameElse:"L"},relativeTime:{future:"um %s",past:"%s síðani",s:"fá sekund",ss:"%d sekundir",m:"ein minuttur",mm:"%d minuttir",h:"ein tími",hh:"%d tímar",d:"ein dagur",dd:"%d dagar",M:"ein mánaður",MM:"%d mánaðir",y:"eitt ár",yy:"%d ár"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})},874573,(e,a,t)=>{e.e,e.r(166540).defineLocale("fr-ca",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd’hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|e)/,ordinal:function(e,a){switch(a){default:case"M":case"Q":case"D":case"DDD":case"d":return e+(1===e?"er":"e");case"w":case"W":return e+(1===e?"re":"e")}}})},639994,(e,a,t)=>{e.e,e.r(166540).defineLocale("fr-ch",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd’hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|e)/,ordinal:function(e,a){switch(a){default:case"M":case"Q":case"D":case"DDD":case"d":return e+(1===e?"er":"e");case"w":case"W":return e+(1===e?"re":"e")}},week:{dow:1,doy:4}})},618184,(e,a,t)=>{e.e,function(e){"use strict";var a=/(janv\.?|févr\.?|mars|avr\.?|mai|juin|juil\.?|août|sept\.?|oct\.?|nov\.?|déc\.?|janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i,t=[/^janv/i,/^févr/i,/^mars/i,/^avr/i,/^mai/i,/^juin/i,/^juil/i,/^août/i,/^sept/i,/^oct/i,/^nov/i,/^déc/i];e.defineLocale("fr",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsRegex:a,monthsShortRegex:a,monthsStrictRegex:/^(janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i,monthsShortStrictRegex:/(janv\.?|févr\.?|mars|avr\.?|mai|juin|juil\.?|août|sept\.?|oct\.?|nov\.?|déc\.?)/i,monthsParse:t,longMonthsParse:t,shortMonthsParse:t,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd’hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",w:"une semaine",ww:"%d semaines",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|)/,ordinal:function(e,a){switch(a){case"D":return e+(1===e?"er":"");default:case"M":case"Q":case"DDD":case"d":return e+(1===e?"er":"e");case"w":case"W":return e+(1===e?"re":"e")}},week:{dow:1,doy:4}})}(e.r(166540))},439552,(e,a,t)=>{e.e,function(e){"use strict";var a="jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.".split("_"),t="jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_");e.defineLocale("fy",{months:"jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber".split("_"),monthsShort:function(e,s){return e?/-MMM-/.test(s)?t[e.month()]:a[e.month()]:a},monthsParseExact:!0,weekdays:"snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon".split("_"),weekdaysShort:"si._mo._ti._wo._to._fr._so.".split("_"),weekdaysMin:"Si_Mo_Ti_Wo_To_Fr_So".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[hjoed om] LT",nextDay:"[moarn om] LT",nextWeek:"dddd [om] LT",lastDay:"[juster om] LT",lastWeek:"[ôfrûne] dddd [om] LT",sameElse:"L"},relativeTime:{future:"oer %s",past:"%s lyn",s:"in pear sekonden",ss:"%d sekonden",m:"ien minút",mm:"%d minuten",h:"ien oere",hh:"%d oeren",d:"ien dei",dd:"%d dagen",M:"ien moanne",MM:"%d moannen",y:"ien jier",yy:"%d jierren"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(e){return e+(1===e||8===e||e>=20?"ste":"de")},week:{dow:1,doy:4}})}(e.r(166540))},866284,(e,a,t)=>{e.e,e.r(166540).defineLocale("ga",{months:["Eanáir","Feabhra","Márta","Aibreán","Bealtaine","Meitheamh","Iúil","Lúnasa","Meán Fómhair","Deireadh Fómhair","Samhain","Nollaig"],monthsShort:["Ean","Feabh","Márt","Aib","Beal","Meith","Iúil","Lún","M.F.","D.F.","Samh","Noll"],monthsParseExact:!0,weekdays:["Dé Domhnaigh","Dé Luain","Dé Máirt","Dé Céadaoin","Déardaoin","Dé hAoine","Dé Sathairn"],weekdaysShort:["Domh","Luan","Máirt","Céad","Déar","Aoine","Sath"],weekdaysMin:["Do","Lu","Má","Cé","Dé","A","Sa"],longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Inniu ag] LT",nextDay:"[Amárach ag] LT",nextWeek:"dddd [ag] LT",lastDay:"[Inné ag] LT",lastWeek:"dddd [seo caite] [ag] LT",sameElse:"L"},relativeTime:{future:"i %s",past:"%s ó shin",s:"cúpla soicind",ss:"%d soicind",m:"nóiméad",mm:"%d nóiméad",h:"uair an chloig",hh:"%d uair an chloig",d:"lá",dd:"%d lá",M:"mí",MM:"%d míonna",y:"bliain",yy:"%d bliain"},dayOfMonthOrdinalParse:/\d{1,2}(d|na|mh)/,ordinal:function(e){return e+(1===e?"d":e%10==2?"na":"mh")},week:{dow:1,doy:4}})},810136,(e,a,t)=>{e.e,e.r(166540).defineLocale("gd",{months:["Am Faoilleach","An Gearran","Am Màrt","An Giblean","An Cèitean","An t-Ògmhios","An t-Iuchar","An Lùnastal","An t-Sultain","An Dàmhair","An t-Samhain","An Dùbhlachd"],monthsShort:["Faoi","Gear","Màrt","Gibl","Cèit","Ògmh","Iuch","Lùn","Sult","Dàmh","Samh","Dùbh"],monthsParseExact:!0,weekdays:["Didòmhnaich","Diluain","Dimàirt","Diciadain","Diardaoin","Dihaoine","Disathairne"],weekdaysShort:["Did","Dil","Dim","Dic","Dia","Dih","Dis"],weekdaysMin:["Dò","Lu","Mà","Ci","Ar","Ha","Sa"],longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[An-diugh aig] LT",nextDay:"[A-màireach aig] LT",nextWeek:"dddd [aig] LT",lastDay:"[An-dè aig] LT",lastWeek:"dddd [seo chaidh] [aig] LT",sameElse:"L"},relativeTime:{future:"ann an %s",past:"bho chionn %s",s:"beagan diogan",ss:"%d diogan",m:"mionaid",mm:"%d mionaidean",h:"uair",hh:"%d uairean",d:"latha",dd:"%d latha",M:"mìos",MM:"%d mìosan",y:"bliadhna",yy:"%d bliadhna"},dayOfMonthOrdinalParse:/\d{1,2}(d|na|mh)/,ordinal:function(e){return e+(1===e?"d":e%10==2?"na":"mh")},week:{dow:1,doy:4}})},703131,(e,a,t)=>{e.e,e.r(166540).defineLocale("gl",{months:"xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro".split("_"),monthsShort:"xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"domingo_luns_martes_mércores_xoves_venres_sábado".split("_"),weekdaysShort:"dom._lun._mar._mér._xov._ven._sáb.".split("_"),weekdaysMin:"do_lu_ma_mé_xo_ve_sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoxe "+(1!==this.hours()?"ás":"á")+"] LT"},nextDay:function(){return"[mañá "+(1!==this.hours()?"ás":"á")+"] LT"},nextWeek:function(){return"dddd ["+(1!==this.hours()?"ás":"a")+"] LT"},lastDay:function(){return"[onte "+(1!==this.hours()?"á":"a")+"] LT"},lastWeek:function(){return"[o] dddd [pasado "+(1!==this.hours()?"ás":"a")+"] LT"},sameElse:"L"},relativeTime:{future:function(e){return 0===e.indexOf("un")?"n"+e:"en "+e},past:"hai %s",s:"uns segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"unha hora",hh:"%d horas",d:"un día",dd:"%d días",M:"un mes",MM:"%d meses",y:"un ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})},56861,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t,s){var n={s:["थोडया सॅकंडांनी","थोडे सॅकंड"],ss:[e+" सॅकंडांनी",e+" सॅकंड"],m:["एका मिणटान","एक मिनूट"],mm:[e+" मिणटांनी",e+" मिणटां"],h:["एका वरान","एक वर"],hh:[e+" वरांनी",e+" वरां"],d:["एका दिसान","एक दीस"],dd:[e+" दिसांनी",e+" दीस"],M:["एका म्हयन्यान","एक म्हयनो"],MM:[e+" म्हयन्यानी",e+" म्हयने"],y:["एका वर्सान","एक वर्स"],yy:[e+" वर्सांनी",e+" वर्सां"]};return s?n[t][0]:n[t][1]}e.defineLocale("gom-deva",{months:{standalone:"जानेवारी_फेब्रुवारी_मार्च_एप्रील_मे_जून_जुलय_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर".split("_"),format:"जानेवारीच्या_फेब्रुवारीच्या_मार्चाच्या_एप्रीलाच्या_मेयाच्या_जूनाच्या_जुलयाच्या_ऑगस्टाच्या_सप्टेंबराच्या_ऑक्टोबराच्या_नोव्हेंबराच्या_डिसेंबराच्या".split("_"),isFormat:/MMMM(\s)+D[oD]?/},monthsShort:"जाने._फेब्रु._मार्च_एप्री._मे_जून_जुल._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.".split("_"),monthsParseExact:!0,weekdays:"आयतार_सोमार_मंगळार_बुधवार_बिरेस्तार_सुक्रार_शेनवार".split("_"),weekdaysShort:"आयत._सोम._मंगळ._बुध._ब्रेस्त._सुक्र._शेन.".split("_"),weekdaysMin:"आ_सो_मं_बु_ब्रे_सु_शे".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"A h:mm [वाजतां]",LTS:"A h:mm:ss [वाजतां]",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY A h:mm [वाजतां]",LLLL:"dddd, MMMM Do, YYYY, A h:mm [वाजतां]",llll:"ddd, D MMM YYYY, A h:mm [वाजतां]"},calendar:{sameDay:"[आयज] LT",nextDay:"[फाल्यां] LT",nextWeek:"[फुडलो] dddd[,] LT",lastDay:"[काल] LT",lastWeek:"[फाटलो] dddd[,] LT",sameElse:"L"},relativeTime:{future:"%s",past:"%s आदीं",s:a,ss:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},dayOfMonthOrdinalParse:/\d{1,2}(वेर)/,ordinal:function(e,a){return"D"===a?e+"वेर":e},week:{dow:0,doy:3},meridiemParse:/राती|सकाळीं|दनपारां|सांजे/,meridiemHour:function(e,a){return(12===e&&(e=0),"राती"===a)?e<4?e:e+12:"सकाळीं"===a?e:"दनपारां"===a?e>12?e:e+12:"सांजे"===a?e+12:void 0},meridiem:function(e,a,t){return e<4?"राती":e<12?"सकाळीं":e<16?"दनपारां":e<20?"सांजे":"राती"}})}(e.r(166540))},227159,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t,s){var n={s:["thoddea sekondamni","thodde sekond"],ss:[e+" sekondamni",e+" sekond"],m:["eka mintan","ek minut"],mm:[e+" mintamni",e+" mintam"],h:["eka voran","ek vor"],hh:[e+" voramni",e+" voram"],d:["eka disan","ek dis"],dd:[e+" disamni",e+" dis"],M:["eka mhoinean","ek mhoino"],MM:[e+" mhoineamni",e+" mhoine"],y:["eka vorsan","ek voros"],yy:[e+" vorsamni",e+" vorsam"]};return s?n[t][0]:n[t][1]}e.defineLocale("gom-latn",{months:{standalone:"Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr".split("_"),format:"Janerachea_Febrerachea_Marsachea_Abrilachea_Maiachea_Junachea_Julaiachea_Agostachea_Setembrachea_Otubrachea_Novembrachea_Dezembrachea".split("_"),isFormat:/MMMM(\s)+D[oD]?/},monthsShort:"Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Aitar_Somar_Mongllar_Budhvar_Birestar_Sukrar_Son'var".split("_"),weekdaysShort:"Ait._Som._Mon._Bud._Bre._Suk._Son.".split("_"),weekdaysMin:"Ai_Sm_Mo_Bu_Br_Su_Sn".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"A h:mm [vazta]",LTS:"A h:mm:ss [vazta]",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY A h:mm [vazta]",LLLL:"dddd, MMMM Do, YYYY, A h:mm [vazta]",llll:"ddd, D MMM YYYY, A h:mm [vazta]"},calendar:{sameDay:"[Aiz] LT",nextDay:"[Faleam] LT",nextWeek:"[Fuddlo] dddd[,] LT",lastDay:"[Kal] LT",lastWeek:"[Fattlo] dddd[,] LT",sameElse:"L"},relativeTime:{future:"%s",past:"%s adim",s:a,ss:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},dayOfMonthOrdinalParse:/\d{1,2}(er)/,ordinal:function(e,a){return"D"===a?e+"er":e},week:{dow:0,doy:3},meridiemParse:/rati|sokallim|donparam|sanje/,meridiemHour:function(e,a){return(12===e&&(e=0),"rati"===a)?e<4?e:e+12:"sokallim"===a?e:"donparam"===a?e>12?e:e+12:"sanje"===a?e+12:void 0},meridiem:function(e,a,t){return e<4?"rati":e<12?"sokallim":e<16?"donparam":e<20?"sanje":"rati"}})}(e.r(166540))},277496,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"૧",2:"૨",3:"૩",4:"૪",5:"૫",6:"૬",7:"૭",8:"૮",9:"૯",0:"૦"},t={"૧":"1","૨":"2","૩":"3","૪":"4","૫":"5","૬":"6","૭":"7","૮":"8","૯":"9","૦":"0"};e.defineLocale("gu",{months:"જાન્યુઆરી_ફેબ્રુઆરી_માર્ચ_એપ્રિલ_મે_જૂન_જુલાઈ_ઑગસ્ટ_સપ્ટેમ્બર_ઑક્ટ્બર_નવેમ્બર_ડિસેમ્બર".split("_"),monthsShort:"જાન્યુ._ફેબ્રુ._માર્ચ_એપ્રિ._મે_જૂન_જુલા._ઑગ._સપ્ટે._ઑક્ટ્._નવે._ડિસે.".split("_"),monthsParseExact:!0,weekdays:"રવિવાર_સોમવાર_મંગળવાર_બુધ્વાર_ગુરુવાર_શુક્રવાર_શનિવાર".split("_"),weekdaysShort:"રવિ_સોમ_મંગળ_બુધ્_ગુરુ_શુક્ર_શનિ".split("_"),weekdaysMin:"ર_સો_મં_બુ_ગુ_શુ_શ".split("_"),longDateFormat:{LT:"A h:mm વાગ્યે",LTS:"A h:mm:ss વાગ્યે",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm વાગ્યે",LLLL:"dddd, D MMMM YYYY, A h:mm વાગ્યે"},calendar:{sameDay:"[આજ] LT",nextDay:"[કાલે] LT",nextWeek:"dddd, LT",lastDay:"[ગઇકાલે] LT",lastWeek:"[પાછલા] dddd, LT",sameElse:"L"},relativeTime:{future:"%s મા",past:"%s પહેલા",s:"અમુક પળો",ss:"%d સેકંડ",m:"એક મિનિટ",mm:"%d મિનિટ",h:"એક કલાક",hh:"%d કલાક",d:"એક દિવસ",dd:"%d દિવસ",M:"એક મહિનો",MM:"%d મહિનો",y:"એક વર્ષ",yy:"%d વર્ષ"},preparse:function(e){return e.replace(/[૧૨૩૪૫૬૭૮૯૦]/g,function(e){return t[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]})},meridiemParse:/રાત|બપોર|સવાર|સાંજ/,meridiemHour:function(e,a){return(12===e&&(e=0),"રાત"===a)?e<4?e:e+12:"સવાર"===a?e:"બપોર"===a?e>=10?e:e+12:"સાંજ"===a?e+12:void 0},meridiem:function(e,a,t){return e<4?"રાત":e<10?"સવાર":e<17?"બપોર":e<20?"સાંજ":"રાત"},week:{dow:0,doy:6}})}(e.r(166540))},796669,(e,a,t)=>{e.e,e.r(166540).defineLocale("he",{months:"ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר".split("_"),monthsShort:"ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳".split("_"),weekdays:"ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת".split("_"),weekdaysShort:"א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳".split("_"),weekdaysMin:"א_ב_ג_ד_ה_ו_ש".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [ב]MMMM YYYY",LLL:"D [ב]MMMM YYYY HH:mm",LLLL:"dddd, D [ב]MMMM YYYY HH:mm",l:"D/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[היום ב־]LT",nextDay:"[מחר ב־]LT",nextWeek:"dddd [בשעה] LT",lastDay:"[אתמול ב־]LT",lastWeek:"[ביום] dddd [האחרון בשעה] LT",sameElse:"L"},relativeTime:{future:"בעוד %s",past:"לפני %s",s:"מספר שניות",ss:"%d שניות",m:"דקה",mm:"%d דקות",h:"שעה",hh:function(e){return 2===e?"שעתיים":e+" שעות"},d:"יום",dd:function(e){return 2===e?"יומיים":e+" ימים"},M:"חודש",MM:function(e){return 2===e?"חודשיים":e+" חודשים"},y:"שנה",yy:function(e){return 2===e?"שנתיים":e%10==0&&10!==e?e+" שנה":e+" שנים"}},meridiemParse:/אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,isPM:function(e){return/^(אחה"צ|אחרי הצהריים|בערב)$/.test(e)},meridiem:function(e,a,t){return e<5?"לפנות בוקר":e<10?"בבוקר":e<12?t?'לפנה"צ':"לפני הצהריים":e<18?t?'אחה"צ':"אחרי הצהריים":"בערב"}})},725949,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"१",2:"२",3:"३",4:"४",5:"५",6:"६",7:"७",8:"८",9:"९",0:"०"},t={"१":"1","२":"2","३":"3","४":"4","५":"5","६":"6","७":"7","८":"8","९":"9","०":"0"},s=[/^जन/i,/^फ़र|फर/i,/^मार्च/i,/^अप्रै/i,/^मई/i,/^जून/i,/^जुल/i,/^अग/i,/^सितं|सित/i,/^अक्टू/i,/^नव|नवं/i,/^दिसं|दिस/i];e.defineLocale("hi",{months:{format:"जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर".split("_"),standalone:"जनवरी_फरवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितंबर_अक्टूबर_नवंबर_दिसंबर".split("_")},monthsShort:"जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.".split("_"),weekdays:"रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार".split("_"),weekdaysShort:"रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि".split("_"),weekdaysMin:"र_सो_मं_बु_गु_शु_श".split("_"),longDateFormat:{LT:"A h:mm बजे",LTS:"A h:mm:ss बजे",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm बजे",LLLL:"dddd, D MMMM YYYY, A h:mm बजे"},monthsParse:s,longMonthsParse:s,shortMonthsParse:[/^जन/i,/^फ़र/i,/^मार्च/i,/^अप्रै/i,/^मई/i,/^जून/i,/^जुल/i,/^अग/i,/^सित/i,/^अक्टू/i,/^नव/i,/^दिस/i],monthsRegex:/^(जनवरी|जन\.?|फ़रवरी|फरवरी|फ़र\.?|मार्च?|अप्रैल|अप्रै\.?|मई?|जून?|जुलाई|जुल\.?|अगस्त|अग\.?|सितम्बर|सितंबर|सित\.?|अक्टूबर|अक्टू\.?|नवम्बर|नवंबर|नव\.?|दिसम्बर|दिसंबर|दिस\.?)/i,monthsShortRegex:/^(जनवरी|जन\.?|फ़रवरी|फरवरी|फ़र\.?|मार्च?|अप्रैल|अप्रै\.?|मई?|जून?|जुलाई|जुल\.?|अगस्त|अग\.?|सितम्बर|सितंबर|सित\.?|अक्टूबर|अक्टू\.?|नवम्बर|नवंबर|नव\.?|दिसम्बर|दिसंबर|दिस\.?)/i,monthsStrictRegex:/^(जनवरी?|फ़रवरी|फरवरी?|मार्च?|अप्रैल?|मई?|जून?|जुलाई?|अगस्त?|सितम्बर|सितंबर|सित?\.?|अक्टूबर|अक्टू\.?|नवम्बर|नवंबर?|दिसम्बर|दिसंबर?)/i,monthsShortStrictRegex:/^(जन\.?|फ़र\.?|मार्च?|अप्रै\.?|मई?|जून?|जुल\.?|अग\.?|सित\.?|अक्टू\.?|नव\.?|दिस\.?)/i,calendar:{sameDay:"[आज] LT",nextDay:"[कल] LT",nextWeek:"dddd, LT",lastDay:"[कल] LT",lastWeek:"[पिछले] dddd, LT",sameElse:"L"},relativeTime:{future:"%s में",past:"%s पहले",s:"कुछ ही क्षण",ss:"%d सेकंड",m:"एक मिनट",mm:"%d मिनट",h:"एक घंटा",hh:"%d घंटे",d:"एक दिन",dd:"%d दिन",M:"एक महीने",MM:"%d महीने",y:"एक वर्ष",yy:"%d वर्ष"},preparse:function(e){return e.replace(/[१२३४५६७८९०]/g,function(e){return t[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]})},meridiemParse:/रात|सुबह|दोपहर|शाम/,meridiemHour:function(e,a){return(12===e&&(e=0),"रात"===a)?e<4?e:e+12:"सुबह"===a?e:"दोपहर"===a?e>=10?e:e+12:"शाम"===a?e+12:void 0},meridiem:function(e,a,t){return e<4?"रात":e<10?"सुबह":e<17?"दोपहर":e<20?"शाम":"रात"},week:{dow:0,doy:6}})}(e.r(166540))},863164,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t){var s=e+" ";switch(t){case"ss":return 1===e?s+="sekunda":2===e||3===e||4===e?s+="sekunde":s+="sekundi",s;case"m":return a?"jedna minuta":"jedne minute";case"mm":return 1===e?s+="minuta":2===e||3===e||4===e?s+="minute":s+="minuta",s;case"h":return a?"jedan sat":"jednog sata";case"hh":return 1===e?s+="sat":2===e||3===e||4===e?s+="sata":s+="sati",s;case"dd":return 1===e?s+="dan":s+="dana",s;case"MM":return 1===e?s+="mjesec":2===e||3===e||4===e?s+="mjeseca":s+="mjeseci",s;case"yy":return 1===e?s+="godina":2===e||3===e||4===e?s+="godine":s+="godina",s}}e.defineLocale("hr",{months:{format:"siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca".split("_"),standalone:"siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac".split("_")},monthsShort:"sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"Do MMMM YYYY",LLL:"Do MMMM YYYY H:mm",LLLL:"dddd, Do MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[jučer u] LT",lastWeek:function(){switch(this.day()){case 0:return"[prošlu] [nedjelju] [u] LT";case 3:return"[prošlu] [srijedu] [u] LT";case 6:return"[prošle] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[prošli] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",ss:a,m:a,mm:a,h:a,hh:a,d:"dan",dd:a,M:"mjesec",MM:a,y:"godinu",yy:a},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(e.r(166540))},491161,(e,a,t)=>{e.e,function(e){"use strict";var a="vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton".split(" ");function t(e,a,t,s){switch(t){case"s":return s||a?"néhány másodperc":"néhány másodperce";case"ss":return e+(s||a)?" másodperc":" másodperce";case"m":return"egy"+(s||a?" perc":" perce");case"mm":return e+(s||a?" perc":" perce");case"h":return"egy"+(s||a?" óra":" órája");case"hh":return e+(s||a?" óra":" órája");case"d":return"egy"+(s||a?" nap":" napja");case"dd":return e+(s||a?" nap":" napja");case"M":return"egy"+(s||a?" hónap":" hónapja");case"MM":return e+(s||a?" hónap":" hónapja");case"y":return"egy"+(s||a?" év":" éve");case"yy":return e+(s||a?" év":" éve")}return""}function s(e){return(e?"":"[múlt] ")+"["+a[this.day()]+"] LT[-kor]"}e.defineLocale("hu",{months:"január_február_március_április_május_június_július_augusztus_szeptember_október_november_december".split("_"),monthsShort:"jan._feb._márc._ápr._máj._jún._júl._aug._szept._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat".split("_"),weekdaysShort:"vas_hét_kedd_sze_csüt_pén_szo".split("_"),weekdaysMin:"v_h_k_sze_cs_p_szo".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"YYYY.MM.DD.",LL:"YYYY. MMMM D.",LLL:"YYYY. MMMM D. H:mm",LLLL:"YYYY. MMMM D., dddd H:mm"},meridiemParse:/de|du/i,isPM:function(e){return"u"===e.charAt(1).toLowerCase()},meridiem:function(e,a,t){return e<12?!0===t?"de":"DE":!0===t?"du":"DU"},calendar:{sameDay:"[ma] LT[-kor]",nextDay:"[holnap] LT[-kor]",nextWeek:function(){return s.call(this,!0)},lastDay:"[tegnap] LT[-kor]",lastWeek:function(){return s.call(this,!1)},sameElse:"L"},relativeTime:{future:"%s múlva",past:"%s",s:t,ss:t,m:t,mm:t,h:t,hh:t,d:t,dd:t,M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e.r(166540))},122472,(e,a,t)=>{e.e,e.r(166540).defineLocale("hy-am",{months:{format:"հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի".split("_"),standalone:"հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր".split("_")},monthsShort:"հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ".split("_"),weekdays:"կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ".split("_"),weekdaysShort:"կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ".split("_"),weekdaysMin:"կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY թ.",LLL:"D MMMM YYYY թ., HH:mm",LLLL:"dddd, D MMMM YYYY թ., HH:mm"},calendar:{sameDay:"[այսօր] LT",nextDay:"[վաղը] LT",lastDay:"[երեկ] LT",nextWeek:function(){return"dddd [օրը ժամը] LT"},lastWeek:function(){return"[անցած] dddd [օրը ժամը] LT"},sameElse:"L"},relativeTime:{future:"%s հետո",past:"%s առաջ",s:"մի քանի վայրկյան",ss:"%d վայրկյան",m:"րոպե",mm:"%d րոպե",h:"ժամ",hh:"%d ժամ",d:"օր",dd:"%d օր",M:"ամիս",MM:"%d ամիս",y:"տարի",yy:"%d տարի"},meridiemParse:/գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,isPM:function(e){return/^(ցերեկվա|երեկոյան)$/.test(e)},meridiem:function(e){return e<4?"գիշերվա":e<12?"առավոտվա":e<17?"ցերեկվա":"երեկոյան"},dayOfMonthOrdinalParse:/\d{1,2}|\d{1,2}-(ին|րդ)/,ordinal:function(e,a){switch(a){case"DDD":case"w":case"W":case"DDDo":if(1===e)return e+"-ին";return e+"-րդ";default:return e}},week:{dow:1,doy:7}})},261476,(e,a,t)=>{e.e,e.r(166540).defineLocale("id",{months:"Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Mei_Jun_Jul_Agt_Sep_Okt_Nov_Des".split("_"),weekdays:"Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu".split("_"),weekdaysShort:"Min_Sen_Sel_Rab_Kam_Jum_Sab".split("_"),weekdaysMin:"Mg_Sn_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|siang|sore|malam/,meridiemHour:function(e,a){return(12===e&&(e=0),"pagi"===a)?e:"siang"===a?e>=11?e:e+12:"sore"===a||"malam"===a?e+12:void 0},meridiem:function(e,a,t){return e<11?"pagi":e<15?"siang":e<19?"sore":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Besok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kemarin pukul] LT",lastWeek:"dddd [lalu pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lalu",s:"beberapa detik",ss:"%d detik",m:"semenit",mm:"%d menit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:0,doy:6}})},595500,(e,a,t)=>{e.e,function(e){"use strict";function a(e){if(e%100==11);else if(e%10==1)return!1;return!0}function t(e,t,s,n){var r=e+" ";switch(s){case"s":return t||n?"nokkrar sekúndur":"nokkrum sekúndum";case"ss":if(a(e))return r+(t||n?"sekúndur":"sekúndum");return r+"sekúnda";case"m":return t?"mínúta":"mínútu";case"mm":if(a(e))return r+(t||n?"mínútur":"mínútum");if(t)return r+"mínúta";return r+"mínútu";case"hh":if(a(e))return r+(t||n?"klukkustundir":"klukkustundum");return r+"klukkustund";case"d":if(t)return"dagur";return n?"dag":"degi";case"dd":if(a(e)){if(t)return r+"dagar";return r+(n?"daga":"dögum")}if(t)return r+"dagur";return r+(n?"dag":"degi");case"M":if(t)return"mánuður";return n?"mánuð":"mánuði";case"MM":if(a(e)){if(t)return r+"mánuðir";return r+(n?"mánuði":"mánuðum")}if(t)return r+"mánuður";return r+(n?"mánuð":"mánuði");case"y":return t||n?"ár":"ári";case"yy":if(a(e))return r+(t||n?"ár":"árum");return r+(t||n?"ár":"ári")}}e.defineLocale("is",{months:"janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember".split("_"),monthsShort:"jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des".split("_"),weekdays:"sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur".split("_"),weekdaysShort:"sun_mán_þri_mið_fim_fös_lau".split("_"),weekdaysMin:"Su_Má_Þr_Mi_Fi_Fö_La".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] H:mm",LLLL:"dddd, D. MMMM YYYY [kl.] H:mm"},calendar:{sameDay:"[í dag kl.] LT",nextDay:"[á morgun kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[í gær kl.] LT",lastWeek:"[síðasta] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"eftir %s",past:"fyrir %s síðan",s:t,ss:t,m:t,mm:t,h:"klukkustund",hh:t,d:t,dd:t,M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e.r(166540))},351426,(e,a,t)=>{e.e,e.r(166540).defineLocale("it-ch",{months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato".split("_"),weekdaysShort:"dom_lun_mar_mer_gio_ven_sab".split("_"),weekdaysMin:"do_lu_ma_me_gi_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:function(){return 0===this.day()?"[la scorsa] dddd [alle] LT":"[lo scorso] dddd [alle] LT"},sameElse:"L"},relativeTime:{future:function(e){return(/^[0-9].+$/.test(e)?"tra":"in")+" "+e},past:"%s fa",s:"alcuni secondi",ss:"%d secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})},988869,(e,a,t)=>{e.e,e.r(166540).defineLocale("it",{months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato".split("_"),weekdaysShort:"dom_lun_mar_mer_gio_ven_sab".split("_"),weekdaysMin:"do_lu_ma_me_gi_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:function(){return"[Oggi a"+(this.hours()>1?"lle ":0===this.hours()?" ":"ll'")+"]LT"},nextDay:function(){return"[Domani a"+(this.hours()>1?"lle ":0===this.hours()?" ":"ll'")+"]LT"},nextWeek:function(){return"dddd [a"+(this.hours()>1?"lle ":0===this.hours()?" ":"ll'")+"]LT"},lastDay:function(){return"[Ieri a"+(this.hours()>1?"lle ":0===this.hours()?" ":"ll'")+"]LT"},lastWeek:function(){return 0===this.day()?"[La scorsa] dddd [a"+(this.hours()>1?"lle ":0===this.hours()?" ":"ll'")+"]LT":"[Lo scorso] dddd [a"+(this.hours()>1?"lle ":0===this.hours()?" ":"ll'")+"]LT"},sameElse:"L"},relativeTime:{future:"tra %s",past:"%s fa",s:"alcuni secondi",ss:"%d secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",w:"una settimana",ww:"%d settimane",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})},622116,(e,a,t)=>{e.e,e.r(166540).defineLocale("ja",{eras:[{since:"2019-05-01",offset:1,name:"令和",narrow:"㋿",abbr:"R"},{since:"1989-01-08",until:"2019-04-30",offset:1,name:"平成",narrow:"㍻",abbr:"H"},{since:"1926-12-25",until:"1989-01-07",offset:1,name:"昭和",narrow:"㍼",abbr:"S"},{since:"1912-07-30",until:"1926-12-24",offset:1,name:"大正",narrow:"㍽",abbr:"T"},{since:"1873-01-01",until:"1912-07-29",offset:6,name:"明治",narrow:"㍾",abbr:"M"},{since:"0001-01-01",until:"1873-12-31",offset:1,name:"西暦",narrow:"AD",abbr:"AD"},{since:"0000-12-31",until:-1/0,offset:1,name:"紀元前",narrow:"BC",abbr:"BC"}],eraYearOrdinalRegex:/(元|\d+)年/,eraYearOrdinalParse:function(e,a){return"元"===a[1]?1:parseInt(a[1]||e,10)},months:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日".split("_"),weekdaysShort:"日_月_火_水_木_金_土".split("_"),weekdaysMin:"日_月_火_水_木_金_土".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日 HH:mm",LLLL:"YYYY年M月D日 dddd HH:mm",l:"YYYY/MM/DD",ll:"YYYY年M月D日",lll:"YYYY年M月D日 HH:mm",llll:"YYYY年M月D日(ddd) HH:mm"},meridiemParse:/午前|午後/i,isPM:function(e){return"午後"===e},meridiem:function(e,a,t){return e<12?"午前":"午後"},calendar:{sameDay:"[今日] LT",nextDay:"[明日] LT",nextWeek:function(e){return e.week()!==this.week()?"[来週]dddd LT":"dddd LT"},lastDay:"[昨日] LT",lastWeek:function(e){return this.week()!==e.week()?"[先週]dddd LT":"dddd LT"},sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}日/,ordinal:function(e,a){switch(a){case"y":return 1===e?"元年":e+"年";case"d":case"D":case"DDD":return e+"日";default:return e}},relativeTime:{future:"%s後",past:"%s前",s:"数秒",ss:"%d秒",m:"1分",mm:"%d分",h:"1時間",hh:"%d時間",d:"1日",dd:"%d日",M:"1ヶ月",MM:"%dヶ月",y:"1年",yy:"%d年"}})},874383,(e,a,t)=>{e.e,e.r(166540).defineLocale("jv",{months:"Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des".split("_"),weekdays:"Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu".split("_"),weekdaysShort:"Min_Sen_Sel_Reb_Kem_Jem_Sep".split("_"),weekdaysMin:"Mg_Sn_Sl_Rb_Km_Jm_Sp".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/enjing|siyang|sonten|ndalu/,meridiemHour:function(e,a){return(12===e&&(e=0),"enjing"===a)?e:"siyang"===a?e>=11?e:e+12:"sonten"===a||"ndalu"===a?e+12:void 0},meridiem:function(e,a,t){return e<11?"enjing":e<15?"siyang":e<19?"sonten":"ndalu"},calendar:{sameDay:"[Dinten puniko pukul] LT",nextDay:"[Mbenjang pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kala wingi pukul] LT",lastWeek:"dddd [kepengker pukul] LT",sameElse:"L"},relativeTime:{future:"wonten ing %s",past:"%s ingkang kepengker",s:"sawetawis detik",ss:"%d detik",m:"setunggal menit",mm:"%d menit",h:"setunggal jam",hh:"%d jam",d:"sedinten",dd:"%d dinten",M:"sewulan",MM:"%d wulan",y:"setaun",yy:"%d taun"},week:{dow:1,doy:7}})},11842,(e,a,t)=>{e.e,e.r(166540).defineLocale("ka",{months:"იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი".split("_"),monthsShort:"იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ".split("_"),weekdays:{standalone:"კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი".split("_"),format:"კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს".split("_"),isFormat:/(წინა|შემდეგ)/},weekdaysShort:"კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ".split("_"),weekdaysMin:"კვ_ორ_სა_ოთ_ხუ_პა_შა".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[დღეს] LT[-ზე]",nextDay:"[ხვალ] LT[-ზე]",lastDay:"[გუშინ] LT[-ზე]",nextWeek:"[შემდეგ] dddd LT[-ზე]",lastWeek:"[წინა] dddd LT-ზე",sameElse:"L"},relativeTime:{future:function(e){return e.replace(/(წამ|წუთ|საათ|წელ|დღ|თვ)(ი|ე)/,function(e,a,t){return"ი"===t?a+"ში":a+t+"ში"})},past:function(e){return/(წამი|წუთი|საათი|დღე|თვე)/.test(e)?e.replace(/(ი|ე)$/,"ის წინ"):/წელი/.test(e)?e.replace(/წელი$/,"წლის წინ"):e},s:"რამდენიმე წამი",ss:"%d წამი",m:"წუთი",mm:"%d წუთი",h:"საათი",hh:"%d საათი",d:"დღე",dd:"%d დღე",M:"თვე",MM:"%d თვე",y:"წელი",yy:"%d წელი"},dayOfMonthOrdinalParse:/0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/,ordinal:function(e){return 0===e?e:1===e?e+"-ლი":e<20||e<=100&&e%20==0||e%100==0?"მე-"+e:e+"-ე"},week:{dow:1,doy:7}})},613970,(e,a,t)=>{e.e,function(e){"use strict";var a={0:"-ші",1:"-ші",2:"-ші",3:"-ші",4:"-ші",5:"-ші",6:"-шы",7:"-ші",8:"-ші",9:"-шы",10:"-шы",20:"-шы",30:"-шы",40:"-шы",50:"-ші",60:"-шы",70:"-ші",80:"-ші",90:"-шы",100:"-ші"};e.defineLocale("kk",{months:"қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан".split("_"),monthsShort:"қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел".split("_"),weekdays:"жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі".split("_"),weekdaysShort:"жек_дүй_сей_сәр_бей_жұм_сен".split("_"),weekdaysMin:"жк_дй_сй_ср_бй_жм_сн".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Бүгін сағат] LT",nextDay:"[Ертең сағат] LT",nextWeek:"dddd [сағат] LT",lastDay:"[Кеше сағат] LT",lastWeek:"[Өткен аптаның] dddd [сағат] LT",sameElse:"L"},relativeTime:{future:"%s ішінде",past:"%s бұрын",s:"бірнеше секунд",ss:"%d секунд",m:"бір минут",mm:"%d минут",h:"бір сағат",hh:"%d сағат",d:"бір күн",dd:"%d күн",M:"бір ай",MM:"%d ай",y:"бір жыл",yy:"%d жыл"},dayOfMonthOrdinalParse:/\d{1,2}-(ші|шы)/,ordinal:function(e){return e+(a[e]||a[e%10]||a[e>=100?100:null])},week:{dow:1,doy:7}})}(e.r(166540))},621412,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"១",2:"២",3:"៣",4:"៤",5:"៥",6:"៦",7:"៧",8:"៨",9:"៩",0:"០"},t={"១":"1","២":"2","៣":"3","៤":"4","៥":"5","៦":"6","៧":"7","៨":"8","៩":"9","០":"0"};e.defineLocale("km",{months:"មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"),monthsShort:"មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"),weekdays:"អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"),weekdaysShort:"អា_ច_អ_ព_ព្រ_សុ_ស".split("_"),weekdaysMin:"អា_ច_អ_ព_ព្រ_សុ_ស".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/ព្រឹក|ល្ងាច/,isPM:function(e){return"ល្ងាច"===e},meridiem:function(e,a,t){return e<12?"ព្រឹក":"ល្ងាច"},calendar:{sameDay:"[ថ្ងៃនេះ ម៉ោង] LT",nextDay:"[ស្អែក ម៉ោង] LT",nextWeek:"dddd [ម៉ោង] LT",lastDay:"[ម្សិលមិញ ម៉ោង] LT",lastWeek:"dddd [សប្តាហ៍មុន] [ម៉ោង] LT",sameElse:"L"},relativeTime:{future:"%sទៀត",past:"%sមុន",s:"ប៉ុន្មានវិនាទី",ss:"%d វិនាទី",m:"មួយនាទី",mm:"%d នាទី",h:"មួយម៉ោង",hh:"%d ម៉ោង",d:"មួយថ្ងៃ",dd:"%d ថ្ងៃ",M:"មួយខែ",MM:"%d ខែ",y:"មួយឆ្នាំ",yy:"%d ឆ្នាំ"},dayOfMonthOrdinalParse:/ទី\d{1,2}/,ordinal:"ទី%d",preparse:function(e){return e.replace(/[១២៣៤៥៦៧៨៩០]/g,function(e){return t[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]})},week:{dow:1,doy:4}})}(e.r(166540))},978630,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"೧",2:"೨",3:"೩",4:"೪",5:"೫",6:"೬",7:"೭",8:"೮",9:"೯",0:"೦"},t={"೧":"1","೨":"2","೩":"3","೪":"4","೫":"5","೬":"6","೭":"7","೮":"8","೯":"9","೦":"0"};e.defineLocale("kn",{months:"ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್".split("_"),monthsShort:"ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂ_ಅಕ್ಟೋ_ನವೆಂ_ಡಿಸೆಂ".split("_"),monthsParseExact:!0,weekdays:"ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ".split("_"),weekdaysShort:"ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ".split("_"),weekdaysMin:"ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[ಇಂದು] LT",nextDay:"[ನಾಳೆ] LT",nextWeek:"dddd, LT",lastDay:"[ನಿನ್ನೆ] LT",lastWeek:"[ಕೊನೆಯ] dddd, LT",sameElse:"L"},relativeTime:{future:"%s ನಂತರ",past:"%s ಹಿಂದೆ",s:"ಕೆಲವು ಕ್ಷಣಗಳು",ss:"%d ಸೆಕೆಂಡುಗಳು",m:"ಒಂದು ನಿಮಿಷ",mm:"%d ನಿಮಿಷ",h:"ಒಂದು ಗಂಟೆ",hh:"%d ಗಂಟೆ",d:"ಒಂದು ದಿನ",dd:"%d ದಿನ",M:"ಒಂದು ತಿಂಗಳು",MM:"%d ತಿಂಗಳು",y:"ಒಂದು ವರ್ಷ",yy:"%d ವರ್ಷ"},preparse:function(e){return e.replace(/[೧೨೩೪೫೬೭೮೯೦]/g,function(e){return t[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]})},meridiemParse:/ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/,meridiemHour:function(e,a){return(12===e&&(e=0),"ರಾತ್ರಿ"===a)?e<4?e:e+12:"ಬೆಳಿಗ್ಗೆ"===a?e:"ಮಧ್ಯಾಹ್ನ"===a?e>=10?e:e+12:"ಸಂಜೆ"===a?e+12:void 0},meridiem:function(e,a,t){return e<4?"ರಾತ್ರಿ":e<10?"ಬೆಳಿಗ್ಗೆ":e<17?"ಮಧ್ಯಾಹ್ನ":e<20?"ಸಂಜೆ":"ರಾತ್ರಿ"},dayOfMonthOrdinalParse:/\d{1,2}(ನೇ)/,ordinal:function(e){return e+"ನೇ"},week:{dow:0,doy:6}})}(e.r(166540))},73893,(e,a,t)=>{e.e,e.r(166540).defineLocale("ko",{months:"1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),monthsShort:"1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),weekdays:"일요일_월요일_화요일_수요일_목요일_금요일_토요일".split("_"),weekdaysShort:"일_월_화_수_목_금_토".split("_"),weekdaysMin:"일_월_화_수_목_금_토".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"YYYY.MM.DD.",LL:"YYYY년 MMMM D일",LLL:"YYYY년 MMMM D일 A h:mm",LLLL:"YYYY년 MMMM D일 dddd A h:mm",l:"YYYY.MM.DD.",ll:"YYYY년 MMMM D일",lll:"YYYY년 MMMM D일 A h:mm",llll:"YYYY년 MMMM D일 dddd A h:mm"},calendar:{sameDay:"오늘 LT",nextDay:"내일 LT",nextWeek:"dddd LT",lastDay:"어제 LT",lastWeek:"지난주 dddd LT",sameElse:"L"},relativeTime:{future:"%s 후",past:"%s 전",s:"몇 초",ss:"%d초",m:"1분",mm:"%d분",h:"한 시간",hh:"%d시간",d:"하루",dd:"%d일",M:"한 달",MM:"%d달",y:"일 년",yy:"%d년"},dayOfMonthOrdinalParse:/\d{1,2}(일|월|주)/,ordinal:function(e,a){switch(a){case"d":case"D":case"DDD":return e+"일";case"M":return e+"월";case"w":case"W":return e+"주";default:return e}},meridiemParse:/오전|오후/,isPM:function(e){return"오후"===e},meridiem:function(e,a,t){return e<12?"오전":"오후"}})},531990,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t,s){var n={s:["çend sanîye","çend sanîyeyan"],ss:[e+" sanîye",e+" sanîyeyan"],m:["deqîqeyek","deqîqeyekê"],mm:[e+" deqîqe",e+" deqîqeyan"],h:["saetek","saetekê"],hh:[e+" saet",e+" saetan"],d:["rojek","rojekê"],dd:[e+" roj",e+" rojan"],w:["hefteyek","hefteyekê"],ww:[e+" hefte",e+" hefteyan"],M:["mehek","mehekê"],MM:[e+" meh",e+" mehan"],y:["salek","salekê"],yy:[e+" sal",e+" salan"]};return a?n[t][0]:n[t][1]}e.defineLocale("ku-kmr",{months:"Rêbendan_Sibat_Adar_Nîsan_Gulan_Hezîran_Tîrmeh_Tebax_Îlon_Cotmeh_Mijdar_Berfanbar".split("_"),monthsShort:"Rêb_Sib_Ada_Nîs_Gul_Hez_Tîr_Teb_Îlo_Cot_Mij_Ber".split("_"),monthsParseExact:!0,weekdays:"Yekşem_Duşem_Sêşem_Çarşem_Pêncşem_În_Şemî".split("_"),weekdaysShort:"Yek_Du_Sê_Çar_Pên_În_Şem".split("_"),weekdaysMin:"Ye_Du_Sê_Ça_Pê_În_Şe".split("_"),meridiem:function(e,a,t){return e<12?t?"bn":"BN":t?"pn":"PN"},meridiemParse:/bn|BN|pn|PN/,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"Do MMMM[a] YYYY[an]",LLL:"Do MMMM[a] YYYY[an] HH:mm",LLLL:"dddd, Do MMMM[a] YYYY[an] HH:mm",ll:"Do MMM[.] YYYY[an]",lll:"Do MMM[.] YYYY[an] HH:mm",llll:"ddd[.], Do MMM[.] YYYY[an] HH:mm"},calendar:{sameDay:"[Îro di saet] LT [de]",nextDay:"[Sibê di saet] LT [de]",nextWeek:"dddd [di saet] LT [de]",lastDay:"[Duh di saet] LT [de]",lastWeek:"dddd[a borî di saet] LT [de]",sameElse:"L"},relativeTime:{future:"di %s de",past:"berî %s",s:a,ss:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,w:a,ww:a,M:a,MM:a,y:a,yy:a},dayOfMonthOrdinalParse:/\d{1,2}(?:yê|ê|\.)/,ordinal:function(e,a){var t,s,n,r=a.toLowerCase();return r.includes("w")||r.includes("m")?e+".":e+(s=(t=""+(t=e)).substring(t.length-1),12!=(n=t.length>1?t.substring(t.length-2):"")&&13!=n&&("2"==s||"3"==s||"50"==n||"70"==s||"80"==s)?"yê":"ê")},week:{dow:1,doy:4}})}(e.r(166540))},327383,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},t={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"},s=["کانونی دووەم","شوبات","ئازار","نیسان","ئایار","حوزەیران","تەمموز","ئاب","ئەیلوول","تشرینی یەكەم","تشرینی دووەم","كانونی یەکەم"];e.defineLocale("ku",{months:s,monthsShort:s,weekdays:"یه‌كشه‌ممه‌_دووشه‌ممه‌_سێشه‌ممه‌_چوارشه‌ممه‌_پێنجشه‌ممه‌_هه‌ینی_شه‌ممه‌".split("_"),weekdaysShort:"یه‌كشه‌م_دووشه‌م_سێشه‌م_چوارشه‌م_پێنجشه‌م_هه‌ینی_شه‌ممه‌".split("_"),weekdaysMin:"ی_د_س_چ_پ_ه_ش".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/ئێواره‌|به‌یانی/,isPM:function(e){return/ئێواره‌/.test(e)},meridiem:function(e,a,t){return e<12?"به‌یانی":"ئێواره‌"},calendar:{sameDay:"[ئه‌مرۆ كاتژمێر] LT",nextDay:"[به‌یانی كاتژمێر] LT",nextWeek:"dddd [كاتژمێر] LT",lastDay:"[دوێنێ كاتژمێر] LT",lastWeek:"dddd [كاتژمێر] LT",sameElse:"L"},relativeTime:{future:"له‌ %s",past:"%s",s:"چه‌ند چركه‌یه‌ك",ss:"چركه‌ %d",m:"یه‌ك خوله‌ك",mm:"%d خوله‌ك",h:"یه‌ك كاتژمێر",hh:"%d كاتژمێر",d:"یه‌ك ڕۆژ",dd:"%d ڕۆژ",M:"یه‌ك مانگ",MM:"%d مانگ",y:"یه‌ك ساڵ",yy:"%d ساڵ"},preparse:function(e){return e.replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(e){return t[e]}).replace(/،/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]}).replace(/,/g,"،")},week:{dow:6,doy:12}})}(e.r(166540))},913233,(e,a,t)=>{e.e,function(e){"use strict";var a={0:"-чү",1:"-чи",2:"-чи",3:"-чү",4:"-чү",5:"-чи",6:"-чы",7:"-чи",8:"-чи",9:"-чу",10:"-чу",20:"-чы",30:"-чу",40:"-чы",50:"-чү",60:"-чы",70:"-чи",80:"-чи",90:"-чу",100:"-чү"};e.defineLocale("ky",{months:"январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_"),monthsShort:"янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек".split("_"),weekdays:"Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби".split("_"),weekdaysShort:"Жек_Дүй_Шей_Шар_Бей_Жум_Ише".split("_"),weekdaysMin:"Жк_Дй_Шй_Шр_Бй_Жм_Иш".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Бүгүн саат] LT",nextDay:"[Эртең саат] LT",nextWeek:"dddd [саат] LT",lastDay:"[Кечээ саат] LT",lastWeek:"[Өткөн аптанын] dddd [күнү] [саат] LT",sameElse:"L"},relativeTime:{future:"%s ичинде",past:"%s мурун",s:"бирнече секунд",ss:"%d секунд",m:"бир мүнөт",mm:"%d мүнөт",h:"бир саат",hh:"%d саат",d:"бир күн",dd:"%d күн",M:"бир ай",MM:"%d ай",y:"бир жыл",yy:"%d жыл"},dayOfMonthOrdinalParse:/\d{1,2}-(чи|чы|чү|чу)/,ordinal:function(e){return e+(a[e]||a[e%10]||a[e>=100?100:null])},week:{dow:1,doy:7}})}(e.r(166540))},535403,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t,s){var n={m:["eng Minutt","enger Minutt"],h:["eng Stonn","enger Stonn"],d:["een Dag","engem Dag"],M:["ee Mount","engem Mount"],y:["ee Joer","engem Joer"]};return a?n[t][0]:n[t][1]}function t(e){if(isNaN(e=parseInt(e,10)))return!1;if(e<0)return!0;if(e<10)return!!(4<=e)&&!!(e<=7);if(e<100){var a=e%10,s=e/10;return 0===a?t(s):t(a)}if(!(e<1e4))return t(e/=1e3);for(;e>=10;)e/=10;return t(e)}e.defineLocale("lb",{months:"Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg".split("_"),weekdaysShort:"So._Mé._Dë._Më._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mé_Dë_Më_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm [Auer]",LTS:"H:mm:ss [Auer]",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm [Auer]",LLLL:"dddd, D. MMMM YYYY H:mm [Auer]"},calendar:{sameDay:"[Haut um] LT",sameElse:"L",nextDay:"[Muer um] LT",nextWeek:"dddd [um] LT",lastDay:"[Gëschter um] LT",lastWeek:function(){switch(this.day()){case 2:case 4:return"[Leschten] dddd [um] LT";default:return"[Leschte] dddd [um] LT"}}},relativeTime:{future:function(e){return t(e.substr(0,e.indexOf(" ")))?"a "+e:"an "+e},past:function(e){return t(e.substr(0,e.indexOf(" ")))?"viru "+e:"virun "+e},s:"e puer Sekonnen",ss:"%d Sekonnen",m:a,mm:"%d Minutten",h:a,hh:"%d Stonnen",d:a,dd:"%d Deeg",M:a,MM:"%d Méint",y:a,yy:"%d Joer"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e.r(166540))},17373,(e,a,t)=>{e.e,e.r(166540).defineLocale("lo",{months:"ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ".split("_"),monthsShort:"ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ".split("_"),weekdays:"ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ".split("_"),weekdaysShort:"ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ".split("_"),weekdaysMin:"ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"ວັນdddd D MMMM YYYY HH:mm"},meridiemParse:/ຕອນເຊົ້າ|ຕອນແລງ/,isPM:function(e){return"ຕອນແລງ"===e},meridiem:function(e,a,t){return e<12?"ຕອນເຊົ້າ":"ຕອນແລງ"},calendar:{sameDay:"[ມື້ນີ້ເວລາ] LT",nextDay:"[ມື້ອື່ນເວລາ] LT",nextWeek:"[ວັນ]dddd[ໜ້າເວລາ] LT",lastDay:"[ມື້ວານນີ້ເວລາ] LT",lastWeek:"[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT",sameElse:"L"},relativeTime:{future:"ອີກ %s",past:"%sຜ່ານມາ",s:"ບໍ່ເທົ່າໃດວິນາທີ",ss:"%d ວິນາທີ",m:"1 ນາທີ",mm:"%d ນາທີ",h:"1 ຊົ່ວໂມງ",hh:"%d ຊົ່ວໂມງ",d:"1 ມື້",dd:"%d ມື້",M:"1 ເດືອນ",MM:"%d ເດືອນ",y:"1 ປີ",yy:"%d ປີ"},dayOfMonthOrdinalParse:/(ທີ່)\d{1,2}/,ordinal:function(e){return"ທີ່"+e}})},409583,(e,a,t)=>{e.e,function(e){"use strict";var a={ss:"sekundė_sekundžių_sekundes",m:"minutė_minutės_minutę",mm:"minutės_minučių_minutes",h:"valanda_valandos_valandą",hh:"valandos_valandų_valandas",d:"diena_dienos_dieną",dd:"dienos_dienų_dienas",M:"mėnuo_mėnesio_mėnesį",MM:"mėnesiai_mėnesių_mėnesius",y:"metai_metų_metus",yy:"metai_metų_metus"};function t(e,a,t,s){return a?n(t)[0]:s?n(t)[1]:n(t)[2]}function s(e){return e%10==0||e>10&&e<20}function n(e){return a[e].split("_")}function r(e,a,r,d){var i=e+" ";return 1===e?i+t(e,a,r[0],d):a?i+(s(e)?n(r)[1]:n(r)[0]):d?i+n(r)[1]:i+(s(e)?n(r)[1]:n(r)[2])}e.defineLocale("lt",{months:{format:"sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio".split("_"),standalone:"sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis".split("_"),isFormat:/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/},monthsShort:"sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd".split("_"),weekdays:{format:"sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį".split("_"),standalone:"sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis".split("_"),isFormat:/dddd HH:mm/},weekdaysShort:"Sek_Pir_Ant_Tre_Ket_Pen_Šeš".split("_"),weekdaysMin:"S_P_A_T_K_Pn_Š".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY [m.] MMMM D [d.]",LLL:"YYYY [m.] MMMM D [d.], HH:mm [val.]",LLLL:"YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]",l:"YYYY-MM-DD",ll:"YYYY [m.] MMMM D [d.]",lll:"YYYY [m.] MMMM D [d.], HH:mm [val.]",llll:"YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]"},calendar:{sameDay:"[Šiandien] LT",nextDay:"[Rytoj] LT",nextWeek:"dddd LT",lastDay:"[Vakar] LT",lastWeek:"[Praėjusį] dddd LT",sameElse:"L"},relativeTime:{future:"po %s",past:"prieš %s",s:function(e,a,t,s){return a?"kelios sekundės":s?"kelių sekundžių":"kelias sekundes"},ss:r,m:t,mm:r,h:t,hh:r,d:t,dd:r,M:t,MM:r,y:t,yy:r},dayOfMonthOrdinalParse:/\d{1,2}-oji/,ordinal:function(e){return e+"-oji"},week:{dow:1,doy:4}})}(e.r(166540))},407912,(e,a,t)=>{e.e,function(e){"use strict";var a={ss:"sekundes_sekundēm_sekunde_sekundes".split("_"),m:"minūtes_minūtēm_minūte_minūtes".split("_"),mm:"minūtes_minūtēm_minūte_minūtes".split("_"),h:"stundas_stundām_stunda_stundas".split("_"),hh:"stundas_stundām_stunda_stundas".split("_"),d:"dienas_dienām_diena_dienas".split("_"),dd:"dienas_dienām_diena_dienas".split("_"),M:"mēneša_mēnešiem_mēnesis_mēneši".split("_"),MM:"mēneša_mēnešiem_mēnesis_mēneši".split("_"),y:"gada_gadiem_gads_gadi".split("_"),yy:"gada_gadiem_gads_gadi".split("_")};function t(e,a,t){return t?a%10==1&&a%100!=11?e[2]:e[3]:a%10==1&&a%100!=11?e[0]:e[1]}function s(e,s,n){return e+" "+t(a[n],e,s)}function n(e,s,n){return t(a[n],e,s)}e.defineLocale("lv",{months:"janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris".split("_"),monthsShort:"jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec".split("_"),weekdays:"svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena".split("_"),weekdaysShort:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysMin:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY.",LL:"YYYY. [gada] D. MMMM",LLL:"YYYY. [gada] D. MMMM, HH:mm",LLLL:"YYYY. [gada] D. MMMM, dddd, HH:mm"},calendar:{sameDay:"[Šodien pulksten] LT",nextDay:"[Rīt pulksten] LT",nextWeek:"dddd [pulksten] LT",lastDay:"[Vakar pulksten] LT",lastWeek:"[Pagājušā] dddd [pulksten] LT",sameElse:"L"},relativeTime:{future:"pēc %s",past:"pirms %s",s:function(e,a){return a?"dažas sekundes":"dažām sekundēm"},ss:s,m:n,mm:s,h:n,hh:s,d:n,dd:s,M:n,MM:s,y:n,yy:s},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e.r(166540))},545267,(e,a,t)=>{e.e,function(e){"use strict";var a={words:{ss:["sekund","sekunda","sekundi"],m:["jedan minut","jednog minuta"],mm:["minut","minuta","minuta"],h:["jedan sat","jednog sata"],hh:["sat","sata","sati"],dd:["dan","dana","dana"],MM:["mjesec","mjeseca","mjeseci"],yy:["godina","godine","godina"]},correctGrammaticalCase:function(e,a){return 1===e?a[0]:e>=2&&e<=4?a[1]:a[2]},translate:function(e,t,s){var n=a.words[s];return 1===s.length?t?n[0]:n[1]:e+" "+a.correctGrammaticalCase(e,n)}};e.defineLocale("me",{months:"januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sjutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[juče u] LT",lastWeek:function(){return["[prošle] [nedjelje] [u] LT","[prošlog] [ponedjeljka] [u] LT","[prošlog] [utorka] [u] LT","[prošle] [srijede] [u] LT","[prošlog] [četvrtka] [u] LT","[prošlog] [petka] [u] LT","[prošle] [subote] [u] LT"][this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"nekoliko sekundi",ss:a.translate,m:a.translate,mm:a.translate,h:a.translate,hh:a.translate,d:"dan",dd:a.translate,M:"mjesec",MM:a.translate,y:"godinu",yy:a.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(e.r(166540))},961705,(e,a,t)=>{e.e,e.r(166540).defineLocale("mi",{months:"Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea".split("_"),monthsShort:"Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki".split("_"),monthsRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsStrictRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsShortRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsShortStrictRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i,weekdays:"Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei".split("_"),weekdaysShort:"Ta_Ma_Tū_We_Tāi_Pa_Hā".split("_"),weekdaysMin:"Ta_Ma_Tū_We_Tāi_Pa_Hā".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [i] HH:mm",LLLL:"dddd, D MMMM YYYY [i] HH:mm"},calendar:{sameDay:"[i teie mahana, i] LT",nextDay:"[apopo i] LT",nextWeek:"dddd [i] LT",lastDay:"[inanahi i] LT",lastWeek:"dddd [whakamutunga i] LT",sameElse:"L"},relativeTime:{future:"i roto i %s",past:"%s i mua",s:"te hēkona ruarua",ss:"%d hēkona",m:"he meneti",mm:"%d meneti",h:"te haora",hh:"%d haora",d:"he ra",dd:"%d ra",M:"he marama",MM:"%d marama",y:"he tau",yy:"%d tau"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})},354402,(e,a,t)=>{e.e,e.r(166540).defineLocale("mk",{months:"јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември".split("_"),monthsShort:"јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек".split("_"),weekdays:"недела_понеделник_вторник_среда_четврток_петок_сабота".split("_"),weekdaysShort:"нед_пон_вто_сре_чет_пет_саб".split("_"),weekdaysMin:"нe_пo_вт_ср_че_пе_сa".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[Денес во] LT",nextDay:"[Утре во] LT",nextWeek:"[Во] dddd [во] LT",lastDay:"[Вчера во] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[Изминатата] dddd [во] LT";case 1:case 2:case 4:case 5:return"[Изминатиот] dddd [во] LT"}},sameElse:"L"},relativeTime:{future:"за %s",past:"пред %s",s:"неколку секунди",ss:"%d секунди",m:"една минута",mm:"%d минути",h:"еден час",hh:"%d часа",d:"еден ден",dd:"%d дена",M:"еден месец",MM:"%d месеци",y:"една година",yy:"%d години"},dayOfMonthOrdinalParse:/\d{1,2}-(ев|ен|ти|ви|ри|ми)/,ordinal:function(e){var a=e%10,t=e%100;if(0===e)return e+"-ев";if(0===t)return e+"-ен";if(t>10&&t<20)return e+"-ти";if(1===a)return e+"-ви";if(2===a)return e+"-ри";else if(7===a||8===a)return e+"-ми";else return e+"-ти"},week:{dow:1,doy:7}})},624201,(e,a,t)=>{e.e,e.r(166540).defineLocale("ml",{months:"ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ".split("_"),monthsShort:"ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.".split("_"),monthsParseExact:!0,weekdays:"ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച".split("_"),weekdaysShort:"ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി".split("_"),weekdaysMin:"ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ".split("_"),longDateFormat:{LT:"A h:mm -നു",LTS:"A h:mm:ss -നു",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm -നു",LLLL:"dddd, D MMMM YYYY, A h:mm -നു"},calendar:{sameDay:"[ഇന്ന്] LT",nextDay:"[നാളെ] LT",nextWeek:"dddd, LT",lastDay:"[ഇന്നലെ] LT",lastWeek:"[കഴിഞ്ഞ] dddd, LT",sameElse:"L"},relativeTime:{future:"%s കഴിഞ്ഞ്",past:"%s മുൻപ്",s:"അൽപ നിമിഷങ്ങൾ",ss:"%d സെക്കൻഡ്",m:"ഒരു മിനിറ്റ്",mm:"%d മിനിറ്റ്",h:"ഒരു മണിക്കൂർ",hh:"%d മണിക്കൂർ",d:"ഒരു ദിവസം",dd:"%d ദിവസം",M:"ഒരു മാസം",MM:"%d മാസം",y:"ഒരു വർഷം",yy:"%d വർഷം"},meridiemParse:/രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,meridiemHour:function(e,a){return(12===e&&(e=0),"രാത്രി"===a&&e>=4||"ഉച്ച കഴിഞ്ഞ്"===a||"വൈകുന്നേരം"===a)?e+12:e},meridiem:function(e,a,t){return e<4?"രാത്രി":e<12?"രാവിലെ":e<17?"ഉച്ച കഴിഞ്ഞ്":e<20?"വൈകുന്നേരം":"രാത്രി"}})},969668,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t,s){switch(t){case"s":return a?"хэдхэн секунд":"хэдхэн секундын";case"ss":return e+(a?" секунд":" секундын");case"m":case"mm":return e+(a?" минут":" минутын");case"h":case"hh":return e+(a?" цаг":" цагийн");case"d":case"dd":return e+(a?" өдөр":" өдрийн");case"M":case"MM":return e+(a?" сар":" сарын");case"y":case"yy":return e+(a?" жил":" жилийн");default:return e}}e.defineLocale("mn",{months:"Нэгдүгээр сар_Хоёрдугаар сар_Гуравдугаар сар_Дөрөвдүгээр сар_Тавдугаар сар_Зургадугаар сар_Долдугаар сар_Наймдугаар сар_Есдүгээр сар_Аравдугаар сар_Арван нэгдүгээр сар_Арван хоёрдугаар сар".split("_"),monthsShort:"1 сар_2 сар_3 сар_4 сар_5 сар_6 сар_7 сар_8 сар_9 сар_10 сар_11 сар_12 сар".split("_"),monthsParseExact:!0,weekdays:"Ням_Даваа_Мягмар_Лхагва_Пүрэв_Баасан_Бямба".split("_"),weekdaysShort:"Ням_Дав_Мяг_Лха_Пүр_Баа_Бям".split("_"),weekdaysMin:"Ня_Да_Мя_Лх_Пү_Ба_Бя".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY оны MMMMын D",LLL:"YYYY оны MMMMын D HH:mm",LLLL:"dddd, YYYY оны MMMMын D HH:mm"},meridiemParse:/ҮӨ|ҮХ/i,isPM:function(e){return"ҮХ"===e},meridiem:function(e,a,t){return e<12?"ҮӨ":"ҮХ"},calendar:{sameDay:"[Өнөөдөр] LT",nextDay:"[Маргааш] LT",nextWeek:"[Ирэх] dddd LT",lastDay:"[Өчигдөр] LT",lastWeek:"[Өнгөрсөн] dddd LT",sameElse:"L"},relativeTime:{future:"%s дараа",past:"%s өмнө",s:a,ss:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},dayOfMonthOrdinalParse:/\d{1,2} өдөр/,ordinal:function(e,a){switch(a){case"d":case"D":case"DDD":return e+" өдөр";default:return e}}})}(e.r(166540))},417366,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"१",2:"२",3:"३",4:"४",5:"५",6:"६",7:"७",8:"८",9:"९",0:"०"},t={"१":"1","२":"2","३":"3","४":"4","५":"5","६":"6","७":"7","८":"8","९":"9","०":"0"};function s(e,a,t,s){var n="";if(a)switch(t){case"s":n="काही सेकंद";break;case"ss":n="%d सेकंद";break;case"m":n="एक मिनिट";break;case"mm":n="%d मिनिटे";break;case"h":n="एक तास";break;case"hh":n="%d तास";break;case"d":n="एक दिवस";break;case"dd":n="%d दिवस";break;case"M":n="एक महिना";break;case"MM":n="%d महिने";break;case"y":n="एक वर्ष";break;case"yy":n="%d वर्षे"}else switch(t){case"s":n="काही सेकंदां";break;case"ss":n="%d सेकंदां";break;case"m":n="एका मिनिटा";break;case"mm":n="%d मिनिटां";break;case"h":n="एका तासा";break;case"hh":n="%d तासां";break;case"d":n="एका दिवसा";break;case"dd":n="%d दिवसां";break;case"M":n="एका महिन्या";break;case"MM":n="%d महिन्यां";break;case"y":n="एका वर्षा";break;case"yy":n="%d वर्षां"}return n.replace(/%d/i,e)}e.defineLocale("mr",{months:"जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर".split("_"),monthsShort:"जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.".split("_"),monthsParseExact:!0,weekdays:"रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार".split("_"),weekdaysShort:"रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि".split("_"),weekdaysMin:"र_सो_मं_बु_गु_शु_श".split("_"),longDateFormat:{LT:"A h:mm वाजता",LTS:"A h:mm:ss वाजता",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm वाजता",LLLL:"dddd, D MMMM YYYY, A h:mm वाजता"},calendar:{sameDay:"[आज] LT",nextDay:"[उद्या] LT",nextWeek:"dddd, LT",lastDay:"[काल] LT",lastWeek:"[मागील] dddd, LT",sameElse:"L"},relativeTime:{future:"%sमध्ये",past:"%sपूर्वी",s:s,ss:s,m:s,mm:s,h:s,hh:s,d:s,dd:s,M:s,MM:s,y:s,yy:s},preparse:function(e){return e.replace(/[१२३४५६७८९०]/g,function(e){return t[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]})},meridiemParse:/पहाटे|सकाळी|दुपारी|सायंकाळी|रात्री/,meridiemHour:function(e,a){return(12===e&&(e=0),"पहाटे"===a||"सकाळी"===a)?e:"दुपारी"===a||"सायंकाळी"===a||"रात्री"===a?e>=12?e:e+12:void 0},meridiem:function(e,a,t){return e>=0&&e<6?"पहाटे":e<12?"सकाळी":e<17?"दुपारी":e<20?"सायंकाळी":"रात्री"},week:{dow:0,doy:6}})}(e.r(166540))},538640,(e,a,t)=>{e.e,e.r(166540).defineLocale("ms-my",{months:"Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),weekdays:"Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),weekdaysShort:"Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),weekdaysMin:"Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|tengahari|petang|malam/,meridiemHour:function(e,a){return(12===e&&(e=0),"pagi"===a)?e:"tengahari"===a?e>=11?e:e+12:"petang"===a||"malam"===a?e+12:void 0},meridiem:function(e,a,t){return e<11?"pagi":e<15?"tengahari":e<19?"petang":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Esok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kelmarin pukul] LT",lastWeek:"dddd [lepas pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lepas",s:"beberapa saat",ss:"%d saat",m:"seminit",mm:"%d minit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}})},367856,(e,a,t)=>{e.e,e.r(166540).defineLocale("ms",{months:"Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),weekdays:"Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),weekdaysShort:"Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),weekdaysMin:"Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|tengahari|petang|malam/,meridiemHour:function(e,a){return(12===e&&(e=0),"pagi"===a)?e:"tengahari"===a?e>=11?e:e+12:"petang"===a||"malam"===a?e+12:void 0},meridiem:function(e,a,t){return e<11?"pagi":e<15?"tengahari":e<19?"petang":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Esok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kelmarin pukul] LT",lastWeek:"dddd [lepas pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lepas",s:"beberapa saat",ss:"%d saat",m:"seminit",mm:"%d minit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}})},157692,(e,a,t)=>{e.e,e.r(166540).defineLocale("mt",{months:"Jannar_Frar_Marzu_April_Mejju_Ġunju_Lulju_Awwissu_Settembru_Ottubru_Novembru_Diċembru".split("_"),monthsShort:"Jan_Fra_Mar_Apr_Mej_Ġun_Lul_Aww_Set_Ott_Nov_Diċ".split("_"),weekdays:"Il-Ħadd_It-Tnejn_It-Tlieta_L-Erbgħa_Il-Ħamis_Il-Ġimgħa_Is-Sibt".split("_"),weekdaysShort:"Ħad_Tne_Tli_Erb_Ħam_Ġim_Sib".split("_"),weekdaysMin:"Ħa_Tn_Tl_Er_Ħa_Ġi_Si".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Illum fil-]LT",nextDay:"[Għada fil-]LT",nextWeek:"dddd [fil-]LT",lastDay:"[Il-bieraħ fil-]LT",lastWeek:"dddd [li għadda] [fil-]LT",sameElse:"L"},relativeTime:{future:"f’ %s",past:"%s ilu",s:"ftit sekondi",ss:"%d sekondi",m:"minuta",mm:"%d minuti",h:"siegħa",hh:"%d siegħat",d:"ġurnata",dd:"%d ġranet",M:"xahar",MM:"%d xhur",y:"sena",yy:"%d sni"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})},222310,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"၁",2:"၂",3:"၃",4:"၄",5:"၅",6:"၆",7:"၇",8:"၈",9:"၉",0:"၀"},t={"၁":"1","၂":"2","၃":"3","၄":"4","၅":"5","၆":"6","၇":"7","၈":"8","၉":"9","၀":"0"};e.defineLocale("my",{months:"ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ".split("_"),monthsShort:"ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ".split("_"),weekdays:"တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ".split("_"),weekdaysShort:"နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ".split("_"),weekdaysMin:"နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[ယနေ.] LT [မှာ]",nextDay:"[မနက်ဖြန်] LT [မှာ]",nextWeek:"dddd LT [မှာ]",lastDay:"[မနေ.က] LT [မှာ]",lastWeek:"[ပြီးခဲ့သော] dddd LT [မှာ]",sameElse:"L"},relativeTime:{future:"လာမည့် %s မှာ",past:"လွန်ခဲ့သော %s က",s:"စက္ကန်.အနည်းငယ်",ss:"%d စက္ကန့်",m:"တစ်မိနစ်",mm:"%d မိနစ်",h:"တစ်နာရီ",hh:"%d နာရီ",d:"တစ်ရက်",dd:"%d ရက်",M:"တစ်လ",MM:"%d လ",y:"တစ်နှစ်",yy:"%d နှစ်"},preparse:function(e){return e.replace(/[၁၂၃၄၅၆၇၈၉၀]/g,function(e){return t[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]})},week:{dow:1,doy:4}})}(e.r(166540))},441867,(e,a,t)=>{e.e,e.r(166540).defineLocale("nb",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan._feb._mars_apr._mai_juni_juli_aug._sep._okt._nov._des.".split("_"),monthsParseExact:!0,weekdays:"søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),weekdaysShort:"sø._ma._ti._on._to._fr._lø.".split("_"),weekdaysMin:"sø_ma_ti_on_to_fr_lø".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] HH:mm",LLLL:"dddd D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[i dag kl.] LT",nextDay:"[i morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[i går kl.] LT",lastWeek:"[forrige] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"noen sekunder",ss:"%d sekunder",m:"ett minutt",mm:"%d minutter",h:"én time",hh:"%d timer",d:"én dag",dd:"%d dager",w:"én uke",ww:"%d uker",M:"én måned",MM:"%d måneder",y:"ett år",yy:"%d år"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})},899103,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"१",2:"२",3:"३",4:"४",5:"५",6:"६",7:"७",8:"८",9:"९",0:"०"},t={"१":"1","२":"2","३":"3","४":"4","५":"5","६":"6","७":"7","८":"8","९":"9","०":"0"};e.defineLocale("ne",{months:"जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर".split("_"),monthsShort:"जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.".split("_"),monthsParseExact:!0,weekdays:"आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार".split("_"),weekdaysShort:"आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.".split("_"),weekdaysMin:"आ._सो._मं._बु._बि._शु._श.".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"Aको h:mm बजे",LTS:"Aको h:mm:ss बजे",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, Aको h:mm बजे",LLLL:"dddd, D MMMM YYYY, Aको h:mm बजे"},preparse:function(e){return e.replace(/[१२३४५६७८९०]/g,function(e){return t[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]})},meridiemParse:/राति|बिहान|दिउँसो|साँझ/,meridiemHour:function(e,a){return(12===e&&(e=0),"राति"===a)?e<4?e:e+12:"बिहान"===a?e:"दिउँसो"===a?e>=10?e:e+12:"साँझ"===a?e+12:void 0},meridiem:function(e,a,t){return e<3?"राति":e<12?"बिहान":e<16?"दिउँसो":e<20?"साँझ":"राति"},calendar:{sameDay:"[आज] LT",nextDay:"[भोलि] LT",nextWeek:"[आउँदो] dddd[,] LT",lastDay:"[हिजो] LT",lastWeek:"[गएको] dddd[,] LT",sameElse:"L"},relativeTime:{future:"%sमा",past:"%s अगाडि",s:"केही क्षण",ss:"%d सेकेण्ड",m:"एक मिनेट",mm:"%d मिनेट",h:"एक घण्टा",hh:"%d घण्टा",d:"एक दिन",dd:"%d दिन",M:"एक महिना",MM:"%d महिना",y:"एक बर्ष",yy:"%d बर्ष"},week:{dow:0,doy:6}})}(e.r(166540))},775136,(e,a,t)=>{e.e,function(e){"use strict";var a="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),t="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),s=[/^jan/i,/^feb/i,/^(maart|mrt\.?)$/i,/^apr/i,/^mei$/i,/^jun[i.]?$/i,/^jul[i.]?$/i,/^aug/i,/^sep/i,/^okt/i,/^nov/i,/^dec/i],n=/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;e.defineLocale("nl-be",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(e,s){return e?/-MMM-/.test(s)?t[e.month()]:a[e.month()]:a},monthsRegex:n,monthsShortRegex:n,monthsStrictRegex:/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i,monthsShortStrictRegex:/^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,monthsParse:s,longMonthsParse:s,shortMonthsParse:s,weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"zo_ma_di_wo_do_vr_za".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",ss:"%d seconden",m:"één minuut",mm:"%d minuten",h:"één uur",hh:"%d uur",d:"één dag",dd:"%d dagen",M:"één maand",MM:"%d maanden",y:"één jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(e){return e+(1===e||8===e||e>=20?"ste":"de")},week:{dow:1,doy:4}})}(e.r(166540))},618264,(e,a,t)=>{e.e,function(e){"use strict";var a="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),t="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),s=[/^jan/i,/^feb/i,/^(maart|mrt\.?)$/i,/^apr/i,/^mei$/i,/^jun[i.]?$/i,/^jul[i.]?$/i,/^aug/i,/^sep/i,/^okt/i,/^nov/i,/^dec/i],n=/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;e.defineLocale("nl",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(e,s){return e?/-MMM-/.test(s)?t[e.month()]:a[e.month()]:a},monthsRegex:n,monthsShortRegex:n,monthsStrictRegex:/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i,monthsShortStrictRegex:/^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,monthsParse:s,longMonthsParse:s,shortMonthsParse:s,weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"zo_ma_di_wo_do_vr_za".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",ss:"%d seconden",m:"één minuut",mm:"%d minuten",h:"één uur",hh:"%d uur",d:"één dag",dd:"%d dagen",w:"één week",ww:"%d weken",M:"één maand",MM:"%d maanden",y:"één jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(e){return e+(1===e||8===e||e>=20?"ste":"de")},week:{dow:1,doy:4}})}(e.r(166540))},876976,(e,a,t)=>{e.e,e.r(166540).defineLocale("nn",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan._feb._mars_apr._mai_juni_juli_aug._sep._okt._nov._des.".split("_"),monthsParseExact:!0,weekdays:"sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag".split("_"),weekdaysShort:"su._må._ty._on._to._fr._lau.".split("_"),weekdaysMin:"su_må_ty_on_to_fr_la".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] H:mm",LLLL:"dddd D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[I dag klokka] LT",nextDay:"[I morgon klokka] LT",nextWeek:"dddd [klokka] LT",lastDay:"[I går klokka] LT",lastWeek:"[Føregåande] dddd [klokka] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s sidan",s:"nokre sekund",ss:"%d sekund",m:"eit minutt",mm:"%d minutt",h:"ein time",hh:"%d timar",d:"ein dag",dd:"%d dagar",w:"ei veke",ww:"%d veker",M:"ein månad",MM:"%d månader",y:"eit år",yy:"%d år"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})},225313,(e,a,t)=>{e.e,e.r(166540).defineLocale("oc-lnc",{months:{standalone:"genièr_febrièr_març_abril_mai_junh_julhet_agost_setembre_octòbre_novembre_decembre".split("_"),format:"de genièr_de febrièr_de març_d'abril_de mai_de junh_de julhet_d'agost_de setembre_d'octòbre_de novembre_de decembre".split("_"),isFormat:/D[oD]?(\s)+MMMM/},monthsShort:"gen._febr._març_abr._mai_junh_julh._ago._set._oct._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"dimenge_diluns_dimars_dimècres_dijòus_divendres_dissabte".split("_"),weekdaysShort:"dg._dl._dm._dc._dj._dv._ds.".split("_"),weekdaysMin:"dg_dl_dm_dc_dj_dv_ds".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [de] YYYY",ll:"D MMM YYYY",LLL:"D MMMM [de] YYYY [a] H:mm",lll:"D MMM YYYY, H:mm",LLLL:"dddd D MMMM [de] YYYY [a] H:mm",llll:"ddd D MMM YYYY, H:mm"},calendar:{sameDay:"[uèi a] LT",nextDay:"[deman a] LT",nextWeek:"dddd [a] LT",lastDay:"[ièr a] LT",lastWeek:"dddd [passat a] LT",sameElse:"L"},relativeTime:{future:"d'aquí %s",past:"fa %s",s:"unas segondas",ss:"%d segondas",m:"una minuta",mm:"%d minutas",h:"una ora",hh:"%d oras",d:"un jorn",dd:"%d jorns",M:"un mes",MM:"%d meses",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(r|n|t|è|a)/,ordinal:function(e,a){var t=1===e?"r":2===e?"n":3===e?"r":4===e?"t":"è";return("w"===a||"W"===a)&&(t="a"),e+t},week:{dow:1,doy:4}})},368431,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"੧",2:"੨",3:"੩",4:"੪",5:"੫",6:"੬",7:"੭",8:"੮",9:"੯",0:"੦"},t={"੧":"1","੨":"2","੩":"3","੪":"4","੫":"5","੬":"6","੭":"7","੮":"8","੯":"9","੦":"0"};e.defineLocale("pa-in",{months:"ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ".split("_"),monthsShort:"ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ".split("_"),weekdays:"ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ".split("_"),weekdaysShort:"ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ".split("_"),weekdaysMin:"ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ".split("_"),longDateFormat:{LT:"A h:mm ਵਜੇ",LTS:"A h:mm:ss ਵਜੇ",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm ਵਜੇ",LLLL:"dddd, D MMMM YYYY, A h:mm ਵਜੇ"},calendar:{sameDay:"[ਅਜ] LT",nextDay:"[ਕਲ] LT",nextWeek:"[ਅਗਲਾ] dddd, LT",lastDay:"[ਕਲ] LT",lastWeek:"[ਪਿਛਲੇ] dddd, LT",sameElse:"L"},relativeTime:{future:"%s ਵਿੱਚ",past:"%s ਪਿਛਲੇ",s:"ਕੁਝ ਸਕਿੰਟ",ss:"%d ਸਕਿੰਟ",m:"ਇਕ ਮਿੰਟ",mm:"%d ਮਿੰਟ",h:"ਇੱਕ ਘੰਟਾ",hh:"%d ਘੰਟੇ",d:"ਇੱਕ ਦਿਨ",dd:"%d ਦਿਨ",M:"ਇੱਕ ਮਹੀਨਾ",MM:"%d ਮਹੀਨੇ",y:"ਇੱਕ ਸਾਲ",yy:"%d ਸਾਲ"},preparse:function(e){return e.replace(/[੧੨੩੪੫੬੭੮੯੦]/g,function(e){return t[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]})},meridiemParse:/ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/,meridiemHour:function(e,a){return(12===e&&(e=0),"ਰਾਤ"===a)?e<4?e:e+12:"ਸਵੇਰ"===a?e:"ਦੁਪਹਿਰ"===a?e>=10?e:e+12:"ਸ਼ਾਮ"===a?e+12:void 0},meridiem:function(e,a,t){return e<4?"ਰਾਤ":e<10?"ਸਵੇਰ":e<17?"ਦੁਪਹਿਰ":e<20?"ਸ਼ਾਮ":"ਰਾਤ"},week:{dow:0,doy:6}})}(e.r(166540))},657968,(e,a,t)=>{e.e,function(e){"use strict";var a="styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień".split("_"),t="stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia".split("_"),s=[/^sty/i,/^lut/i,/^mar/i,/^kwi/i,/^maj/i,/^cze/i,/^lip/i,/^sie/i,/^wrz/i,/^paź/i,/^lis/i,/^gru/i];function n(e){return e%10<5&&e%10>1&&~~(e/10)%10!=1}function r(e,a,t){var s=e+" ";switch(t){case"ss":return s+(n(e)?"sekundy":"sekund");case"m":return a?"minuta":"minutę";case"mm":return s+(n(e)?"minuty":"minut");case"h":return a?"godzina":"godzinę";case"hh":return s+(n(e)?"godziny":"godzin");case"ww":return s+(n(e)?"tygodnie":"tygodni");case"MM":return s+(n(e)?"miesiące":"miesięcy");case"yy":return s+(n(e)?"lata":"lat")}}e.defineLocale("pl",{months:function(e,s){return e?/D MMMM/.test(s)?t[e.month()]:a[e.month()]:a},monthsShort:"sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru".split("_"),monthsParse:s,longMonthsParse:s,shortMonthsParse:s,weekdays:"niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota".split("_"),weekdaysShort:"ndz_pon_wt_śr_czw_pt_sob".split("_"),weekdaysMin:"Nd_Pn_Wt_Śr_Cz_Pt_So".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Dziś o] LT",nextDay:"[Jutro o] LT",nextWeek:function(){switch(this.day()){case 0:return"[W niedzielę o] LT";case 2:return"[We wtorek o] LT";case 3:return"[W środę o] LT";case 6:return"[W sobotę o] LT";default:return"[W] dddd [o] LT"}},lastDay:"[Wczoraj o] LT",lastWeek:function(){switch(this.day()){case 0:return"[W zeszłą niedzielę o] LT";case 3:return"[W zeszłą środę o] LT";case 6:return"[W zeszłą sobotę o] LT";default:return"[W zeszły] dddd [o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"%s temu",s:"kilka sekund",ss:r,m:r,mm:r,h:r,hh:r,d:"1 dzień",dd:"%d dni",w:"tydzień",ww:r,M:"miesiąc",MM:r,y:"rok",yy:r},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e.r(166540))},736919,(e,a,t)=>{e.e,e.r(166540).defineLocale("pt-br",{months:"janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),monthsShort:"jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),weekdays:"domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado".split("_"),weekdaysShort:"dom_seg_ter_qua_qui_sex_sáb".split("_"),weekdaysMin:"do_2ª_3ª_4ª_5ª_6ª_sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY [às] HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY [às] HH:mm"},calendar:{sameDay:"[Hoje às] LT",nextDay:"[Amanhã às] LT",nextWeek:"dddd [às] LT",lastDay:"[Ontem às] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[Último] dddd [às] LT":"[Última] dddd [às] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"há %s",s:"poucos segundos",ss:"%d segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um mês",MM:"%d meses",y:"um ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",invalidDate:"Data inválida"})},493062,(e,a,t)=>{e.e,e.r(166540).defineLocale("pt",{months:"janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),monthsShort:"jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),weekdays:"Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_Sáb".split("_"),weekdaysMin:"Do_2ª_3ª_4ª_5ª_6ª_Sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY HH:mm"},calendar:{sameDay:"[Hoje às] LT",nextDay:"[Amanhã às] LT",nextWeek:"dddd [às] LT",lastDay:"[Ontem às] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[Último] dddd [às] LT":"[Última] dddd [às] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"há %s",s:"segundos",ss:"%d segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",w:"uma semana",ww:"%d semanas",M:"um mês",MM:"%d meses",y:"um ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})},869377,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t){var s=" ";return(e%100>=20||e>=100&&e%100==0)&&(s=" de "),e+s+({ss:"secunde",mm:"minute",hh:"ore",dd:"zile",ww:"săptămâni",MM:"luni",yy:"ani"})[t]}e.defineLocale("ro",{months:"ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie".split("_"),monthsShort:"ian._feb._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"duminică_luni_marți_miercuri_joi_vineri_sâmbătă".split("_"),weekdaysShort:"Dum_Lun_Mar_Mie_Joi_Vin_Sâm".split("_"),weekdaysMin:"Du_Lu_Ma_Mi_Jo_Vi_Sâ".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[azi la] LT",nextDay:"[mâine la] LT",nextWeek:"dddd [la] LT",lastDay:"[ieri la] LT",lastWeek:"[fosta] dddd [la] LT",sameElse:"L"},relativeTime:{future:"peste %s",past:"%s în urmă",s:"câteva secunde",ss:a,m:"un minut",mm:a,h:"o oră",hh:a,d:"o zi",dd:a,w:"o săptămână",ww:a,M:"o lună",MM:a,y:"un an",yy:a},week:{dow:1,doy:7}})}(e.r(166540))},498262,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t){var s,n,r;return"m"===t?a?"минута":"минуту":e+" "+(s=({ss:a?"секунда_секунды_секунд":"секунду_секунды_секунд",mm:a?"минута_минуты_минут":"минуту_минуты_минут",hh:"час_часа_часов",dd:"день_дня_дней",ww:"неделя_недели_недель",MM:"месяц_месяца_месяцев",yy:"год_года_лет"})[t],n=+e,r=s.split("_"),n%10==1&&n%100!=11?r[0]:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?r[1]:r[2])}var t=[/^янв/i,/^фев/i,/^мар/i,/^апр/i,/^ма[йя]/i,/^июн/i,/^июл/i,/^авг/i,/^сен/i,/^окт/i,/^ноя/i,/^дек/i];e.defineLocale("ru",{months:{format:"января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря".split("_"),standalone:"январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_")},monthsShort:{format:"янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.".split("_"),standalone:"янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.".split("_")},weekdays:{standalone:"воскресенье_понедельник_вторник_среда_четверг_пятница_суббота".split("_"),format:"воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу".split("_"),isFormat:/\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?] ?dddd/},weekdaysShort:"вс_пн_вт_ср_чт_пт_сб".split("_"),weekdaysMin:"вс_пн_вт_ср_чт_пт_сб".split("_"),monthsParse:t,longMonthsParse:t,shortMonthsParse:t,monthsRegex:/^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,monthsShortRegex:/^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,monthsStrictRegex:/^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,monthsShortStrictRegex:/^(янв\.|февр?\.|мар[т.]|апр\.|ма[яй]|июн[ья.]|июл[ья.]|авг\.|сент?\.|окт\.|нояб?\.|дек\.)/i,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY г.",LLL:"D MMMM YYYY г., H:mm",LLLL:"dddd, D MMMM YYYY г., H:mm"},calendar:{sameDay:"[Сегодня, в] LT",nextDay:"[Завтра, в] LT",lastDay:"[Вчера, в] LT",nextWeek:function(e){if(e.week()!==this.week())switch(this.day()){case 0:return"[В следующее] dddd, [в] LT";case 1:case 2:case 4:return"[В следующий] dddd, [в] LT";case 3:case 5:case 6:return"[В следующую] dddd, [в] LT"}else if(2===this.day())return"[Во] dddd, [в] LT";else return"[В] dddd, [в] LT"},lastWeek:function(e){if(e.week()!==this.week())switch(this.day()){case 0:return"[В прошлое] dddd, [в] LT";case 1:case 2:case 4:return"[В прошлый] dddd, [в] LT";case 3:case 5:case 6:return"[В прошлую] dddd, [в] LT"}else if(2===this.day())return"[Во] dddd, [в] LT";else return"[В] dddd, [в] LT"},sameElse:"L"},relativeTime:{future:"через %s",past:"%s назад",s:"несколько секунд",ss:a,m:a,mm:a,h:"час",hh:a,d:"день",dd:a,w:"неделя",ww:a,M:"месяц",MM:a,y:"год",yy:a},meridiemParse:/ночи|утра|дня|вечера/i,isPM:function(e){return/^(дня|вечера)$/.test(e)},meridiem:function(e,a,t){return e<4?"ночи":e<12?"утра":e<17?"дня":"вечера"},dayOfMonthOrdinalParse:/\d{1,2}-(й|го|я)/,ordinal:function(e,a){switch(a){case"M":case"d":case"DDD":return e+"-й";case"D":return e+"-го";case"w":case"W":return e+"-я";default:return e}},week:{dow:1,doy:4}})}(e.r(166540))},137750,(e,a,t)=>{e.e,function(e){"use strict";var a=["جنوري","فيبروري","مارچ","اپريل","مئي","جون","جولاءِ","آگسٽ","سيپٽمبر","آڪٽوبر","نومبر","ڊسمبر"],t=["آچر","سومر","اڱارو","اربع","خميس","جمع","ڇنڇر"];e.defineLocale("sd",{months:a,monthsShort:a,weekdays:t,weekdaysShort:t,weekdaysMin:t,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd، D MMMM YYYY HH:mm"},meridiemParse:/صبح|شام/,isPM:function(e){return"شام"===e},meridiem:function(e,a,t){return e<12?"صبح":"شام"},calendar:{sameDay:"[اڄ] LT",nextDay:"[سڀاڻي] LT",nextWeek:"dddd [اڳين هفتي تي] LT",lastDay:"[ڪالهه] LT",lastWeek:"[گزريل هفتي] dddd [تي] LT",sameElse:"L"},relativeTime:{future:"%s پوء",past:"%s اڳ",s:"چند سيڪنڊ",ss:"%d سيڪنڊ",m:"هڪ منٽ",mm:"%d منٽ",h:"هڪ ڪلاڪ",hh:"%d ڪلاڪ",d:"هڪ ڏينهن",dd:"%d ڏينهن",M:"هڪ مهينو",MM:"%d مهينا",y:"هڪ سال",yy:"%d سال"},preparse:function(e){return e.replace(/،/g,",")},postformat:function(e){return e.replace(/,/g,"،")},week:{dow:1,doy:4}})}(e.r(166540))},455308,(e,a,t)=>{e.e,e.r(166540).defineLocale("se",{months:"ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu".split("_"),monthsShort:"ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov".split("_"),weekdays:"sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat".split("_"),weekdaysShort:"sotn_vuos_maŋ_gask_duor_bear_láv".split("_"),weekdaysMin:"s_v_m_g_d_b_L".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"MMMM D. [b.] YYYY",LLL:"MMMM D. [b.] YYYY [ti.] HH:mm",LLLL:"dddd, MMMM D. [b.] YYYY [ti.] HH:mm"},calendar:{sameDay:"[otne ti] LT",nextDay:"[ihttin ti] LT",nextWeek:"dddd [ti] LT",lastDay:"[ikte ti] LT",lastWeek:"[ovddit] dddd [ti] LT",sameElse:"L"},relativeTime:{future:"%s geažes",past:"maŋit %s",s:"moadde sekunddat",ss:"%d sekunddat",m:"okta minuhta",mm:"%d minuhtat",h:"okta diimmu",hh:"%d diimmut",d:"okta beaivi",dd:"%d beaivvit",M:"okta mánnu",MM:"%d mánut",y:"okta jahki",yy:"%d jagit"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})},303364,(e,a,t)=>{e.e,e.r(166540).defineLocale("si",{months:"ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්".split("_"),monthsShort:"ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ".split("_"),weekdays:"ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා".split("_"),weekdaysShort:"ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන".split("_"),weekdaysMin:"ඉ_ස_අ_බ_බ්‍ර_සි_සෙ".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"a h:mm",LTS:"a h:mm:ss",L:"YYYY/MM/DD",LL:"YYYY MMMM D",LLL:"YYYY MMMM D, a h:mm",LLLL:"YYYY MMMM D [වැනි] dddd, a h:mm:ss"},calendar:{sameDay:"[අද] LT[ට]",nextDay:"[හෙට] LT[ට]",nextWeek:"dddd LT[ට]",lastDay:"[ඊයේ] LT[ට]",lastWeek:"[පසුගිය] dddd LT[ට]",sameElse:"L"},relativeTime:{future:"%sකින්",past:"%sකට පෙර",s:"තත්පර කිහිපය",ss:"තත්පර %d",m:"මිනිත්තුව",mm:"මිනිත්තු %d",h:"පැය",hh:"පැය %d",d:"දිනය",dd:"දින %d",M:"මාසය",MM:"මාස %d",y:"වසර",yy:"වසර %d"},dayOfMonthOrdinalParse:/\d{1,2} වැනි/,ordinal:function(e){return e+" වැනි"},meridiemParse:/පෙර වරු|පස් වරු|පෙ.ව|ප.ව./,isPM:function(e){return"ප.ව."===e||"පස් වරු"===e},meridiem:function(e,a,t){return e>11?t?"ප.ව.":"පස් වරු":t?"පෙ.ව.":"පෙර වරු"}})},195013,(e,a,t)=>{e.e,function(e){"use strict";function a(e){return e>1&&e<5}function t(e,t,s,n){var r=e+" ";switch(s){case"s":return t||n?"pár sekúnd":"pár sekundami";case"ss":if(t||n)return r+(a(e)?"sekundy":"sekúnd");return r+"sekundami";case"m":return t?"minúta":n?"minútu":"minútou";case"mm":if(t||n)return r+(a(e)?"minúty":"minút");return r+"minútami";case"h":return t?"hodina":n?"hodinu":"hodinou";case"hh":if(t||n)return r+(a(e)?"hodiny":"hodín");return r+"hodinami";case"d":return t||n?"deň":"dňom";case"dd":if(t||n)return r+(a(e)?"dni":"dní");return r+"dňami";case"M":return t||n?"mesiac":"mesiacom";case"MM":if(t||n)return r+(a(e)?"mesiace":"mesiacov");return r+"mesiacmi";case"y":return t||n?"rok":"rokom";case"yy":if(t||n)return r+(a(e)?"roky":"rokov");return r+"rokmi"}}e.defineLocale("sk",{months:"január_február_marec_apríl_máj_jún_júl_august_september_október_november_december".split("_"),monthsShort:"jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec".split("_"),weekdays:"nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota".split("_"),weekdaysShort:"ne_po_ut_st_št_pi_so".split("_"),weekdaysMin:"ne_po_ut_st_št_pi_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm"},calendar:{sameDay:"[dnes o] LT",nextDay:"[zajtra o] LT",nextWeek:function(){switch(this.day()){case 0:return"[v nedeľu o] LT";case 1:case 2:return"[v] dddd [o] LT";case 3:return"[v stredu o] LT";case 4:return"[vo štvrtok o] LT";case 5:return"[v piatok o] LT";case 6:return"[v sobotu o] LT"}},lastDay:"[včera o] LT",lastWeek:function(){switch(this.day()){case 0:return"[minulú nedeľu o] LT";case 1:case 2:case 4:case 5:return"[minulý] dddd [o] LT";case 3:return"[minulú stredu o] LT";case 6:return"[minulú sobotu o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"pred %s",s:t,ss:t,m:t,mm:t,h:t,hh:t,d:t,dd:t,M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e.r(166540))},575550,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t,s){var n=e+" ";switch(t){case"s":return a||s?"nekaj sekund":"nekaj sekundami";case"ss":return 1===e?n+=a?"sekundo":"sekundi":2===e?n+=a||s?"sekundi":"sekundah":e<5?n+=a||s?"sekunde":"sekundah":n+="sekund",n;case"m":return a?"ena minuta":"eno minuto";case"mm":return 1===e?n+=a?"minuta":"minuto":2===e?n+=a||s?"minuti":"minutama":e<5?n+=a||s?"minute":"minutami":n+=a||s?"minut":"minutami",n;case"h":return a?"ena ura":"eno uro";case"hh":return 1===e?n+=a?"ura":"uro":2===e?n+=a||s?"uri":"urama":e<5?n+=a||s?"ure":"urami":n+=a||s?"ur":"urami",n;case"d":return a||s?"en dan":"enim dnem";case"dd":return 1===e?n+=a||s?"dan":"dnem":2===e?n+=a||s?"dni":"dnevoma":n+=a||s?"dni":"dnevi",n;case"M":return a||s?"en mesec":"enim mesecem";case"MM":return 1===e?n+=a||s?"mesec":"mesecem":2===e?n+=a||s?"meseca":"mesecema":e<5?n+=a||s?"mesece":"meseci":n+=a||s?"mesecev":"meseci",n;case"y":return a||s?"eno leto":"enim letom";case"yy":return 1===e?n+=a||s?"leto":"letom":2===e?n+=a||s?"leti":"letoma":e<5?n+=a||s?"leta":"leti":n+=a||s?"let":"leti",n}}e.defineLocale("sl",{months:"januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota".split("_"),weekdaysShort:"ned._pon._tor._sre._čet._pet._sob.".split("_"),weekdaysMin:"ne_po_to_sr_če_pe_so".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danes ob] LT",nextDay:"[jutri ob] LT",nextWeek:function(){switch(this.day()){case 0:return"[v] [nedeljo] [ob] LT";case 3:return"[v] [sredo] [ob] LT";case 6:return"[v] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[v] dddd [ob] LT"}},lastDay:"[včeraj ob] LT",lastWeek:function(){switch(this.day()){case 0:return"[prejšnjo] [nedeljo] [ob] LT";case 3:return"[prejšnjo] [sredo] [ob] LT";case 6:return"[prejšnjo] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[prejšnji] dddd [ob] LT"}},sameElse:"L"},relativeTime:{future:"čez %s",past:"pred %s",s:a,ss:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(e.r(166540))},813013,(e,a,t)=>{e.e,e.r(166540).defineLocale("sq",{months:"Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor".split("_"),monthsShort:"Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj".split("_"),weekdays:"E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë".split("_"),weekdaysShort:"Die_Hën_Mar_Mër_Enj_Pre_Sht".split("_"),weekdaysMin:"D_H_Ma_Më_E_P_Sh".split("_"),weekdaysParseExact:!0,meridiemParse:/PD|MD/,isPM:function(e){return"M"===e.charAt(0)},meridiem:function(e,a,t){return e<12?"PD":"MD"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Sot në] LT",nextDay:"[Nesër në] LT",nextWeek:"dddd [në] LT",lastDay:"[Dje në] LT",lastWeek:"dddd [e kaluar në] LT",sameElse:"L"},relativeTime:{future:"në %s",past:"%s më parë",s:"disa sekonda",ss:"%d sekonda",m:"një minutë",mm:"%d minuta",h:"një orë",hh:"%d orë",d:"një ditë",dd:"%d ditë",M:"një muaj",MM:"%d muaj",y:"një vit",yy:"%d vite"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})},423039,(e,a,t)=>{e.e,function(e){"use strict";var a={words:{ss:["секунда","секунде","секунди"],m:["један минут","једног минута"],mm:["минут","минута","минута"],h:["један сат","једног сата"],hh:["сат","сата","сати"],d:["један дан","једног дана"],dd:["дан","дана","дана"],M:["један месец","једног месеца"],MM:["месец","месеца","месеци"],y:["једну годину","једне године"],yy:["годину","године","година"]},correctGrammaticalCase:function(e,a){return e%10>=1&&e%10<=4&&(e%100<10||e%100>=20)?e%10==1?a[0]:a[1]:a[2]},translate:function(e,t,s,n){var r,d=a.words[s];return 1===s.length?"y"===s&&t?"једна година":n||t?d[0]:d[1]:(r=a.correctGrammaticalCase(e,d),"yy"===s&&t&&"годину"===r)?e+" година":e+" "+r}};e.defineLocale("sr-cyrl",{months:"јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар".split("_"),monthsShort:"јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.".split("_"),monthsParseExact:!0,weekdays:"недеља_понедељак_уторак_среда_четвртак_петак_субота".split("_"),weekdaysShort:"нед._пон._уто._сре._чет._пет._суб.".split("_"),weekdaysMin:"не_по_ут_ср_че_пе_су".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D. M. YYYY.",LL:"D. MMMM YYYY.",LLL:"D. MMMM YYYY. H:mm",LLLL:"dddd, D. MMMM YYYY. H:mm"},calendar:{sameDay:"[данас у] LT",nextDay:"[сутра у] LT",nextWeek:function(){switch(this.day()){case 0:return"[у] [недељу] [у] LT";case 3:return"[у] [среду] [у] LT";case 6:return"[у] [суботу] [у] LT";case 1:case 2:case 4:case 5:return"[у] dddd [у] LT"}},lastDay:"[јуче у] LT",lastWeek:function(){return["[прошле] [недеље] [у] LT","[прошлог] [понедељка] [у] LT","[прошлог] [уторка] [у] LT","[прошле] [среде] [у] LT","[прошлог] [четвртка] [у] LT","[прошлог] [петка] [у] LT","[прошле] [суботе] [у] LT"][this.day()]},sameElse:"L"},relativeTime:{future:"за %s",past:"пре %s",s:"неколико секунди",ss:a.translate,m:a.translate,mm:a.translate,h:a.translate,hh:a.translate,d:a.translate,dd:a.translate,M:a.translate,MM:a.translate,y:a.translate,yy:a.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(e.r(166540))},654301,(e,a,t)=>{e.e,function(e){"use strict";var a={words:{ss:["sekunda","sekunde","sekundi"],m:["jedan minut","jednog minuta"],mm:["minut","minuta","minuta"],h:["jedan sat","jednog sata"],hh:["sat","sata","sati"],d:["jedan dan","jednog dana"],dd:["dan","dana","dana"],M:["jedan mesec","jednog meseca"],MM:["mesec","meseca","meseci"],y:["jednu godinu","jedne godine"],yy:["godinu","godine","godina"]},correctGrammaticalCase:function(e,a){return e%10>=1&&e%10<=4&&(e%100<10||e%100>=20)?e%10==1?a[0]:a[1]:a[2]},translate:function(e,t,s,n){var r,d=a.words[s];return 1===s.length?"y"===s&&t?"jedna godina":n||t?d[0]:d[1]:(r=a.correctGrammaticalCase(e,d),"yy"===s&&t&&"godinu"===r)?e+" godina":e+" "+r}};e.defineLocale("sr",{months:"januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sre._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D. M. YYYY.",LL:"D. MMMM YYYY.",LLL:"D. MMMM YYYY. H:mm",LLLL:"dddd, D. MMMM YYYY. H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedelju] [u] LT";case 3:return"[u] [sredu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[juče u] LT",lastWeek:function(){return["[prošle] [nedelje] [u] LT","[prošlog] [ponedeljka] [u] LT","[prošlog] [utorka] [u] LT","[prošle] [srede] [u] LT","[prošlog] [četvrtka] [u] LT","[prošlog] [petka] [u] LT","[prošle] [subote] [u] LT"][this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"pre %s",s:"nekoliko sekundi",ss:a.translate,m:a.translate,mm:a.translate,h:a.translate,hh:a.translate,d:a.translate,dd:a.translate,M:a.translate,MM:a.translate,y:a.translate,yy:a.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(e.r(166540))},492305,(e,a,t)=>{e.e,e.r(166540).defineLocale("ss",{months:"Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni".split("_"),monthsShort:"Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo".split("_"),weekdays:"Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo".split("_"),weekdaysShort:"Lis_Umb_Lsb_Les_Lsi_Lsh_Umg".split("_"),weekdaysMin:"Li_Us_Lb_Lt_Ls_Lh_Ug".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Namuhla nga] LT",nextDay:"[Kusasa nga] LT",nextWeek:"dddd [nga] LT",lastDay:"[Itolo nga] LT",lastWeek:"dddd [leliphelile] [nga] LT",sameElse:"L"},relativeTime:{future:"nga %s",past:"wenteka nga %s",s:"emizuzwana lomcane",ss:"%d mzuzwana",m:"umzuzu",mm:"%d emizuzu",h:"lihora",hh:"%d emahora",d:"lilanga",dd:"%d emalanga",M:"inyanga",MM:"%d tinyanga",y:"umnyaka",yy:"%d iminyaka"},meridiemParse:/ekuseni|emini|entsambama|ebusuku/,meridiem:function(e,a,t){return e<11?"ekuseni":e<15?"emini":e<19?"entsambama":"ebusuku"},meridiemHour:function(e,a){return(12===e&&(e=0),"ekuseni"===a)?e:"emini"===a?e>=11?e:e+12:"entsambama"===a||"ebusuku"===a?0===e?0:e+12:void 0},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:"%d",week:{dow:1,doy:4}})},937057,(e,a,t)=>{e.e,e.r(166540).defineLocale("sv",{months:"januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag".split("_"),weekdaysShort:"sön_mån_tis_ons_tor_fre_lör".split("_"),weekdaysMin:"sö_må_ti_on_to_fr_lö".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [kl.] HH:mm",LLLL:"dddd D MMMM YYYY [kl.] HH:mm",lll:"D MMM YYYY HH:mm",llll:"ddd D MMM YYYY HH:mm"},calendar:{sameDay:"[Idag] LT",nextDay:"[Imorgon] LT",lastDay:"[Igår] LT",nextWeek:"[På] dddd LT",lastWeek:"[I] dddd[s] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"för %s sedan",s:"några sekunder",ss:"%d sekunder",m:"en minut",mm:"%d minuter",h:"en timme",hh:"%d timmar",d:"en dag",dd:"%d dagar",M:"en månad",MM:"%d månader",y:"ett år",yy:"%d år"},dayOfMonthOrdinalParse:/\d{1,2}(\:e|\:a)/,ordinal:function(e){var a=e%10,t=1==~~(e%100/10)?":e":1===a||2===a?":a":":e";return e+t},week:{dow:1,doy:4}})},771953,(e,a,t)=>{e.e,e.r(166540).defineLocale("sw",{months:"Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des".split("_"),weekdays:"Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi".split("_"),weekdaysShort:"Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos".split("_"),weekdaysMin:"J2_J3_J4_J5_Al_Ij_J1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"hh:mm A",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[leo saa] LT",nextDay:"[kesho saa] LT",nextWeek:"[wiki ijayo] dddd [saat] LT",lastDay:"[jana] LT",lastWeek:"[wiki iliyopita] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s baadaye",past:"tokea %s",s:"hivi punde",ss:"sekunde %d",m:"dakika moja",mm:"dakika %d",h:"saa limoja",hh:"masaa %d",d:"siku moja",dd:"siku %d",M:"mwezi mmoja",MM:"miezi %d",y:"mwaka mmoja",yy:"miaka %d"},week:{dow:1,doy:7}})},271953,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"௧",2:"௨",3:"௩",4:"௪",5:"௫",6:"௬",7:"௭",8:"௮",9:"௯",0:"௦"},t={"௧":"1","௨":"2","௩":"3","௪":"4","௫":"5","௬":"6","௭":"7","௮":"8","௯":"9","௦":"0"};e.defineLocale("ta",{months:"ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்".split("_"),monthsShort:"ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்".split("_"),weekdays:"ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை".split("_"),weekdaysShort:"ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி".split("_"),weekdaysMin:"ஞா_தி_செ_பு_வி_வெ_ச".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, HH:mm",LLLL:"dddd, D MMMM YYYY, HH:mm"},calendar:{sameDay:"[இன்று] LT",nextDay:"[நாளை] LT",nextWeek:"dddd, LT",lastDay:"[நேற்று] LT",lastWeek:"[கடந்த வாரம்] dddd, LT",sameElse:"L"},relativeTime:{future:"%s இல்",past:"%s முன்",s:"ஒரு சில விநாடிகள்",ss:"%d விநாடிகள்",m:"ஒரு நிமிடம்",mm:"%d நிமிடங்கள்",h:"ஒரு மணி நேரம்",hh:"%d மணி நேரம்",d:"ஒரு நாள்",dd:"%d நாட்கள்",M:"ஒரு மாதம்",MM:"%d மாதங்கள்",y:"ஒரு வருடம்",yy:"%d ஆண்டுகள்"},dayOfMonthOrdinalParse:/\d{1,2}வது/,ordinal:function(e){return e+"வது"},preparse:function(e){return e.replace(/[௧௨௩௪௫௬௭௮௯௦]/g,function(e){return t[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return a[e]})},meridiemParse:/யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,meridiem:function(e,a,t){if(e<2)return" யாமம்";if(e<6)return" வைகறை";if(e<10)return" காலை";if(e<14)return" நண்பகல்";if(e<18)return" எற்பாடு";else if(e<22)return" மாலை";else return" யாமம்"},meridiemHour:function(e,a){return(12===e&&(e=0),"யாமம்"===a)?e<2?e:e+12:"வைகறை"===a||"காலை"===a?e:"நண்பகல்"===a?e>=10?e:e+12:e+12},week:{dow:0,doy:6}})}(e.r(166540))},749731,(e,a,t)=>{e.e,e.r(166540).defineLocale("te",{months:"జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జులై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్".split("_"),monthsShort:"జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జులై_ఆగ._సెప్._అక్టో._నవ._డిసె.".split("_"),monthsParseExact:!0,weekdays:"ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం".split("_"),weekdaysShort:"ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని".split("_"),weekdaysMin:"ఆ_సో_మం_బు_గు_శు_శ".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[నేడు] LT",nextDay:"[రేపు] LT",nextWeek:"dddd, LT",lastDay:"[నిన్న] LT",lastWeek:"[గత] dddd, LT",sameElse:"L"},relativeTime:{future:"%s లో",past:"%s క్రితం",s:"కొన్ని క్షణాలు",ss:"%d సెకన్లు",m:"ఒక నిమిషం",mm:"%d నిమిషాలు",h:"ఒక గంట",hh:"%d గంటలు",d:"ఒక రోజు",dd:"%d రోజులు",M:"ఒక నెల",MM:"%d నెలలు",y:"ఒక సంవత్సరం",yy:"%d సంవత్సరాలు"},dayOfMonthOrdinalParse:/\d{1,2}వ/,ordinal:"%dవ",meridiemParse:/రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/,meridiemHour:function(e,a){return(12===e&&(e=0),"రాత్రి"===a)?e<4?e:e+12:"ఉదయం"===a?e:"మధ్యాహ్నం"===a?e>=10?e:e+12:"సాయంత్రం"===a?e+12:void 0},meridiem:function(e,a,t){return e<4?"రాత్రి":e<10?"ఉదయం":e<17?"మధ్యాహ్నం":e<20?"సాయంత్రం":"రాత్రి"},week:{dow:0,doy:6}})},165002,(e,a,t)=>{e.e,e.r(166540).defineLocale("tet",{months:"Janeiru_Fevereiru_Marsu_Abril_Maiu_Juñu_Jullu_Agustu_Setembru_Outubru_Novembru_Dezembru".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingu_Segunda_Tersa_Kuarta_Kinta_Sesta_Sabadu".split("_"),weekdaysShort:"Dom_Seg_Ters_Kua_Kint_Sest_Sab".split("_"),weekdaysMin:"Do_Seg_Te_Ku_Ki_Ses_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Ohin iha] LT",nextDay:"[Aban iha] LT",nextWeek:"dddd [iha] LT",lastDay:"[Horiseik iha] LT",lastWeek:"dddd [semana kotuk] [iha] LT",sameElse:"L"},relativeTime:{future:"iha %s",past:"%s liuba",s:"segundu balun",ss:"segundu %d",m:"minutu ida",mm:"minutu %d",h:"oras ida",hh:"oras %d",d:"loron ida",dd:"loron %d",M:"fulan ida",MM:"fulan %d",y:"tinan ida",yy:"tinan %d"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var a=e%10,t=1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th";return e+t},week:{dow:1,doy:4}})},580104,(e,a,t)=>{e.e,function(e){"use strict";var a={0:"-ум",1:"-ум",2:"-юм",3:"-юм",4:"-ум",5:"-ум",6:"-ум",7:"-ум",8:"-ум",9:"-ум",10:"-ум",12:"-ум",13:"-ум",20:"-ум",30:"-юм",40:"-ум",50:"-ум",60:"-ум",70:"-ум",80:"-ум",90:"-ум",100:"-ум"};e.defineLocale("tg",{months:{format:"январи_феврали_марти_апрели_майи_июни_июли_августи_сентябри_октябри_ноябри_декабри".split("_"),standalone:"январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр".split("_")},monthsShort:"янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек".split("_"),weekdays:"якшанбе_душанбе_сешанбе_чоршанбе_панҷшанбе_ҷумъа_шанбе".split("_"),weekdaysShort:"яшб_дшб_сшб_чшб_пшб_ҷум_шнб".split("_"),weekdaysMin:"яш_дш_сш_чш_пш_ҷм_шб".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Имрӯз соати] LT",nextDay:"[Фардо соати] LT",lastDay:"[Дирӯз соати] LT",nextWeek:"dddd[и] [ҳафтаи оянда соати] LT",lastWeek:"dddd[и] [ҳафтаи гузашта соати] LT",sameElse:"L"},relativeTime:{future:"баъди %s",past:"%s пеш",s:"якчанд сония",m:"як дақиқа",mm:"%d дақиқа",h:"як соат",hh:"%d соат",d:"як рӯз",dd:"%d рӯз",M:"як моҳ",MM:"%d моҳ",y:"як сол",yy:"%d сол"},meridiemParse:/шаб|субҳ|рӯз|бегоҳ/,meridiemHour:function(e,a){return(12===e&&(e=0),"шаб"===a)?e<4?e:e+12:"субҳ"===a?e:"рӯз"===a?e>=11?e:e+12:"бегоҳ"===a?e+12:void 0},meridiem:function(e,a,t){return e<4?"шаб":e<11?"субҳ":e<16?"рӯз":e<19?"бегоҳ":"шаб"},dayOfMonthOrdinalParse:/\d{1,2}-(ум|юм)/,ordinal:function(e){return e+(a[e]||a[e%10]||a[e>=100?100:null])},week:{dow:1,doy:7}})}(e.r(166540))},768313,(e,a,t)=>{e.e,e.r(166540).defineLocale("th",{months:"มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม".split("_"),monthsShort:"ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.".split("_"),monthsParseExact:!0,weekdays:"อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์".split("_"),weekdaysShort:"อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์".split("_"),weekdaysMin:"อา._จ._อ._พ._พฤ._ศ._ส.".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY เวลา H:mm",LLLL:"วันddddที่ D MMMM YYYY เวลา H:mm"},meridiemParse:/ก่อนเที่ยง|หลังเที่ยง/,isPM:function(e){return"หลังเที่ยง"===e},meridiem:function(e,a,t){return e<12?"ก่อนเที่ยง":"หลังเที่ยง"},calendar:{sameDay:"[วันนี้ เวลา] LT",nextDay:"[พรุ่งนี้ เวลา] LT",nextWeek:"dddd[หน้า เวลา] LT",lastDay:"[เมื่อวานนี้ เวลา] LT",lastWeek:"[วัน]dddd[ที่แล้ว เวลา] LT",sameElse:"L"},relativeTime:{future:"อีก %s",past:"%sที่แล้ว",s:"ไม่กี่วินาที",ss:"%d วินาที",m:"1 นาที",mm:"%d นาที",h:"1 ชั่วโมง",hh:"%d ชั่วโมง",d:"1 วัน",dd:"%d วัน",w:"1 สัปดาห์",ww:"%d สัปดาห์",M:"1 เดือน",MM:"%d เดือน",y:"1 ปี",yy:"%d ปี"}})},291616,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"'inji",5:"'inji",8:"'inji",70:"'inji",80:"'inji",2:"'nji",7:"'nji",20:"'nji",50:"'nji",3:"'ünji",4:"'ünji",100:"'ünji",6:"'njy",9:"'unjy",10:"'unjy",30:"'unjy",60:"'ynjy",90:"'ynjy"};e.defineLocale("tk",{months:"Ýanwar_Fewral_Mart_Aprel_Maý_Iýun_Iýul_Awgust_Sentýabr_Oktýabr_Noýabr_Dekabr".split("_"),monthsShort:"Ýan_Few_Mar_Apr_Maý_Iýn_Iýl_Awg_Sen_Okt_Noý_Dek".split("_"),weekdays:"Ýekşenbe_Duşenbe_Sişenbe_Çarşenbe_Penşenbe_Anna_Şenbe".split("_"),weekdaysShort:"Ýek_Duş_Siş_Çar_Pen_Ann_Şen".split("_"),weekdaysMin:"Ýk_Dş_Sş_Çr_Pn_An_Şn".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bugün sagat] LT",nextDay:"[ertir sagat] LT",nextWeek:"[indiki] dddd [sagat] LT",lastDay:"[düýn] LT",lastWeek:"[geçen] dddd [sagat] LT",sameElse:"L"},relativeTime:{future:"%s soň",past:"%s öň",s:"birnäçe sekunt",m:"bir minut",mm:"%d minut",h:"bir sagat",hh:"%d sagat",d:"bir gün",dd:"%d gün",M:"bir aý",MM:"%d aý",y:"bir ýyl",yy:"%d ýyl"},ordinal:function(e,t){switch(t){case"d":case"D":case"Do":case"DD":return e;default:if(0===e)return e+"'unjy";var s=e%10;return e+(a[s]||a[e%100-s]||a[e>=100?100:null])}},week:{dow:1,doy:7}})}(e.r(166540))},317895,(e,a,t)=>{e.e,e.r(166540).defineLocale("tl-ph",{months:"Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre".split("_"),monthsShort:"Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis".split("_"),weekdays:"Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado".split("_"),weekdaysShort:"Lin_Lun_Mar_Miy_Huw_Biy_Sab".split("_"),weekdaysMin:"Li_Lu_Ma_Mi_Hu_Bi_Sab".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"MM/D/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY HH:mm",LLLL:"dddd, MMMM DD, YYYY HH:mm"},calendar:{sameDay:"LT [ngayong araw]",nextDay:"[Bukas ng] LT",nextWeek:"LT [sa susunod na] dddd",lastDay:"LT [kahapon]",lastWeek:"LT [noong nakaraang] dddd",sameElse:"L"},relativeTime:{future:"sa loob ng %s",past:"%s ang nakalipas",s:"ilang segundo",ss:"%d segundo",m:"isang minuto",mm:"%d minuto",h:"isang oras",hh:"%d oras",d:"isang araw",dd:"%d araw",M:"isang buwan",MM:"%d buwan",y:"isang taon",yy:"%d taon"},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:function(e){return e},week:{dow:1,doy:4}})},955799,(e,a,t)=>{e.e,function(e){"use strict";var a="pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut".split("_");function t(e,t,s,n){var r,d,i,_,o,m=(d=Math.floor((r=e)%1e3/100),i=Math.floor(r%100/10),_=r%10,o="",d>0&&(o+=a[d]+"vatlh"),i>0&&(o+=(""!==o?" ":"")+a[i]+"maH"),_>0&&(o+=(""!==o?" ":"")+a[_]),""===o?"pagh":o);switch(s){case"ss":return m+" lup";case"mm":return m+" tup";case"hh":return m+" rep";case"dd":return m+" jaj";case"MM":return m+" jar";case"yy":return m+" DIS"}}e.defineLocale("tlh",{months:"tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’".split("_"),monthsShort:"jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’".split("_"),monthsParseExact:!0,weekdays:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),weekdaysShort:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),weekdaysMin:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[DaHjaj] LT",nextDay:"[wa’leS] LT",nextWeek:"LLL",lastDay:"[wa’Hu’] LT",lastWeek:"LLL",sameElse:"L"},relativeTime:{future:function(e){var a=e;return -1!==e.indexOf("jaj")?a.slice(0,-3)+"leS":-1!==e.indexOf("jar")?a.slice(0,-3)+"waQ":-1!==e.indexOf("DIS")?a.slice(0,-3)+"nem":a+" pIq"},past:function(e){var a=e;return -1!==e.indexOf("jaj")?a.slice(0,-3)+"Hu’":-1!==e.indexOf("jar")?a.slice(0,-3)+"wen":-1!==e.indexOf("DIS")?a.slice(0,-3)+"ben":a+" ret"},s:"puS lup",ss:t,m:"wa’ tup",mm:t,h:"wa’ rep",hh:t,d:"wa’ jaj",dd:t,M:"wa’ jar",MM:t,y:"wa’ DIS",yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e.r(166540))},515252,(e,a,t)=>{e.e,function(e){"use strict";var a={1:"'inci",5:"'inci",8:"'inci",70:"'inci",80:"'inci",2:"'nci",7:"'nci",20:"'nci",50:"'nci",3:"'üncü",4:"'üncü",100:"'üncü",6:"'ncı",9:"'uncu",10:"'uncu",30:"'uncu",60:"'ıncı",90:"'ıncı"};e.defineLocale("tr",{months:"Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık".split("_"),monthsShort:"Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara".split("_"),weekdays:"Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi".split("_"),weekdaysShort:"Paz_Pzt_Sal_Çar_Per_Cum_Cmt".split("_"),weekdaysMin:"Pz_Pt_Sa_Ça_Pe_Cu_Ct".split("_"),meridiem:function(e,a,t){return e<12?t?"öö":"ÖÖ":t?"ös":"ÖS"},meridiemParse:/öö|ÖÖ|ös|ÖS/,isPM:function(e){return"ös"===e||"ÖS"===e},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bugün saat] LT",nextDay:"[yarın saat] LT",nextWeek:"[gelecek] dddd [saat] LT",lastDay:"[dün] LT",lastWeek:"[geçen] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s önce",s:"birkaç saniye",ss:"%d saniye",m:"bir dakika",mm:"%d dakika",h:"bir saat",hh:"%d saat",d:"bir gün",dd:"%d gün",w:"bir hafta",ww:"%d hafta",M:"bir ay",MM:"%d ay",y:"bir yıl",yy:"%d yıl"},ordinal:function(e,t){switch(t){case"d":case"D":case"Do":case"DD":return e;default:if(0===e)return e+"'ıncı";var s=e%10;return e+(a[s]||a[e%100-s]||a[e>=100?100:null])}},week:{dow:1,doy:7}})}(e.r(166540))},568087,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t,s){var n={s:["viensas secunds","'iensas secunds"],ss:[e+" secunds",""+e+" secunds"],m:["'n míut","'iens míut"],mm:[e+" míuts",""+e+" míuts"],h:["'n þora","'iensa þora"],hh:[e+" þoras",""+e+" þoras"],d:["'n ziua","'iensa ziua"],dd:[e+" ziuas",""+e+" ziuas"],M:["'n mes","'iens mes"],MM:[e+" mesen",""+e+" mesen"],y:["'n ar","'iens ar"],yy:[e+" ars",""+e+" ars"]};return s||a?n[t][0]:n[t][1]}e.defineLocale("tzl",{months:"Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar".split("_"),monthsShort:"Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec".split("_"),weekdays:"Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi".split("_"),weekdaysShort:"Súl_Lún_Mai_Már_Xhú_Vié_Sát".split("_"),weekdaysMin:"Sú_Lú_Ma_Má_Xh_Vi_Sá".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"D. MMMM [dallas] YYYY",LLL:"D. MMMM [dallas] YYYY HH.mm",LLLL:"dddd, [li] D. MMMM [dallas] YYYY HH.mm"},meridiemParse:/d\'o|d\'a/i,isPM:function(e){return"d'o"===e.toLowerCase()},meridiem:function(e,a,t){return e>11?t?"d'o":"D'O":t?"d'a":"D'A"},calendar:{sameDay:"[oxhi à] LT",nextDay:"[demà à] LT",nextWeek:"dddd [à] LT",lastDay:"[ieiri à] LT",lastWeek:"[sür el] dddd [lasteu à] LT",sameElse:"L"},relativeTime:{future:"osprei %s",past:"ja%s",s:a,ss:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(e.r(166540))},542954,(e,a,t)=>{e.e,e.r(166540).defineLocale("tzm-latn",{months:"innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"),monthsShort:"innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"),weekdays:"asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),weekdaysShort:"asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),weekdaysMin:"asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[asdkh g] LT",nextDay:"[aska g] LT",nextWeek:"dddd [g] LT",lastDay:"[assant g] LT",lastWeek:"dddd [g] LT",sameElse:"L"},relativeTime:{future:"dadkh s yan %s",past:"yan %s",s:"imik",ss:"%d imik",m:"minuḍ",mm:"%d minuḍ",h:"saɛa",hh:"%d tassaɛin",d:"ass",dd:"%d ossan",M:"ayowr",MM:"%d iyyirn",y:"asgas",yy:"%d isgasn"},week:{dow:6,doy:12}})},267123,(e,a,t)=>{e.e,e.r(166540).defineLocale("tzm",{months:"ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"),monthsShort:"ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"),weekdays:"ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),weekdaysShort:"ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),weekdaysMin:"ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[ⴰⵙⴷⵅ ⴴ] LT",nextDay:"[ⴰⵙⴽⴰ ⴴ] LT",nextWeek:"dddd [ⴴ] LT",lastDay:"[ⴰⵚⴰⵏⵜ ⴴ] LT",lastWeek:"dddd [ⴴ] LT",sameElse:"L"},relativeTime:{future:"ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s",past:"ⵢⴰⵏ %s",s:"ⵉⵎⵉⴽ",ss:"%d ⵉⵎⵉⴽ",m:"ⵎⵉⵏⵓⴺ",mm:"%d ⵎⵉⵏⵓⴺ",h:"ⵙⴰⵄⴰ",hh:"%d ⵜⴰⵙⵙⴰⵄⵉⵏ",d:"ⴰⵙⵙ",dd:"%d oⵙⵙⴰⵏ",M:"ⴰⵢoⵓⵔ",MM:"%d ⵉⵢⵢⵉⵔⵏ",y:"ⴰⵙⴳⴰⵙ",yy:"%d ⵉⵙⴳⴰⵙⵏ"},week:{dow:6,doy:12}})},468227,(e,a,t)=>{e.e,e.r(166540).defineLocale("ug-cn",{months:"يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر".split("_"),monthsShort:"يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر".split("_"),weekdays:"يەكشەنبە_دۈشەنبە_سەيشەنبە_چارشەنبە_پەيشەنبە_جۈمە_شەنبە".split("_"),weekdaysShort:"يە_دۈ_سە_چا_پە_جۈ_شە".split("_"),weekdaysMin:"يە_دۈ_سە_چا_پە_جۈ_شە".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY-يىلىM-ئاينىڭD-كۈنى",LLL:"YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm",LLLL:"dddd، YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm"},meridiemParse:/يېرىم كېچە|سەھەر|چۈشتىن بۇرۇن|چۈش|چۈشتىن كېيىن|كەچ/,meridiemHour:function(e,a){return(12===e&&(e=0),"يېرىم كېچە"===a||"سەھەر"===a||"چۈشتىن بۇرۇن"===a)?e:"چۈشتىن كېيىن"===a||"كەچ"===a?e+12:e>=11?e:e+12},meridiem:function(e,a,t){var s=100*e+a;if(s<600)return"يېرىم كېچە";if(s<900)return"سەھەر";if(s<1130)return"چۈشتىن بۇرۇن";if(s<1230)return"چۈش";if(s<1800)return"چۈشتىن كېيىن";else return"كەچ"},calendar:{sameDay:"[بۈگۈن سائەت] LT",nextDay:"[ئەتە سائەت] LT",nextWeek:"[كېلەركى] dddd [سائەت] LT",lastDay:"[تۆنۈگۈن] LT",lastWeek:"[ئالدىنقى] dddd [سائەت] LT",sameElse:"L"},relativeTime:{future:"%s كېيىن",past:"%s بۇرۇن",s:"نەچچە سېكونت",ss:"%d سېكونت",m:"بىر مىنۇت",mm:"%d مىنۇت",h:"بىر سائەت",hh:"%d سائەت",d:"بىر كۈن",dd:"%d كۈن",M:"بىر ئاي",MM:"%d ئاي",y:"بىر يىل",yy:"%d يىل"},dayOfMonthOrdinalParse:/\d{1,2}(-كۈنى|-ئاي|-ھەپتە)/,ordinal:function(e,a){switch(a){case"d":case"D":case"DDD":return e+"-كۈنى";case"w":case"W":return e+"-ھەپتە";default:return e}},preparse:function(e){return e.replace(/،/g,",")},postformat:function(e){return e.replace(/,/g,"،")},week:{dow:1,doy:7}})},557418,(e,a,t)=>{e.e,function(e){"use strict";function a(e,a,t){var s,n,r;return"m"===t?a?"хвилина":"хвилину":"h"===t?a?"година":"годину":e+" "+(s=({ss:a?"секунда_секунди_секунд":"секунду_секунди_секунд",mm:a?"хвилина_хвилини_хвилин":"хвилину_хвилини_хвилин",hh:a?"година_години_годин":"годину_години_годин",dd:"день_дні_днів",MM:"місяць_місяці_місяців",yy:"рік_роки_років"})[t],n=+e,r=s.split("_"),n%10==1&&n%100!=11?r[0]:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?r[1]:r[2])}function t(e){return function(){return e+"о"+(11===this.hours()?"б":"")+"] LT"}}e.defineLocale("uk",{months:{format:"січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня".split("_"),standalone:"січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень".split("_")},monthsShort:"січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд".split("_"),weekdays:function(e,a){var t={nominative:"неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота".split("_"),accusative:"неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу".split("_"),genitive:"неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи".split("_")};return!0===e?t.nominative.slice(1,7).concat(t.nominative.slice(0,1)):e?t[/(\[[ВвУу]\]) ?dddd/.test(a)?"accusative":/\[?(?:минулої|наступної)? ?\] ?dddd/.test(a)?"genitive":"nominative"][e.day()]:t.nominative},weekdaysShort:"нд_пн_вт_ср_чт_пт_сб".split("_"),weekdaysMin:"нд_пн_вт_ср_чт_пт_сб".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY р.",LLL:"D MMMM YYYY р., HH:mm",LLLL:"dddd, D MMMM YYYY р., HH:mm"},calendar:{sameDay:t("[Сьогодні "),nextDay:t("[Завтра "),lastDay:t("[Вчора "),nextWeek:t("[У] dddd ["),lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return t("[Минулої] dddd [").call(this);case 1:case 2:case 4:return t("[Минулого] dddd [").call(this)}},sameElse:"L"},relativeTime:{future:"за %s",past:"%s тому",s:"декілька секунд",ss:a,m:a,mm:a,h:"годину",hh:a,d:"день",dd:a,M:"місяць",MM:a,y:"рік",yy:a},meridiemParse:/ночі|ранку|дня|вечора/,isPM:function(e){return/^(дня|вечора)$/.test(e)},meridiem:function(e,a,t){return e<4?"ночі":e<12?"ранку":e<17?"дня":"вечора"},dayOfMonthOrdinalParse:/\d{1,2}-(й|го)/,ordinal:function(e,a){switch(a){case"M":case"d":case"DDD":case"w":case"W":return e+"-й";case"D":return e+"-го";default:return e}},week:{dow:1,doy:7}})}(e.r(166540))},721396,(e,a,t)=>{e.e,function(e){"use strict";var a=["جنوری","فروری","مارچ","اپریل","مئی","جون","جولائی","اگست","ستمبر","اکتوبر","نومبر","دسمبر"],t=["اتوار","پیر","منگل","بدھ","جمعرات","جمعہ","ہفتہ"];e.defineLocale("ur",{months:a,monthsShort:a,weekdays:t,weekdaysShort:t,weekdaysMin:t,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd، D MMMM YYYY HH:mm"},meridiemParse:/صبح|شام/,isPM:function(e){return"شام"===e},meridiem:function(e,a,t){return e<12?"صبح":"شام"},calendar:{sameDay:"[آج بوقت] LT",nextDay:"[کل بوقت] LT",nextWeek:"dddd [بوقت] LT",lastDay:"[گذشتہ روز بوقت] LT",lastWeek:"[گذشتہ] dddd [بوقت] LT",sameElse:"L"},relativeTime:{future:"%s بعد",past:"%s قبل",s:"چند سیکنڈ",ss:"%d سیکنڈ",m:"ایک منٹ",mm:"%d منٹ",h:"ایک گھنٹہ",hh:"%d گھنٹے",d:"ایک دن",dd:"%d دن",M:"ایک ماہ",MM:"%d ماہ",y:"ایک سال",yy:"%d سال"},preparse:function(e){return e.replace(/،/g,",")},postformat:function(e){return e.replace(/,/g,"،")},week:{dow:1,doy:4}})}(e.r(166540))},647658,(e,a,t)=>{e.e,e.r(166540).defineLocale("uz-latn",{months:"Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr".split("_"),monthsShort:"Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek".split("_"),weekdays:"Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba".split("_"),weekdaysShort:"Yak_Dush_Sesh_Chor_Pay_Jum_Shan".split("_"),weekdaysMin:"Ya_Du_Se_Cho_Pa_Ju_Sha".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"D MMMM YYYY, dddd HH:mm"},calendar:{sameDay:"[Bugun soat] LT [da]",nextDay:"[Ertaga] LT [da]",nextWeek:"dddd [kuni soat] LT [da]",lastDay:"[Kecha soat] LT [da]",lastWeek:"[O'tgan] dddd [kuni soat] LT [da]",sameElse:"L"},relativeTime:{future:"Yaqin %s ichida",past:"Bir necha %s oldin",s:"soniya",ss:"%d soniya",m:"bir daqiqa",mm:"%d daqiqa",h:"bir soat",hh:"%d soat",d:"bir kun",dd:"%d kun",M:"bir oy",MM:"%d oy",y:"bir yil",yy:"%d yil"},week:{dow:1,doy:7}})},298424,(e,a,t)=>{e.e,e.r(166540).defineLocale("uz",{months:"январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр".split("_"),monthsShort:"янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек".split("_"),weekdays:"Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба".split("_"),weekdaysShort:"Якш_Душ_Сеш_Чор_Пай_Жум_Шан".split("_"),weekdaysMin:"Як_Ду_Се_Чо_Па_Жу_Ша".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"D MMMM YYYY, dddd HH:mm"},calendar:{sameDay:"[Бугун соат] LT [да]",nextDay:"[Эртага] LT [да]",nextWeek:"dddd [куни соат] LT [да]",lastDay:"[Кеча соат] LT [да]",lastWeek:"[Утган] dddd [куни соат] LT [да]",sameElse:"L"},relativeTime:{future:"Якин %s ичида",past:"Бир неча %s олдин",s:"фурсат",ss:"%d фурсат",m:"бир дакика",mm:"%d дакика",h:"бир соат",hh:"%d соат",d:"бир кун",dd:"%d кун",M:"бир ой",MM:"%d ой",y:"бир йил",yy:"%d йил"},week:{dow:1,doy:7}})},377647,(e,a,t)=>{e.e,e.r(166540).defineLocale("vi",{months:"tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12".split("_"),monthsShort:"Thg 01_Thg 02_Thg 03_Thg 04_Thg 05_Thg 06_Thg 07_Thg 08_Thg 09_Thg 10_Thg 11_Thg 12".split("_"),monthsParseExact:!0,weekdays:"chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy".split("_"),weekdaysShort:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysMin:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysParseExact:!0,meridiemParse:/sa|ch/i,isPM:function(e){return/^ch$/i.test(e)},meridiem:function(e,a,t){return e<12?t?"sa":"SA":t?"ch":"CH"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [năm] YYYY",LLL:"D MMMM [năm] YYYY HH:mm",LLLL:"dddd, D MMMM [năm] YYYY HH:mm",l:"DD/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[Hôm nay lúc] LT",nextDay:"[Ngày mai lúc] LT",nextWeek:"dddd [tuần tới lúc] LT",lastDay:"[Hôm qua lúc] LT",lastWeek:"dddd [tuần trước lúc] LT",sameElse:"L"},relativeTime:{future:"%s tới",past:"%s trước",s:"vài giây",ss:"%d giây",m:"một phút",mm:"%d phút",h:"một giờ",hh:"%d giờ",d:"một ngày",dd:"%d ngày",w:"một tuần",ww:"%d tuần",M:"một tháng",MM:"%d tháng",y:"một năm",yy:"%d năm"},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:function(e){return e},week:{dow:1,doy:4}})},321194,(e,a,t)=>{e.e,e.r(166540).defineLocale("x-pseudo",{months:"J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér".split("_"),monthsShort:"J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc".split("_"),monthsParseExact:!0,weekdays:"S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý".split("_"),weekdaysShort:"S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát".split("_"),weekdaysMin:"S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[T~ódá~ý át] LT",nextDay:"[T~ómó~rró~w át] LT",nextWeek:"dddd [át] LT",lastDay:"[Ý~ést~érdá~ý át] LT",lastWeek:"[L~ást] dddd [át] LT",sameElse:"L"},relativeTime:{future:"í~ñ %s",past:"%s á~gó",s:"á ~féw ~sécó~ñds",ss:"%d s~écóñ~ds",m:"á ~míñ~úté",mm:"%d m~íñú~tés",h:"á~ñ hó~úr",hh:"%d h~óúrs",d:"á ~dáý",dd:"%d d~áýs",M:"á ~móñ~th",MM:"%d m~óñt~hs",y:"á ~ýéár",yy:"%d ý~éárs"},dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var a=e%10,t=1==~~(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th";return e+t},week:{dow:1,doy:4}})},424446,(e,a,t)=>{e.e,e.r(166540).defineLocale("yo",{months:"Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀".split("_"),monthsShort:"Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀".split("_"),weekdays:"Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta".split("_"),weekdaysShort:"Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá".split("_"),weekdaysMin:"Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Ònì ni] LT",nextDay:"[Ọ̀la ni] LT",nextWeek:"dddd [Ọsẹ̀ tón'bọ] [ni] LT",lastDay:"[Àna ni] LT",lastWeek:"dddd [Ọsẹ̀ tólọ́] [ni] LT",sameElse:"L"},relativeTime:{future:"ní %s",past:"%s kọjá",s:"ìsẹjú aayá die",ss:"aayá %d",m:"ìsẹjú kan",mm:"ìsẹjú %d",h:"wákati kan",hh:"wákati %d",d:"ọjọ́ kan",dd:"ọjọ́ %d",M:"osù kan",MM:"osù %d",y:"ọdún kan",yy:"ọdún %d"},dayOfMonthOrdinalParse:/ọjọ́\s\d{1,2}/,ordinal:"ọjọ́ %d",week:{dow:1,doy:4}})},536655,(e,a,t)=>{e.e,e.r(166540).defineLocale("zh-cn",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"周日_周一_周二_周三_周四_周五_周六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日Ah点mm分",LLLL:"YYYY年M月D日ddddAh点mm分",l:"YYYY/M/D",ll:"YYYY年M月D日",lll:"YYYY年M月D日 HH:mm",llll:"YYYY年M月D日dddd HH:mm"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(e,a){return(12===e&&(e=0),"凌晨"===a||"早上"===a||"上午"===a)?e:"下午"===a||"晚上"===a?e+12:e>=11?e:e+12},meridiem:function(e,a,t){var s=100*e+a;if(s<600)return"凌晨";if(s<900)return"早上";if(s<1130)return"上午";if(s<1230)return"中午";if(s<1800)return"下午";else return"晚上"},calendar:{sameDay:"[今天]LT",nextDay:"[明天]LT",nextWeek:function(e){return e.week()!==this.week()?"[下]dddLT":"[本]dddLT"},lastDay:"[昨天]LT",lastWeek:function(e){return this.week()!==e.week()?"[上]dddLT":"[本]dddLT"},sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(日|月|周)/,ordinal:function(e,a){switch(a){case"d":case"D":case"DDD":return e+"日";case"M":return e+"月";case"w":case"W":return e+"周";default:return e}},relativeTime:{future:"%s后",past:"%s前",s:"几秒",ss:"%d 秒",m:"1 分钟",mm:"%d 分钟",h:"1 小时",hh:"%d 小时",d:"1 天",dd:"%d 天",w:"1 周",ww:"%d 周",M:"1 个月",MM:"%d 个月",y:"1 年",yy:"%d 年"},week:{dow:1,doy:4}})},446820,(e,a,t)=>{e.e,e.r(166540).defineLocale("zh-hk",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"週日_週一_週二_週三_週四_週五_週六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日 HH:mm",LLLL:"YYYY年M月D日dddd HH:mm",l:"YYYY/M/D",ll:"YYYY年M月D日",lll:"YYYY年M月D日 HH:mm",llll:"YYYY年M月D日dddd HH:mm"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(e,a){return(12===e&&(e=0),"凌晨"===a||"早上"===a||"上午"===a)?e:"中午"===a?e>=11?e:e+12:"下午"===a||"晚上"===a?e+12:void 0},meridiem:function(e,a,t){var s=100*e+a;if(s<600)return"凌晨";if(s<900)return"早上";if(s<1200)return"上午";if(1200===s)return"中午";if(s<1800)return"下午";else return"晚上"},calendar:{sameDay:"[今天]LT",nextDay:"[明天]LT",nextWeek:"[下]ddddLT",lastDay:"[昨天]LT",lastWeek:"[上]ddddLT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(日|月|週)/,ordinal:function(e,a){switch(a){case"d":case"D":case"DDD":return e+"日";case"M":return e+"月";case"w":case"W":return e+"週";default:return e}},relativeTime:{future:"%s後",past:"%s前",s:"幾秒",ss:"%d 秒",m:"1 分鐘",mm:"%d 分鐘",h:"1 小時",hh:"%d 小時",d:"1 天",dd:"%d 天",M:"1 個月",MM:"%d 個月",y:"1 年",yy:"%d 年"}})},659396,(e,a,t)=>{e.e,e.r(166540).defineLocale("zh-mo",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"週日_週一_週二_週三_週四_週五_週六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"YYYY年M月D日",LLL:"YYYY年M月D日 HH:mm",LLLL:"YYYY年M月D日dddd HH:mm",l:"D/M/YYYY",ll:"YYYY年M月D日",lll:"YYYY年M月D日 HH:mm",llll:"YYYY年M月D日dddd HH:mm"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(e,a){return(12===e&&(e=0),"凌晨"===a||"早上"===a||"上午"===a)?e:"中午"===a?e>=11?e:e+12:"下午"===a||"晚上"===a?e+12:void 0},meridiem:function(e,a,t){var s=100*e+a;if(s<600)return"凌晨";if(s<900)return"早上";if(s<1130)return"上午";if(s<1230)return"中午";if(s<1800)return"下午";else return"晚上"},calendar:{sameDay:"[今天] LT",nextDay:"[明天] LT",nextWeek:"[下]dddd LT",lastDay:"[昨天] LT",lastWeek:"[上]dddd LT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(日|月|週)/,ordinal:function(e,a){switch(a){case"d":case"D":case"DDD":return e+"日";case"M":return e+"月";case"w":case"W":return e+"週";default:return e}},relativeTime:{future:"%s內",past:"%s前",s:"幾秒",ss:"%d 秒",m:"1 分鐘",mm:"%d 分鐘",h:"1 小時",hh:"%d 小時",d:"1 天",dd:"%d 天",M:"1 個月",MM:"%d 個月",y:"1 年",yy:"%d 年"}})},738643,(e,a,t)=>{e.e,e.r(166540).defineLocale("zh-tw",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"週日_週一_週二_週三_週四_週五_週六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日 HH:mm",LLLL:"YYYY年M月D日dddd HH:mm",l:"YYYY/M/D",ll:"YYYY年M月D日",lll:"YYYY年M月D日 HH:mm",llll:"YYYY年M月D日dddd HH:mm"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(e,a){return(12===e&&(e=0),"凌晨"===a||"早上"===a||"上午"===a)?e:"中午"===a?e>=11?e:e+12:"下午"===a||"晚上"===a?e+12:void 0},meridiem:function(e,a,t){var s=100*e+a;if(s<600)return"凌晨";if(s<900)return"早上";if(s<1130)return"上午";if(s<1230)return"中午";if(s<1800)return"下午";else return"晚上"},calendar:{sameDay:"[今天] LT",nextDay:"[明天] LT",nextWeek:"[下]dddd LT",lastDay:"[昨天] LT",lastWeek:"[上]dddd LT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(日|月|週)/,ordinal:function(e,a){switch(a){case"d":case"D":case"DDD":return e+"日";case"M":return e+"月";case"w":case"W":return e+"週";default:return e}},relativeTime:{future:"%s後",past:"%s前",s:"幾秒",ss:"%d 秒",m:"1 分鐘",mm:"%d 分鐘",h:"1 小時",hh:"%d 小時",d:"1 天",dd:"%d 天",M:"1 個月",MM:"%d 個月",y:"1 年",yy:"%d 年"}})},166540,(e,a,t)=>{e.e,a.exports=function(){"use strict";function t(){return R.apply(null,arguments)}function s(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function n(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function r(e,a){return Object.prototype.hasOwnProperty.call(e,a)}function d(e){var a;if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;for(a in e)if(r(e,a))return!1;return!0}function i(e){return void 0===e}function _(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function o(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function m(e,a){var t,s=[],n=e.length;for(t=0;t>>0;for(a=0;a0)for(t=0;ttypeof console&&console.warn&&console.warn("Deprecation warning: "+e)}function g(e,a){var s=!0;return l(function(){if(null!=t.deprecationHandler&&t.deprecationHandler(null,e),s){var n,d,i,_=[],o=arguments.length;for(d=0;dtypeof Function&&e instanceof Function||"[object Function]"===Object.prototype.toString.call(e)}function H(e,a){var t,s=l({},e);for(t in a)r(a,t)&&(n(e[t])&&n(a[t])?(s[t]={},l(s[t],e[t]),l(s[t],a[t])):null!=a[t]?s[t]=a[t]:delete s[t]);for(t in e)r(e,t)&&!r(a,t)&&n(e[t])&&(s[t]=l({},s[t]));return s}function S(e){null!=e&&this.set(e)}function j(e,a,t){var s=""+Math.abs(e);return(e>=0?t?"+":"":"-")+Math.pow(10,Math.max(0,a-s.length)).toString().substr(1)+s}t.suppressDeprecationWarnings=!1,t.deprecationHandler=null;var x=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,P=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,O={},W={};function A(e,a,t,s){var n=s;"string"==typeof s&&(n=function(){return this[s]()}),e&&(W[e]=n),a&&(W[a[0]]=function(){return j(n.apply(this,arguments),a[1],a[2])}),t&&(W[t]=function(){return this.localeData().ordinal(n.apply(this,arguments),e)})}function E(e,a){return e.isValid()?(O[a=F(a,e.localeData())]=O[a]||function(e){var a,t,s,n=e.match(x);for(t=0,s=n.length;t=0&&P.test(e);)e=e.replace(P,s),P.lastIndex=0,t-=1;return e}var z={D:"date",dates:"date",date:"date",d:"day",days:"day",day:"day",e:"weekday",weekdays:"weekday",weekday:"weekday",E:"isoWeekday",isoweekdays:"isoWeekday",isoweekday:"isoWeekday",DDD:"dayOfYear",dayofyears:"dayOfYear",dayofyear:"dayOfYear",h:"hour",hours:"hour",hour:"hour",ms:"millisecond",milliseconds:"millisecond",millisecond:"millisecond",m:"minute",minutes:"minute",minute:"minute",M:"month",months:"month",month:"month",Q:"quarter",quarters:"quarter",quarter:"quarter",s:"second",seconds:"second",second:"second",gg:"weekYear",weekyears:"weekYear",weekyear:"weekYear",GG:"isoWeekYear",isoweekyears:"isoWeekYear",isoweekyear:"isoWeekYear",w:"week",weeks:"week",week:"week",W:"isoWeek",isoweeks:"isoWeek",isoweek:"isoWeek",y:"year",years:"year",year:"year"};function N(e){return"string"==typeof e?z[e]||z[e.toLowerCase()]:void 0}function J(e){var a,t,s={};for(t in e)r(e,t)&&(a=N(t))&&(s[a]=e[t]);return s}var R,C,I,U={date:9,day:11,weekday:11,isoWeekday:11,dayOfYear:4,hour:13,millisecond:16,minute:14,month:8,quarter:7,second:15,weekYear:1,isoWeekYear:1,week:5,isoWeek:5,year:1},G=Object.keys?Object.keys:function(e){var a,t=[];for(a in e)r(e,a)&&t.push(a);return t},V=/\d/,q=/\d\d/,B=/\d{3}/,K=/\d{4}/,Z=/[+-]?\d{6}/,$=/\d\d?/,Q=/\d\d\d\d?/,X=/\d\d\d\d\d\d?/,ee=/\d{1,3}/,ea=/\d{1,4}/,et=/[+-]?\d{1,6}/,es=/\d+/,en=/[+-]?\d+/,er=/Z|[+-]\d\d:?\d\d/gi,ed=/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,e_=/^[1-9]\d?/,eo=/^([1-9]\d|\d)/;function em(e,a,t){I[e]=b(a)?a:function(e,s){return e&&t?t:a}}function el(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function eu(e){return e<0?Math.ceil(e)||0:Math.floor(e)}function eM(e){var a=+e,t=0;return 0!==a&&isFinite(a)&&(t=eu(a)),t}I={};var eh={};function ec(e,a){var t,s,n=a;for("string"==typeof e&&(e=[e]),_(a)&&(n=function(e,t){t[a]=eM(e)}),s=e.length,t=0;t68?1900:2e3)};var ef=ek("FullYear",!0);function ek(e,a){return function(s){return null!=s?(eD(this,e,s),t.updateOffset(this,a),this):ep(this,e)}}function ep(e,a){if(!e.isValid())return NaN;var t=e._d,s=e._isUTC;switch(a){case"Milliseconds":return s?t.getUTCMilliseconds():t.getMilliseconds();case"Seconds":return s?t.getUTCSeconds():t.getSeconds();case"Minutes":return s?t.getUTCMinutes():t.getMinutes();case"Hours":return s?t.getUTCHours():t.getHours();case"Date":return s?t.getUTCDate():t.getDate();case"Day":return s?t.getUTCDay():t.getDay();case"Month":return s?t.getUTCMonth():t.getMonth();case"FullYear":return s?t.getUTCFullYear():t.getFullYear();default:return NaN}}function eD(e,a,t){var s,n,r,d;if(!(!e.isValid()||isNaN(t))){switch(s=e._d,n=e._isUTC,a){case"Milliseconds":return void(n?s.setUTCMilliseconds(t):s.setMilliseconds(t));case"Seconds":return void(n?s.setUTCSeconds(t):s.setSeconds(t));case"Minutes":return void(n?s.setUTCMinutes(t):s.setMinutes(t));case"Hours":return void(n?s.setUTCHours(t):s.setHours(t));case"Date":return void(n?s.setUTCDate(t):s.setDate(t));case"FullYear":break;default:return}r=e.month(),d=29!==(d=e.date())||1!==r||eY(t)?d:28,n?s.setUTCFullYear(t,r,d):s.setFullYear(t,r,d)}}function eT(e,a){if(isNaN(e)||isNaN(a))return NaN;var t=(a%12+12)%12;return e+=(a-t)/12,1===t?eY(e)?29:28:31-t%7%2}eI=Array.prototype.indexOf?Array.prototype.indexOf:function(e){var a;for(a=0;a=0?isFinite((i=new Date(e+400,a,t,s,n,r,d)).getFullYear())&&i.setFullYear(e):i=new Date(e,a,t,s,n,r,d),i}function ex(e){var a,t;return e<100&&e>=0?(t=Array.prototype.slice.call(arguments),t[0]=e+400,isFinite((a=new Date(Date.UTC.apply(null,t))).getUTCFullYear())&&a.setUTCFullYear(e)):a=new Date(Date.UTC.apply(null,arguments)),a}function eP(e,a,t){var s=7+a-t;return-((7+ex(e,0,s).getUTCDay()-a)%7)+s-1}function eO(e,a,t,s,n){var r,d,i=1+7*(a-1)+(7+t-s)%7+eP(e,s,n);return i<=0?d=ey(r=e-1)+i:i>ey(e)?(r=e+1,d=i-ey(e)):(r=e,d=i),{year:r,dayOfYear:d}}function eW(e,a,t){var s,n,r=eP(e.year(),a,t),d=Math.floor((e.dayOfYear()-r-1)/7)+1;return d<1?s=d+eA(n=e.year()-1,a,t):d>eA(e.year(),a,t)?(s=d-eA(e.year(),a,t),n=e.year()+1):(n=e.year(),s=d),{week:s,year:n}}function eA(e,a,t){var s=eP(e,a,t),n=eP(e+1,a,t);return(ey(e)-s+n)/7}function eE(e,a){return e.slice(a,7).concat(e.slice(0,a))}A("w",["ww",2],"wo","week"),A("W",["WW",2],"Wo","isoWeek"),em("w",$,e_),em("ww",$,q),em("W",$,e_),em("WW",$,q),eL(["w","ww","W","WW"],function(e,a,t,s){a[s.substr(0,1)]=eM(e)}),A("d",0,"do","day"),A("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),A("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),A("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),A("e",0,0,"weekday"),A("E",0,0,"isoWeekday"),em("d",$),em("e",$),em("E",$),em("dd",function(e,a){return a.weekdaysMinRegex(e)}),em("ddd",function(e,a){return a.weekdaysShortRegex(e)}),em("dddd",function(e,a){return a.weekdaysRegex(e)}),eL(["dd","ddd","dddd"],function(e,a,t,s){var n=t._locale.weekdaysParse(e,s,t._strict);null!=n?a.d=n:M(t).invalidWeekday=e}),eL(["d","e","E"],function(e,a,t,s){a[s]=eM(e)});var eF="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_");function ez(e,a,t){var s,n,r,d=e.toLocaleLowerCase();if(!this._weekdaysParse)for(s=0,this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[];s<7;++s)r=u([2e3,1]).day(s),this._minWeekdaysParse[s]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[s]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[s]=this.weekdays(r,"").toLocaleLowerCase();if(t)if("dddd"===a)return -1!==(n=eI.call(this._weekdaysParse,d))?n:null;else if("ddd"===a)return -1!==(n=eI.call(this._shortWeekdaysParse,d))?n:null;else return -1!==(n=eI.call(this._minWeekdaysParse,d))?n:null;return"dddd"===a?-1!==(n=eI.call(this._weekdaysParse,d))||-1!==(n=eI.call(this._shortWeekdaysParse,d))||-1!==(n=eI.call(this._minWeekdaysParse,d))?n:null:"ddd"===a?-1!==(n=eI.call(this._shortWeekdaysParse,d))||-1!==(n=eI.call(this._weekdaysParse,d))||-1!==(n=eI.call(this._minWeekdaysParse,d))?n:null:-1!==(n=eI.call(this._minWeekdaysParse,d))||-1!==(n=eI.call(this._weekdaysParse,d))||-1!==(n=eI.call(this._shortWeekdaysParse,d))?n:null}function eN(){function e(e,a){return a.length-e.length}var a,t,s,n,r,d=[],i=[],_=[],o=[];for(a=0;a<7;a++)t=u([2e3,1]).day(a),s=el(this.weekdaysMin(t,"")),n=el(this.weekdaysShort(t,"")),r=el(this.weekdays(t,"")),d.push(s),i.push(n),_.push(r),o.push(s),o.push(n),o.push(r);d.sort(e),i.sort(e),_.sort(e),o.sort(e),this._weekdaysRegex=RegExp("^("+o.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=RegExp("^("+_.join("|")+")","i"),this._weekdaysShortStrictRegex=RegExp("^("+i.join("|")+")","i"),this._weekdaysMinStrictRegex=RegExp("^("+d.join("|")+")","i")}function eJ(){return this.hours()%12||12}function eR(e,a){A(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),a)})}function eC(e,a){return a._meridiemParse}A("H",["HH",2],0,"hour"),A("h",["hh",2],0,eJ),A("k",["kk",2],0,function(){return this.hours()||24}),A("hmm",0,0,function(){return""+eJ.apply(this)+j(this.minutes(),2)}),A("hmmss",0,0,function(){return""+eJ.apply(this)+j(this.minutes(),2)+j(this.seconds(),2)}),A("Hmm",0,0,function(){return""+this.hours()+j(this.minutes(),2)}),A("Hmmss",0,0,function(){return""+this.hours()+j(this.minutes(),2)+j(this.seconds(),2)}),eR("a",!0),eR("A",!1),em("a",eC),em("A",eC),em("H",$,eo),em("h",$,e_),em("k",$,e_),em("HH",$,q),em("hh",$,q),em("kk",$,q),em("hmm",Q),em("hmmss",X),em("Hmm",Q),em("Hmmss",X),ec(["H","HH"],3),ec(["k","kk"],function(e,a,t){var s=eM(e);a[3]=24===s?0:s}),ec(["a","A"],function(e,a,t){t._isPm=t._locale.isPM(e),t._meridiem=e}),ec(["h","hh"],function(e,a,t){a[3]=eM(e),M(t).bigHour=!0}),ec("hmm",function(e,a,t){var s=e.length-2;a[3]=eM(e.substr(0,s)),a[4]=eM(e.substr(s)),M(t).bigHour=!0}),ec("hmmss",function(e,a,t){var s=e.length-4,n=e.length-2;a[3]=eM(e.substr(0,s)),a[4]=eM(e.substr(s,2)),a[5]=eM(e.substr(n)),M(t).bigHour=!0}),ec("Hmm",function(e,a,t){var s=e.length-2;a[3]=eM(e.substr(0,s)),a[4]=eM(e.substr(s))}),ec("Hmmss",function(e,a,t){var s=e.length-4,n=e.length-2;a[3]=eM(e.substr(0,s)),a[4]=eM(e.substr(s,2)),a[5]=eM(e.substr(n))});var eI,eU,eG=ek("Hours",!0),eV={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:eg,week:{dow:0,doy:6},weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysShort:eF,meridiemParse:/[ap]\.?m?\.?/i},eq={},eB={};function eK(e){return e?e.toLowerCase().replace("_","-"):e}function eZ(t){var s=null;if(void 0===eq[t]&&a&&a.exports&&t&&t.match("^[^/\\\\]*$"))try{s=eU._abbr,e.t,e.f({"./locale/af.js":{id:()=>649222,module:()=>e.r(649222)},"./locale/af":{id:()=>649222,module:()=>e.r(649222)},"./locale/ar-dz.js":{id:()=>50997,module:()=>e.r(50997)},"./locale/ar-dz":{id:()=>50997,module:()=>e.r(50997)},"./locale/ar-kw.js":{id:()=>818181,module:()=>e.r(818181)},"./locale/ar-kw":{id:()=>818181,module:()=>e.r(818181)},"./locale/ar-ly.js":{id:()=>392472,module:()=>e.r(392472)},"./locale/ar-ly":{id:()=>392472,module:()=>e.r(392472)},"./locale/ar-ma.js":{id:()=>48840,module:()=>e.r(48840)},"./locale/ar-ma":{id:()=>48840,module:()=>e.r(48840)},"./locale/ar-ps.js":{id:()=>561871,module:()=>e.r(561871)},"./locale/ar-ps":{id:()=>561871,module:()=>e.r(561871)},"./locale/ar-sa.js":{id:()=>566848,module:()=>e.r(566848)},"./locale/ar-sa":{id:()=>566848,module:()=>e.r(566848)},"./locale/ar-tn.js":{id:()=>892109,module:()=>e.r(892109)},"./locale/ar-tn":{id:()=>892109,module:()=>e.r(892109)},"./locale/ar.js":{id:()=>617209,module:()=>e.r(617209)},"./locale/ar":{id:()=>617209,module:()=>e.r(617209)},"./locale/az.js":{id:()=>627551,module:()=>e.r(627551)},"./locale/az":{id:()=>627551,module:()=>e.r(627551)},"./locale/be.js":{id:()=>416502,module:()=>e.r(416502)},"./locale/be":{id:()=>416502,module:()=>e.r(416502)},"./locale/bg.js":{id:()=>231241,module:()=>e.r(231241)},"./locale/bg":{id:()=>231241,module:()=>e.r(231241)},"./locale/bm.js":{id:()=>909549,module:()=>e.r(909549)},"./locale/bm":{id:()=>909549,module:()=>e.r(909549)},"./locale/bn-bd.js":{id:()=>939441,module:()=>e.r(939441)},"./locale/bn-bd":{id:()=>939441,module:()=>e.r(939441)},"./locale/bn.js":{id:()=>557613,module:()=>e.r(557613)},"./locale/bn":{id:()=>557613,module:()=>e.r(557613)},"./locale/bo.js":{id:()=>447113,module:()=>e.r(447113)},"./locale/bo":{id:()=>447113,module:()=>e.r(447113)},"./locale/br.js":{id:()=>964028,module:()=>e.r(964028)},"./locale/br":{id:()=>964028,module:()=>e.r(964028)},"./locale/bs.js":{id:()=>529619,module:()=>e.r(529619)},"./locale/bs":{id:()=>529619,module:()=>e.r(529619)},"./locale/ca.js":{id:()=>586721,module:()=>e.r(586721)},"./locale/ca":{id:()=>586721,module:()=>e.r(586721)},"./locale/cs.js":{id:()=>586162,module:()=>e.r(586162)},"./locale/cs":{id:()=>586162,module:()=>e.r(586162)},"./locale/cv.js":{id:()=>745143,module:()=>e.r(745143)},"./locale/cv":{id:()=>745143,module:()=>e.r(745143)},"./locale/cy.js":{id:()=>608170,module:()=>e.r(608170)},"./locale/cy":{id:()=>608170,module:()=>e.r(608170)},"./locale/da.js":{id:()=>596740,module:()=>e.r(596740)},"./locale/da":{id:()=>596740,module:()=>e.r(596740)},"./locale/de-at.js":{id:()=>346346,module:()=>e.r(346346)},"./locale/de-at":{id:()=>346346,module:()=>e.r(346346)},"./locale/de-ch.js":{id:()=>700088,module:()=>e.r(700088)},"./locale/de-ch":{id:()=>700088,module:()=>e.r(700088)},"./locale/de.js":{id:()=>486428,module:()=>e.r(486428)},"./locale/de":{id:()=>486428,module:()=>e.r(486428)},"./locale/dv.js":{id:()=>31113,module:()=>e.r(31113)},"./locale/dv":{id:()=>31113,module:()=>e.r(31113)},"./locale/el.js":{id:()=>550841,module:()=>e.r(550841)},"./locale/el":{id:()=>550841,module:()=>e.r(550841)},"./locale/en-au.js":{id:()=>884432,module:()=>e.r(884432)},"./locale/en-au":{id:()=>884432,module:()=>e.r(884432)},"./locale/en-ca.js":{id:()=>448736,module:()=>e.r(448736)},"./locale/en-ca":{id:()=>448736,module:()=>e.r(448736)},"./locale/en-gb.js":{id:()=>828502,module:()=>e.r(828502)},"./locale/en-gb":{id:()=>828502,module:()=>e.r(828502)},"./locale/en-ie.js":{id:()=>421205,module:()=>e.r(421205)},"./locale/en-ie":{id:()=>421205,module:()=>e.r(421205)},"./locale/en-il.js":{id:()=>621015,module:()=>e.r(621015)},"./locale/en-il":{id:()=>621015,module:()=>e.r(621015)},"./locale/en-in.js":{id:()=>162743,module:()=>e.r(162743)},"./locale/en-in":{id:()=>162743,module:()=>e.r(162743)},"./locale/en-nz.js":{id:()=>370661,module:()=>e.r(370661)},"./locale/en-nz":{id:()=>370661,module:()=>e.r(370661)},"./locale/en-sg.js":{id:()=>113826,module:()=>e.r(113826)},"./locale/en-sg":{id:()=>113826,module:()=>e.r(113826)},"./locale/eo.js":{id:()=>633517,module:()=>e.r(633517)},"./locale/eo":{id:()=>633517,module:()=>e.r(633517)},"./locale/es-do.js":{id:()=>954e3,module:()=>e.r(954e3)},"./locale/es-do":{id:()=>954e3,module:()=>e.r(954e3)},"./locale/es-mx.js":{id:()=>120137,module:()=>e.r(120137)},"./locale/es-mx":{id:()=>120137,module:()=>e.r(120137)},"./locale/es-us.js":{id:()=>528845,module:()=>e.r(528845)},"./locale/es-us":{id:()=>528845,module:()=>e.r(528845)},"./locale/es.js":{id:()=>753818,module:()=>e.r(753818)},"./locale/es":{id:()=>753818,module:()=>e.r(753818)},"./locale/et.js":{id:()=>54306,module:()=>e.r(54306)},"./locale/et":{id:()=>54306,module:()=>e.r(54306)},"./locale/eu.js":{id:()=>430810,module:()=>e.r(430810)},"./locale/eu":{id:()=>430810,module:()=>e.r(430810)},"./locale/fa.js":{id:()=>374902,module:()=>e.r(374902)},"./locale/fa":{id:()=>374902,module:()=>e.r(374902)},"./locale/fi.js":{id:()=>412450,module:()=>e.r(412450)},"./locale/fi":{id:()=>412450,module:()=>e.r(412450)},"./locale/fil.js":{id:()=>321329,module:()=>e.r(321329)},"./locale/fil":{id:()=>321329,module:()=>e.r(321329)},"./locale/fo.js":{id:()=>473679,module:()=>e.r(473679)},"./locale/fo":{id:()=>473679,module:()=>e.r(473679)},"./locale/fr-ca.js":{id:()=>874573,module:()=>e.r(874573)},"./locale/fr-ca":{id:()=>874573,module:()=>e.r(874573)},"./locale/fr-ch.js":{id:()=>639994,module:()=>e.r(639994)},"./locale/fr-ch":{id:()=>639994,module:()=>e.r(639994)},"./locale/fr.js":{id:()=>618184,module:()=>e.r(618184)},"./locale/fr":{id:()=>618184,module:()=>e.r(618184)},"./locale/fy.js":{id:()=>439552,module:()=>e.r(439552)},"./locale/fy":{id:()=>439552,module:()=>e.r(439552)},"./locale/ga.js":{id:()=>866284,module:()=>e.r(866284)},"./locale/ga":{id:()=>866284,module:()=>e.r(866284)},"./locale/gd.js":{id:()=>810136,module:()=>e.r(810136)},"./locale/gd":{id:()=>810136,module:()=>e.r(810136)},"./locale/gl.js":{id:()=>703131,module:()=>e.r(703131)},"./locale/gl":{id:()=>703131,module:()=>e.r(703131)},"./locale/gom-deva.js":{id:()=>56861,module:()=>e.r(56861)},"./locale/gom-deva":{id:()=>56861,module:()=>e.r(56861)},"./locale/gom-latn.js":{id:()=>227159,module:()=>e.r(227159)},"./locale/gom-latn":{id:()=>227159,module:()=>e.r(227159)},"./locale/gu.js":{id:()=>277496,module:()=>e.r(277496)},"./locale/gu":{id:()=>277496,module:()=>e.r(277496)},"./locale/he.js":{id:()=>796669,module:()=>e.r(796669)},"./locale/he":{id:()=>796669,module:()=>e.r(796669)},"./locale/hi.js":{id:()=>725949,module:()=>e.r(725949)},"./locale/hi":{id:()=>725949,module:()=>e.r(725949)},"./locale/hr.js":{id:()=>863164,module:()=>e.r(863164)},"./locale/hr":{id:()=>863164,module:()=>e.r(863164)},"./locale/hu.js":{id:()=>491161,module:()=>e.r(491161)},"./locale/hu":{id:()=>491161,module:()=>e.r(491161)},"./locale/hy-am.js":{id:()=>122472,module:()=>e.r(122472)},"./locale/hy-am":{id:()=>122472,module:()=>e.r(122472)},"./locale/id.js":{id:()=>261476,module:()=>e.r(261476)},"./locale/id":{id:()=>261476,module:()=>e.r(261476)},"./locale/is.js":{id:()=>595500,module:()=>e.r(595500)},"./locale/is":{id:()=>595500,module:()=>e.r(595500)},"./locale/it-ch.js":{id:()=>351426,module:()=>e.r(351426)},"./locale/it-ch":{id:()=>351426,module:()=>e.r(351426)},"./locale/it.js":{id:()=>988869,module:()=>e.r(988869)},"./locale/it":{id:()=>988869,module:()=>e.r(988869)},"./locale/ja.js":{id:()=>622116,module:()=>e.r(622116)},"./locale/ja":{id:()=>622116,module:()=>e.r(622116)},"./locale/jv.js":{id:()=>874383,module:()=>e.r(874383)},"./locale/jv":{id:()=>874383,module:()=>e.r(874383)},"./locale/ka.js":{id:()=>11842,module:()=>e.r(11842)},"./locale/ka":{id:()=>11842,module:()=>e.r(11842)},"./locale/kk.js":{id:()=>613970,module:()=>e.r(613970)},"./locale/kk":{id:()=>613970,module:()=>e.r(613970)},"./locale/km.js":{id:()=>621412,module:()=>e.r(621412)},"./locale/km":{id:()=>621412,module:()=>e.r(621412)},"./locale/kn.js":{id:()=>978630,module:()=>e.r(978630)},"./locale/kn":{id:()=>978630,module:()=>e.r(978630)},"./locale/ko.js":{id:()=>73893,module:()=>e.r(73893)},"./locale/ko":{id:()=>73893,module:()=>e.r(73893)},"./locale/ku-kmr.js":{id:()=>531990,module:()=>e.r(531990)},"./locale/ku-kmr":{id:()=>531990,module:()=>e.r(531990)},"./locale/ku.js":{id:()=>327383,module:()=>e.r(327383)},"./locale/ku":{id:()=>327383,module:()=>e.r(327383)},"./locale/ky.js":{id:()=>913233,module:()=>e.r(913233)},"./locale/ky":{id:()=>913233,module:()=>e.r(913233)},"./locale/lb.js":{id:()=>535403,module:()=>e.r(535403)},"./locale/lb":{id:()=>535403,module:()=>e.r(535403)},"./locale/lo.js":{id:()=>17373,module:()=>e.r(17373)},"./locale/lo":{id:()=>17373,module:()=>e.r(17373)},"./locale/lt.js":{id:()=>409583,module:()=>e.r(409583)},"./locale/lt":{id:()=>409583,module:()=>e.r(409583)},"./locale/lv.js":{id:()=>407912,module:()=>e.r(407912)},"./locale/lv":{id:()=>407912,module:()=>e.r(407912)},"./locale/me.js":{id:()=>545267,module:()=>e.r(545267)},"./locale/me":{id:()=>545267,module:()=>e.r(545267)},"./locale/mi.js":{id:()=>961705,module:()=>e.r(961705)},"./locale/mi":{id:()=>961705,module:()=>e.r(961705)},"./locale/mk.js":{id:()=>354402,module:()=>e.r(354402)},"./locale/mk":{id:()=>354402,module:()=>e.r(354402)},"./locale/ml.js":{id:()=>624201,module:()=>e.r(624201)},"./locale/ml":{id:()=>624201,module:()=>e.r(624201)},"./locale/mn.js":{id:()=>969668,module:()=>e.r(969668)},"./locale/mn":{id:()=>969668,module:()=>e.r(969668)},"./locale/mr.js":{id:()=>417366,module:()=>e.r(417366)},"./locale/mr":{id:()=>417366,module:()=>e.r(417366)},"./locale/ms-my.js":{id:()=>538640,module:()=>e.r(538640)},"./locale/ms-my":{id:()=>538640,module:()=>e.r(538640)},"./locale/ms.js":{id:()=>367856,module:()=>e.r(367856)},"./locale/ms":{id:()=>367856,module:()=>e.r(367856)},"./locale/mt.js":{id:()=>157692,module:()=>e.r(157692)},"./locale/mt":{id:()=>157692,module:()=>e.r(157692)},"./locale/my.js":{id:()=>222310,module:()=>e.r(222310)},"./locale/my":{id:()=>222310,module:()=>e.r(222310)},"./locale/nb.js":{id:()=>441867,module:()=>e.r(441867)},"./locale/nb":{id:()=>441867,module:()=>e.r(441867)},"./locale/ne.js":{id:()=>899103,module:()=>e.r(899103)},"./locale/ne":{id:()=>899103,module:()=>e.r(899103)},"./locale/nl-be.js":{id:()=>775136,module:()=>e.r(775136)},"./locale/nl-be":{id:()=>775136,module:()=>e.r(775136)},"./locale/nl.js":{id:()=>618264,module:()=>e.r(618264)},"./locale/nl":{id:()=>618264,module:()=>e.r(618264)},"./locale/nn.js":{id:()=>876976,module:()=>e.r(876976)},"./locale/nn":{id:()=>876976,module:()=>e.r(876976)},"./locale/oc-lnc.js":{id:()=>225313,module:()=>e.r(225313)},"./locale/oc-lnc":{id:()=>225313,module:()=>e.r(225313)},"./locale/pa-in.js":{id:()=>368431,module:()=>e.r(368431)},"./locale/pa-in":{id:()=>368431,module:()=>e.r(368431)},"./locale/pl.js":{id:()=>657968,module:()=>e.r(657968)},"./locale/pl":{id:()=>657968,module:()=>e.r(657968)},"./locale/pt-br.js":{id:()=>736919,module:()=>e.r(736919)},"./locale/pt-br":{id:()=>736919,module:()=>e.r(736919)},"./locale/pt.js":{id:()=>493062,module:()=>e.r(493062)},"./locale/pt":{id:()=>493062,module:()=>e.r(493062)},"./locale/ro.js":{id:()=>869377,module:()=>e.r(869377)},"./locale/ro":{id:()=>869377,module:()=>e.r(869377)},"./locale/ru.js":{id:()=>498262,module:()=>e.r(498262)},"./locale/ru":{id:()=>498262,module:()=>e.r(498262)},"./locale/sd.js":{id:()=>137750,module:()=>e.r(137750)},"./locale/sd":{id:()=>137750,module:()=>e.r(137750)},"./locale/se.js":{id:()=>455308,module:()=>e.r(455308)},"./locale/se":{id:()=>455308,module:()=>e.r(455308)},"./locale/si.js":{id:()=>303364,module:()=>e.r(303364)},"./locale/si":{id:()=>303364,module:()=>e.r(303364)},"./locale/sk.js":{id:()=>195013,module:()=>e.r(195013)},"./locale/sk":{id:()=>195013,module:()=>e.r(195013)},"./locale/sl.js":{id:()=>575550,module:()=>e.r(575550)},"./locale/sl":{id:()=>575550,module:()=>e.r(575550)},"./locale/sq.js":{id:()=>813013,module:()=>e.r(813013)},"./locale/sq":{id:()=>813013,module:()=>e.r(813013)},"./locale/sr-cyrl.js":{id:()=>423039,module:()=>e.r(423039)},"./locale/sr-cyrl":{id:()=>423039,module:()=>e.r(423039)},"./locale/sr.js":{id:()=>654301,module:()=>e.r(654301)},"./locale/sr":{id:()=>654301,module:()=>e.r(654301)},"./locale/ss.js":{id:()=>492305,module:()=>e.r(492305)},"./locale/ss":{id:()=>492305,module:()=>e.r(492305)},"./locale/sv.js":{id:()=>937057,module:()=>e.r(937057)},"./locale/sv":{id:()=>937057,module:()=>e.r(937057)},"./locale/sw.js":{id:()=>771953,module:()=>e.r(771953)},"./locale/sw":{id:()=>771953,module:()=>e.r(771953)},"./locale/ta.js":{id:()=>271953,module:()=>e.r(271953)},"./locale/ta":{id:()=>271953,module:()=>e.r(271953)},"./locale/te.js":{id:()=>749731,module:()=>e.r(749731)},"./locale/te":{id:()=>749731,module:()=>e.r(749731)},"./locale/tet.js":{id:()=>165002,module:()=>e.r(165002)},"./locale/tet":{id:()=>165002,module:()=>e.r(165002)},"./locale/tg.js":{id:()=>580104,module:()=>e.r(580104)},"./locale/tg":{id:()=>580104,module:()=>e.r(580104)},"./locale/th.js":{id:()=>768313,module:()=>e.r(768313)},"./locale/th":{id:()=>768313,module:()=>e.r(768313)},"./locale/tk.js":{id:()=>291616,module:()=>e.r(291616)},"./locale/tk":{id:()=>291616,module:()=>e.r(291616)},"./locale/tl-ph.js":{id:()=>317895,module:()=>e.r(317895)},"./locale/tl-ph":{id:()=>317895,module:()=>e.r(317895)},"./locale/tlh.js":{id:()=>955799,module:()=>e.r(955799)},"./locale/tlh":{id:()=>955799,module:()=>e.r(955799)},"./locale/tr.js":{id:()=>515252,module:()=>e.r(515252)},"./locale/tr":{id:()=>515252,module:()=>e.r(515252)},"./locale/tzl.js":{id:()=>568087,module:()=>e.r(568087)},"./locale/tzl":{id:()=>568087,module:()=>e.r(568087)},"./locale/tzm-latn.js":{id:()=>542954,module:()=>e.r(542954)},"./locale/tzm-latn":{id:()=>542954,module:()=>e.r(542954)},"./locale/tzm.js":{id:()=>267123,module:()=>e.r(267123)},"./locale/tzm":{id:()=>267123,module:()=>e.r(267123)},"./locale/ug-cn.js":{id:()=>468227,module:()=>e.r(468227)},"./locale/ug-cn":{id:()=>468227,module:()=>e.r(468227)},"./locale/uk.js":{id:()=>557418,module:()=>e.r(557418)},"./locale/uk":{id:()=>557418,module:()=>e.r(557418)},"./locale/ur.js":{id:()=>721396,module:()=>e.r(721396)},"./locale/ur":{id:()=>721396,module:()=>e.r(721396)},"./locale/uz-latn.js":{id:()=>647658,module:()=>e.r(647658)},"./locale/uz-latn":{id:()=>647658,module:()=>e.r(647658)},"./locale/uz.js":{id:()=>298424,module:()=>e.r(298424)},"./locale/uz":{id:()=>298424,module:()=>e.r(298424)},"./locale/vi.js":{id:()=>377647,module:()=>e.r(377647)},"./locale/vi":{id:()=>377647,module:()=>e.r(377647)},"./locale/x-pseudo.js":{id:()=>321194,module:()=>e.r(321194)},"./locale/x-pseudo":{id:()=>321194,module:()=>e.r(321194)},"./locale/yo.js":{id:()=>424446,module:()=>e.r(424446)},"./locale/yo":{id:()=>424446,module:()=>e.r(424446)},"./locale/zh-cn.js":{id:()=>536655,module:()=>e.r(536655)},"./locale/zh-cn":{id:()=>536655,module:()=>e.r(536655)},"./locale/zh-hk.js":{id:()=>446820,module:()=>e.r(446820)},"./locale/zh-hk":{id:()=>446820,module:()=>e.r(446820)},"./locale/zh-mo.js":{id:()=>659396,module:()=>e.r(659396)},"./locale/zh-mo":{id:()=>659396,module:()=>e.r(659396)},"./locale/zh-tw.js":{id:()=>738643,module:()=>e.r(738643)},"./locale/zh-tw":{id:()=>738643,module:()=>e.r(738643)}})("./locale/"+t),e$(s)}catch(e){eq[t]=null}return eq[t]}function e$(e,a){var t;return e&&((t=i(a)?eX(e):eQ(e,a))?eU=t:"u">typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),eU._abbr}function eQ(e,a){if(null===a)return delete eq[e],null;var t,s=eV;if(a.abbr=e,null!=eq[e])v("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=eq[e]._config;else if(null!=a.parentLocale)if(null!=eq[a.parentLocale])s=eq[a.parentLocale]._config;else{if(null==(t=eZ(a.parentLocale)))return eB[a.parentLocale]||(eB[a.parentLocale]=[]),eB[a.parentLocale].push({name:e,config:a}),null;s=t._config}return eq[e]=new S(H(s,a)),eB[e]&&eB[e].forEach(function(e){eQ(e.name,e.config)}),e$(e),eq[e]}function eX(e){var a;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return eU;if(!s(e)){if(a=eZ(e))return a;e=[e]}return function(e){for(var a,t,s,n,r=0;r0;){if(s=eZ(n.slice(0,a).join("-")))return s;if(t&&t.length>=a&&function(e,a){var t,s=Math.min(e.length,a.length);for(t=0;t=a-1)break;a--}r++}return eU}(e)}function e1(e){var a,t=e._a;return t&&-2===M(e).overflow&&(a=t[1]<0||t[1]>11?1:t[2]<1||t[2]>eT(t[0],t[1])?2:t[3]<0||t[3]>24||24===t[3]&&(0!==t[4]||0!==t[5]||0!==t[6])?3:t[4]<0||t[4]>59?4:t[5]<0||t[5]>59?5:t[6]<0||t[6]>999?6:-1,M(e)._overflowDayOfYear&&(a<0||a>2)&&(a=2),M(e)._overflowWeeks&&-1===a&&(a=7),M(e)._overflowWeekday&&-1===a&&(a=8),M(e).overflow=a),e}var e0=/^\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)?)?$/,e2=/^\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)?)?$/,e6=/Z|[+-]\d\d(?::?\d\d)?/,e4=[["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]],e3=[["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/]],e5=/^\/?Date\((-?\d+)/i,e7=/^(?:(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}))$/,e9={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function e8(e){var a,t,s,n,r,d,i=e._i,_=e0.exec(i)||e2.exec(i),o=e4.length,m=e3.length;if(_){for(a=0,M(e).iso=!0,t=o;a7)&&(m=!0)):(i=a._locale._week.dow,_=a._locale._week.doy,l=eW(ad(),i,_),n=aa(s.gg,a._a[0],l.year),r=aa(s.w,l.week),null!=s.d?((d=s.d)<0||d>6)&&(m=!0):null!=s.e?(d=s.e+i,(s.e<0||s.e>6)&&(m=!0)):d=i),r<1||r>eA(n,i,_)?M(a)._overflowWeeks=!0:null!=m?M(a)._overflowWeekday=!0:(o=eO(n,r,d,i,_),a._a[0]=o.year,a._dayOfYear=o.dayOfYear)),null!=e._dayOfYear&&(y=aa(e._a[0],L[0]),(e._dayOfYear>ey(y)||0===e._dayOfYear)&&(M(e)._overflowDayOfYear=!0),c=ex(y,0,e._dayOfYear),e._a[1]=c.getUTCMonth(),e._a[2]=c.getUTCDate()),h=0;h<3&&null==e._a[h];++h)e._a[h]=f[h]=L[h];for(;h<7;h++)e._a[h]=f[h]=null==e._a[h]?+(2===h):e._a[h];24===e._a[3]&&0===e._a[4]&&0===e._a[5]&&0===e._a[6]&&(e._nextDay=!0,e._a[3]=0),e._d=(e._useUTC?ex:ej).apply(null,f),Y=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[3]=24),e._w&&void 0!==e._w.d&&e._w.d!==Y&&(M(e).weekdayMismatch=!0)}}function as(e){if(e._f===t.ISO_8601)return void e8(e);if(e._f===t.RFC_2822)return void ae(e);e._a=[],M(e).empty=!0;var a,s,n,d,i,_,o,m,l,u,h,c=""+e._i,L=c.length,Y=0;for(i=0,h=(o=F(e._f,e._locale).match(x)||[]).length;i0&&M(e).unusedInput.push(l),c=c.slice(c.indexOf(_)+_.length),Y+=_.length),W[m])_?M(e).empty=!1:M(e).unusedTokens.push(m),null!=_&&r(eh,m)&&eh[m](_,e._a,e,m);else e._strict&&!_&&M(e).unusedTokens.push(m);M(e).charsLeftOver=L-Y,c.length>0&&M(e).unusedInput.push(c),e._a[3]<=12&&!0===M(e).bigHour&&e._a[3]>0&&(M(e).bigHour=void 0),M(e).parsedDateParts=e._a.slice(0),M(e).meridiem=e._meridiem,e._a[3]=(a=e._locale,s=e._a[3],null==(n=e._meridiem)?s:null!=a.meridiemHour?a.meridiemHour(s,n):(null!=a.isPM&&((d=a.isPM(n))&&s<12&&(s+=12),d||12!==s||(s=0)),s)),null!==(u=M(e).era)&&(e._a[0]=e._locale.erasConvertYear(u,e._a[0])),at(e),e1(e)}function an(e){var a=e._i,r=e._f;return(e._locale=e._locale||eX(e._l),null===a||void 0===r&&""===a)?c({nullInput:!0}):("string"==typeof a&&(e._i=a=e._locale.preparse(a)),D(a))?new p(e1(a)):(o(a)?e._d=a:s(r)?!function(e){var a,t,s,n,r,d,i=!1,_=e._f.length;if(0===_){M(e).invalidFormat=!0,e._d=new Date(NaN);return}for(n=0;n<_;n++)r=0,d=!1,a=k({},e),null!=e._useUTC&&(a._useUTC=e._useUTC),a._f=e._f[n],as(a),h(a)&&(d=!0),r+=M(a).charsLeftOver,r+=10*M(a).unusedTokens.length,M(a).score=r,i?rthis?this:e:c()});function ao(e,a){var t,n;if(1===a.length&&s(a[0])&&(a=a[0]),!a.length)return ad();for(n=1,t=a[0];n=0?new Date(e+400,a,t)-126227808e5:new Date(e,a,t).valueOf()}function aA(e,a,t){return e<100&&e>=0?Date.UTC(e+400,a,t)-126227808e5:Date.UTC(e,a,t)}function aE(e,a){return a.erasAbbrRegex(e)}function aF(){var e,a,t,s,n,r=[],d=[],i=[],_=[],o=this.eras();for(e=0,a=o.length;e(r=eA(e,s,n))&&(a=r),aJ.call(this,e,a,t,s,n))}function aJ(e,a,t,s,n){var r=eO(e,a,t,s,n),d=ex(r.year,0,r.dayOfYear);return this.year(d.getUTCFullYear()),this.month(d.getUTCMonth()),this.date(d.getUTCDate()),this}A("N",0,0,"eraAbbr"),A("NN",0,0,"eraAbbr"),A("NNN",0,0,"eraAbbr"),A("NNNN",0,0,"eraName"),A("NNNNN",0,0,"eraNarrow"),A("y",["y",1],"yo","eraYear"),A("y",["yy",2],0,"eraYear"),A("y",["yyy",3],0,"eraYear"),A("y",["yyyy",4],0,"eraYear"),em("N",aE),em("NN",aE),em("NNN",aE),em("NNNN",function(e,a){return a.erasNameRegex(e)}),em("NNNNN",function(e,a){return a.erasNarrowRegex(e)}),ec(["N","NN","NNN","NNNN","NNNNN"],function(e,a,t,s){var n=t._locale.erasParse(e,s,t._strict);n?M(t).era=n:M(t).invalidEra=e}),em("y",es),em("yy",es),em("yyy",es),em("yyyy",es),em("yo",function(e,a){return a._eraYearOrdinalRegex||es}),ec(["y","yy","yyy","yyyy"],0),ec(["yo"],function(e,a,t,s){var n;t._locale._eraYearOrdinalRegex&&(n=e.match(t._locale._eraYearOrdinalRegex)),t._locale.eraYearOrdinalParse?a[0]=t._locale.eraYearOrdinalParse(e,n):a[0]=parseInt(e,10)}),A(0,["gg",2],0,function(){return this.weekYear()%100}),A(0,["GG",2],0,function(){return this.isoWeekYear()%100}),az("gggg","weekYear"),az("ggggg","weekYear"),az("GGGG","isoWeekYear"),az("GGGGG","isoWeekYear"),em("G",en),em("g",en),em("GG",$,q),em("gg",$,q),em("GGGG",ea,K),em("gggg",ea,K),em("GGGGG",et,Z),em("ggggg",et,Z),eL(["gggg","ggggg","GGGG","GGGGG"],function(e,a,t,s){a[s.substr(0,2)]=eM(e)}),eL(["gg","GG"],function(e,a,s,n){a[n]=t.parseTwoDigitYear(e)}),A("Q",0,"Qo","quarter"),em("Q",V),ec("Q",function(e,a){a[1]=(eM(e)-1)*3}),A("D",["DD",2],"Do","date"),em("D",$,e_),em("DD",$,q),em("Do",function(e,a){return e?a._dayOfMonthOrdinalParse||a._ordinalParse:a._dayOfMonthOrdinalParseLenient}),ec(["D","DD"],2),ec("Do",function(e,a){a[2]=eM(e.match($)[0])});var aR=ek("Date",!0);A("DDD",["DDDD",3],"DDDo","dayOfYear"),em("DDD",ee),em("DDDD",B),ec(["DDD","DDDD"],function(e,a,t){t._dayOfYear=eM(e)}),A("m",["mm",2],0,"minute"),em("m",$,eo),em("mm",$,q),ec(["m","mm"],4);var aC=ek("Minutes",!1);A("s",["ss",2],0,"second"),em("s",$,eo),em("ss",$,q),ec(["s","ss"],5);var aI=ek("Seconds",!1);for(A("S",0,0,function(){return~~(this.millisecond()/100)}),A(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),A(0,["SSS",3],0,"millisecond"),A(0,["SSSS",4],0,function(){return 10*this.millisecond()}),A(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),A(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),A(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),A(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),A(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),em("S",ee,V),em("SS",ee,q),em("SSS",ee,B),L="SSSS";L.length<=9;L+="S")em(L,es);function aU(e,a){a[6]=eM(("0."+e)*1e3)}for(L="S";L.length<=9;L+="S")ec(L,aU);Y=ek("Milliseconds",!1),A("z",0,0,"zoneAbbr"),A("zz",0,0,"zoneName");var aG=p.prototype;function aV(e){return e}aG.add=ab,aG.calendar=function(e,a){if(1==arguments.length)if(arguments[0]){var i,m,l,u;if(i=arguments[0],D(i)||o(i)||aS(i)||_(i)||(l=s(m=i),u=!1,l&&(u=0===m.filter(function(e){return!_(e)&&aS(m)}).length),l&&u)||function(e){var a,t,s=n(e)&&!d(e),i=!1,_=["years","year","y","months","month","M","days","day","d","dates","date","D","hours","hour","h","minutes","minute","m","seconds","second","s","milliseconds","millisecond","ms"],o=_.length;for(a=0;at.valueOf():t.valueOf()t.year()||t.year()>9999)return E(t,a?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ");if(b(Date.prototype.toISOString))if(a)return this.toDate().toISOString();else return new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",E(t,"Z"));return E(t,a?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},aG.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e,a,t,s="moment",n="";return this.isLocal()||(s=0===this.utcOffset()?"moment.utc":"moment.parseZone",n="Z"),e="["+s+'("]',a=0<=this.year()&&9999>=this.year()?"YYYY":"YYYYYY",t=n+'[")]',this.format(e+a+"-MM-DD[T]HH:mm:ss.SSS"+t)},"u">typeof Symbol&&null!=Symbol.for&&(aG[Symbol.for("nodejs.util.inspect.custom")]=function(){return"Moment<"+this.format()+">"}),aG.toJSON=function(){return this.isValid()?this.toISOString():null},aG.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},aG.unix=function(){return Math.floor(this.valueOf()/1e3)},aG.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},aG.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},aG.eraName=function(){var e,a,t,s=this.localeData().eras();for(e=0,a=s.length;eMath.abs(e)&&!s&&(e*=60);return!this._isUTC&&a&&(n=ay(this)),this._offset=e,this._isUTC=!0,null!=n&&this.add(n,"m"),r!==e&&(!a||this._changeInProgress?av(this,aD(e-r,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,t.updateOffset(this,!0),this._changeInProgress=null)),this},aG.utc=function(e){return this.utcOffset(0,e)},aG.local=function(e){return this._isUTC&&(this.utcOffset(0,e),this._isUTC=!1,e&&this.subtract(ay(this),"m")),this},aG.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var e=aL(er,this._i);null!=e?this.utcOffset(e):this.utcOffset(0,!0)}return this},aG.hasAlignedHourOffset=function(e){return!!this.isValid()&&(e=e?ad(e).utcOffset():0,(this.utcOffset()-e)%60==0)},aG.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},aG.isLocal=function(){return!!this.isValid()&&!this._isUTC},aG.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},aG.isUtc=af,aG.isUTC=af,aG.zoneAbbr=function(){return this._isUTC?"UTC":""},aG.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},aG.dates=g("dates accessor is deprecated. Use date instead.",aR),aG.months=g("months accessor is deprecated. Use month instead",eH),aG.years=g("years accessor is deprecated. Use year instead",ef),aG.zone=g("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,a){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,a),this):-this.utcOffset()}),aG.isDSTShifted=g("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!i(this._isDSTShifted))return this._isDSTShifted;var e,a={};return k(a,this),(a=an(a))._a?(e=a._isUTC?u(a._a):ad(a._a),this._isDSTShifted=this.isValid()&&function(e,a){var t,s=Math.min(e.length,a.length),n=Math.abs(e.length-a.length),r=0;for(t=0;t0):this._isDSTShifted=!1,this._isDSTShifted});var aq=S.prototype;function aB(e,a,t,s){var n=eX(),r=u().set(s,a);return n[t](r,e)}function aK(e,a,t){if(_(e)&&(a=e,e=void 0),e=e||"",null!=a)return aB(e,a,t,"month");var s,n=[];for(s=0;s<12;s++)n[s]=aB(e,s,t,"month");return n}function aZ(e,a,t,s){"boolean"==typeof e||(t=a=e,e=!1),_(a)&&(t=a,a=void 0),a=a||"";var n,r=eX(),d=e?r._week.dow:0,i=[];if(null!=t)return aB(a,(t+d)%7,s,"day");for(n=0;n<7;n++)i[n]=aB(a,(n+d)%7,s,"day");return i}aq.calendar=function(e,a,t){var s=this._calendar[e]||this._calendar.sameElse;return b(s)?s.call(a,t):s},aq.longDateFormat=function(e){var a=this._longDateFormat[e],t=this._longDateFormat[e.toUpperCase()];return a||!t?a:(this._longDateFormat[e]=t.match(x).map(function(e){return"MMMM"===e||"MM"===e||"DD"===e||"dddd"===e?e.slice(1):e}).join(""),this._longDateFormat[e])},aq.invalidDate=function(){return this._invalidDate},aq.ordinal=function(e){return this._ordinal.replace("%d",e)},aq.preparse=aV,aq.postformat=aV,aq.relativeTime=function(e,a,t,s){var n=this._relativeTime[t];return b(n)?n(e,a,t,s):n.replace(/%d/i,e)},aq.pastFuture=function(e,a){var t=this._relativeTime[e>0?"future":"past"];return b(t)?t(a):t.replace(/%s/i,a)},aq.set=function(e){var a,t;for(t in e)r(e,t)&&(b(a=e[t])?this[t]=a:this["_"+t]=a);this._config=e,this._dayOfMonthOrdinalParseLenient=RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},aq.eras=function(e,a){var s,n,r,d=this._eras||eX("en")._eras;for(s=0,n=d.length;s=0)return _[s]},aq.erasConvertYear=function(e,a){var s=e.since<=e.until?1:-1;return void 0===a?t(e.since).year():t(e.since).year()+(a-e.offset)*s},aq.erasAbbrRegex=function(e){return r(this,"_erasAbbrRegex")||aF.call(this),e?this._erasAbbrRegex:this._erasRegex},aq.erasNameRegex=function(e){return r(this,"_erasNameRegex")||aF.call(this),e?this._erasNameRegex:this._erasRegex},aq.erasNarrowRegex=function(e){return r(this,"_erasNarrowRegex")||aF.call(this),e?this._erasNarrowRegex:this._erasRegex},aq.months=function(e,a){return e?s(this._months)?this._months[e.month()]:this._months[(this._months.isFormat||ew).test(a)?"format":"standalone"][e.month()]:s(this._months)?this._months:this._months.standalone},aq.monthsShort=function(e,a){return e?s(this._monthsShort)?this._monthsShort[e.month()]:this._monthsShort[ew.test(a)?"format":"standalone"][e.month()]:s(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},aq.monthsParse=function(e,a,t){var s,n,r;if(this._monthsParseExact)return ev.call(this,e,a,t);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),s=0;s<12;s++){if(n=u([2e3,s]),t&&!this._longMonthsParse[s]&&(this._longMonthsParse[s]=RegExp("^"+this.months(n,"").replace(".","")+"$","i"),this._shortMonthsParse[s]=RegExp("^"+this.monthsShort(n,"").replace(".","")+"$","i")),t||this._monthsParse[s]||(r="^"+this.months(n,"")+"|^"+this.monthsShort(n,""),this._monthsParse[s]=RegExp(r.replace(".",""),"i")),t&&"MMMM"===a&&this._longMonthsParse[s].test(e))return s;if(t&&"MMM"===a&&this._shortMonthsParse[s].test(e))return s;if(!t&&this._monthsParse[s].test(e))return s}},aq.monthsRegex=function(e){return this._monthsParseExact?(r(this,"_monthsRegex")||eS.call(this),e)?this._monthsStrictRegex:this._monthsRegex:(r(this,"_monthsRegex")||(this._monthsRegex=ei),this._monthsStrictRegex&&e?this._monthsStrictRegex:this._monthsRegex)},aq.monthsShortRegex=function(e){return this._monthsParseExact?(r(this,"_monthsRegex")||eS.call(this),e)?this._monthsShortStrictRegex:this._monthsShortRegex:(r(this,"_monthsShortRegex")||(this._monthsShortRegex=ei),this._monthsShortStrictRegex&&e?this._monthsShortStrictRegex:this._monthsShortRegex)},aq.week=function(e){return eW(e,this._week.dow,this._week.doy).week},aq.firstDayOfYear=function(){return this._week.doy},aq.firstDayOfWeek=function(){return this._week.dow},aq.weekdays=function(e,a){var t=s(this._weekdays)?this._weekdays:this._weekdays[e&&!0!==e&&this._weekdays.isFormat.test(a)?"format":"standalone"];return!0===e?eE(t,this._week.dow):e?t[e.day()]:t},aq.weekdaysMin=function(e){return!0===e?eE(this._weekdaysMin,this._week.dow):e?this._weekdaysMin[e.day()]:this._weekdaysMin},aq.weekdaysShort=function(e){return!0===e?eE(this._weekdaysShort,this._week.dow):e?this._weekdaysShort[e.day()]:this._weekdaysShort},aq.weekdaysParse=function(e,a,t){var s,n,r;if(this._weekdaysParseExact)return ez.call(this,e,a,t);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),s=0;s<7;s++){if(n=u([2e3,1]).day(s),t&&!this._fullWeekdaysParse[s]&&(this._fullWeekdaysParse[s]=RegExp("^"+this.weekdays(n,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[s]=RegExp("^"+this.weekdaysShort(n,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[s]=RegExp("^"+this.weekdaysMin(n,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[s]||(r="^"+this.weekdays(n,"")+"|^"+this.weekdaysShort(n,"")+"|^"+this.weekdaysMin(n,""),this._weekdaysParse[s]=RegExp(r.replace(".",""),"i")),t&&"dddd"===a&&this._fullWeekdaysParse[s].test(e))return s;if(t&&"ddd"===a&&this._shortWeekdaysParse[s].test(e))return s;if(t&&"dd"===a&&this._minWeekdaysParse[s].test(e))return s;else if(!t&&this._weekdaysParse[s].test(e))return s}},aq.weekdaysRegex=function(e){return this._weekdaysParseExact?(r(this,"_weekdaysRegex")||eN.call(this),e)?this._weekdaysStrictRegex:this._weekdaysRegex:(r(this,"_weekdaysRegex")||(this._weekdaysRegex=ei),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)},aq.weekdaysShortRegex=function(e){return this._weekdaysParseExact?(r(this,"_weekdaysRegex")||eN.call(this),e)?this._weekdaysShortStrictRegex:this._weekdaysShortRegex:(r(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=ei),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},aq.weekdaysMinRegex=function(e){return this._weekdaysParseExact?(r(this,"_weekdaysRegex")||eN.call(this),e)?this._weekdaysMinStrictRegex:this._weekdaysMinRegex:(r(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=ei),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},aq.isPM=function(e){return"p"===(e+"").toLowerCase().charAt(0)},aq.meridiem=function(e,a,t){return e>11?t?"pm":"PM":t?"am":"AM"},e$("en",{eras:[{since:"0001-01-01",until:Infinity,offset:1,name:"Anno Domini",narrow:"AD",abbr:"AD"},{since:"0000-12-31",until:-1/0,offset:1,name:"Before Christ",narrow:"BC",abbr:"BC"}],dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var a=e%10,t=1===eM(e%100/10)?"th":1===a?"st":2===a?"nd":3===a?"rd":"th";return e+t}}),t.lang=g("moment.lang is deprecated. Use moment.locale instead.",e$),t.langData=g("moment.langData is deprecated. Use moment.localeData instead.",eX);var a$=Math.abs;function aQ(e,a,t,s){var n=aD(a,t);return e._milliseconds+=s*n._milliseconds,e._days+=s*n._days,e._months+=s*n._months,e._bubble()}function aX(e){return e<0?Math.floor(e):Math.ceil(e)}function a1(e){return 4800*e/146097}function a0(e){return 146097*e/4800}function a2(e){return function(){return this.as(e)}}var a6=a2("ms"),a4=a2("s"),a3=a2("m"),a5=a2("h"),a7=a2("d"),a9=a2("w"),a8=a2("M"),te=a2("Q"),ta=a2("y");function tt(e){return function(){return this.isValid()?this._data[e]:NaN}}var ts=tt("milliseconds"),tn=tt("seconds"),tr=tt("minutes"),td=tt("hours"),ti=tt("days"),t_=tt("months"),to=tt("years"),tm=Math.round,tl={ss:44,s:45,m:45,h:22,d:26,w:null,M:11};function tu(e,a,t,s,n){return n.relativeTime(a||1,!!t,e,s)}var tM=Math.abs;function th(e){return(e>0)-(e<0)||+e}function tc(){if(!this.isValid())return this.localeData().invalidDate();var e,a,t,s,n,r,d,i,_=tM(this._milliseconds)/1e3,o=tM(this._days),m=tM(this._months),l=this.asSeconds();return l?(e=eu(_/60),a=eu(e/60),_%=60,e%=60,t=eu(m/12),m%=12,s=_?_.toFixed(3).replace(/\.?0+$/,""):"",n=l<0?"-":"",r=th(this._months)!==th(l)?"-":"",d=th(this._days)!==th(l)?"-":"",i=th(this._milliseconds)!==th(l)?"-":"",n+"P"+(t?r+t+"Y":"")+(m?r+m+"M":"")+(o?d+o+"D":"")+(a||e||_?"T":"")+(a?i+a+"H":"")+(e?i+e+"M":"")+(_?i+s+"S":"")):"P0D"}var tL=al.prototype;return tL.isValid=function(){return this._isValid},tL.abs=function(){var e=this._data;return this._milliseconds=a$(this._milliseconds),this._days=a$(this._days),this._months=a$(this._months),e.milliseconds=a$(e.milliseconds),e.seconds=a$(e.seconds),e.minutes=a$(e.minutes),e.hours=a$(e.hours),e.months=a$(e.months),e.years=a$(e.years),this},tL.add=function(e,a){return aQ(this,e,a,1)},tL.subtract=function(e,a){return aQ(this,e,a,-1)},tL.as=function(e){if(!this.isValid())return NaN;var a,t,s=this._milliseconds;if("month"===(e=N(e))||"quarter"===e||"year"===e)switch(a=this._days+s/864e5,t=this._months+a1(a),e){case"month":return t;case"quarter":return t/3;case"year":return t/12}else switch(a=this._days+Math.round(a0(this._months)),e){case"week":return a/7+s/6048e5;case"day":return a+s/864e5;case"hour":return 24*a+s/36e5;case"minute":return 1440*a+s/6e4;case"second":return 86400*a+s/1e3;case"millisecond":return Math.floor(864e5*a)+s;default:throw Error("Unknown unit "+e)}},tL.asMilliseconds=a6,tL.asSeconds=a4,tL.asMinutes=a3,tL.asHours=a5,tL.asDays=a7,tL.asWeeks=a9,tL.asMonths=a8,tL.asQuarters=te,tL.asYears=ta,tL.valueOf=a6,tL._bubble=function(){var e,a,t,s,n,r=this._milliseconds,d=this._days,i=this._months,_=this._data;return r>=0&&d>=0&&i>=0||r<=0&&d<=0&&i<=0||(r+=864e5*aX(a0(i)+d),d=0,i=0),_.milliseconds=r%1e3,_.seconds=(e=eu(r/1e3))%60,_.minutes=(a=eu(e/60))%60,_.hours=(t=eu(a/60))%24,d+=eu(t/24),i+=n=eu(a1(d)),d-=aX(a0(n)),s=eu(i/12),i%=12,_.days=d,_.months=i,_.years=s,this},tL.clone=function(){return aD(this)},tL.get=function(e){return e=N(e),this.isValid()?this[e+"s"]():NaN},tL.milliseconds=ts,tL.seconds=tn,tL.minutes=tr,tL.hours=td,tL.days=ti,tL.weeks=function(){return eu(this.days()/7)},tL.months=t_,tL.years=to,tL.humanize=function(e,a){if(!this.isValid())return this.localeData().invalidDate();var t,s,n,r,d,i,_,o,m,l,u,M,h,c=!1,L=tl;return"object"==typeof e&&(a=e,e=!1),"boolean"==typeof e&&(c=e),"object"==typeof a&&(L=Object.assign({},tl,a),null!=a.s&&null==a.ss&&(L.ss=a.s-1)),M=this.localeData(),t=!c,s=L,n=aD(this).abs(),r=tm(n.as("s")),d=tm(n.as("m")),i=tm(n.as("h")),_=tm(n.as("d")),o=tm(n.as("M")),m=tm(n.as("w")),l=tm(n.as("y")),u=r<=s.ss&&["s",r]||r0,u[4]=M,h=tu.apply(null,u),c&&(h=M.pastFuture(+this,h)),M.postformat(h)},tL.toISOString=tc,tL.toString=tc,tL.toJSON=tc,tL.locale=ax,tL.localeData=aO,tL.toIsoString=g("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",tc),tL.lang=aP,A("X",0,0,"unix"),A("x",0,0,"valueOf"),em("x",en),em("X",/[+-]?\d+(\.\d{1,3})?/),ec("X",function(e,a,t){t._d=new Date(1e3*parseFloat(e))}),ec("x",function(e,a,t){t._d=new Date(eM(e))}),t.version="2.30.1",R=ad,t.fn=aG,t.min=function(){var e=[].slice.call(arguments,0);return ao("isBefore",e)},t.max=function(){var e=[].slice.call(arguments,0);return ao("isAfter",e)},t.now=function(){return Date.now?Date.now():+new Date},t.utc=u,t.unix=function(e){return ad(1e3*e)},t.months=function(e,a){return aK(e,a,"months")},t.isDate=o,t.locale=e$,t.invalid=c,t.duration=aD,t.isMoment=D,t.weekdays=function(e,a,t){return aZ(e,a,t,"weekdays")},t.parseZone=function(){return ad.apply(null,arguments).parseZone()},t.localeData=eX,t.isDuration=au,t.monthsShort=function(e,a){return aK(e,a,"monthsShort")},t.weekdaysMin=function(e,a,t){return aZ(e,a,t,"weekdaysMin")},t.defineLocale=eQ,t.updateLocale=function(e,a){if(null!=a){var t,s,n=eV;null!=eq[e]&&null!=eq[e].parentLocale?eq[e].set(H(eq[e]._config,a)):(null!=(s=eZ(e))&&(n=s._config),a=H(n,a),null==s&&(a.abbr=e),(t=new S(a)).parentLocale=eq[e],eq[e]=t),e$(e)}else null!=eq[e]&&(null!=eq[e].parentLocale?(eq[e]=eq[e].parentLocale,e===e$()&&e$(e)):null!=eq[e]&&delete eq[e]);return eq[e]},t.locales=function(){return G(eq)},t.weekdaysShort=function(e,a,t){return aZ(e,a,t,"weekdaysShort")},t.normalizeUnits=N,t.relativeTimeRounding=function(e){return void 0===e?tm:"function"==typeof e&&(tm=e,!0)},t.relativeTimeThreshold=function(e,a){return void 0!==tl[e]&&(void 0===a?tl[e]:(tl[e]=a,"s"===e&&(tl.ss=a-1),!0))},t.calendarFormat=function(e,a){var t=e.diff(a,"days",!0);return t<-6?"sameElse":t<-1?"lastWeek":t<0?"lastDay":t<1?"sameDay":t<2?"nextDay":t<7?"nextWeek":"sameElse"},t.prototype=aG,t.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},t}()}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/039aof7m9ej57.js b/litellm/proxy/_experimental/out/_next/static/chunks/039aof7m9ej57.js new file mode 100644 index 00000000000..364718dd62e --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/039aof7m9ej57.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,166406,e=>{"use strict";var t=e.i(190144);e.s(["CopyOutlined",()=>t.default])},447566,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 000 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"}}]},name:"arrow-left",theme:"outlined"};var s=e.i(9583),o=r.forwardRef(function(e,o){return r.createElement(s.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["ArrowLeftOutlined",0,o],447566)},871943,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"}))});e.s(["ChevronDownIcon",0,r],871943)},360820,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 15l7-7 7 7"}))});e.s(["ChevronUpIcon",0,r],360820)},269200,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(444755);let s=(0,e.i(673706).makeClassName)("Table"),o=r.default.forwardRef((e,o)=>{let{children:l,className:n}=e,i=(0,t.__rest)(e,["children","className"]);return r.default.createElement("div",{className:(0,a.tremorTwMerge)(s("root"),"overflow-auto",n)},r.default.createElement("table",Object.assign({ref:o,className:(0,a.tremorTwMerge)(s("table"),"w-full text-tremor-default","text-tremor-content","dark:text-dark-tremor-content")},i),l))});o.displayName="Table",e.s(["Table",0,o],269200)},427612,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(444755);let s=(0,e.i(673706).makeClassName)("TableHead"),o=r.default.forwardRef((e,o)=>{let{children:l,className:n}=e,i=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("thead",Object.assign({ref:o,className:(0,a.tremorTwMerge)(s("root"),"text-left","text-tremor-content","dark:text-dark-tremor-content",n)},i),l))});o.displayName="TableHead",e.s(["TableHead",0,o],427612)},496020,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(444755);let s=(0,e.i(673706).makeClassName)("TableRow"),o=r.default.forwardRef((e,o)=>{let{children:l,className:n}=e,i=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("tr",Object.assign({ref:o,className:(0,a.tremorTwMerge)(s("row"),n)},i),l))});o.displayName="TableRow",e.s(["TableRow",0,o],496020)},64848,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(444755);let s=(0,e.i(673706).makeClassName)("TableHeaderCell"),o=r.default.forwardRef((e,o)=>{let{children:l,className:n}=e,i=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("th",Object.assign({ref:o,className:(0,a.tremorTwMerge)(s("root"),"whitespace-nowrap text-left font-semibold top-0 px-4 py-3.5","text-tremor-content-strong","dark:text-dark-tremor-content-strong",n)},i),l))});o.displayName="TableHeaderCell",e.s(["TableHeaderCell",0,o],64848)},942232,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(444755);let s=(0,e.i(673706).makeClassName)("TableBody"),o=r.default.forwardRef((e,o)=>{let{children:l,className:n}=e,i=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("tbody",Object.assign({ref:o,className:(0,a.tremorTwMerge)(s("root"),"align-top divide-y","divide-tremor-border","dark:divide-dark-tremor-border",n)},i),l))});o.displayName="TableBody",e.s(["TableBody",0,o],942232)},977572,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(444755);let s=(0,e.i(673706).makeClassName)("TableCell"),o=r.default.forwardRef((e,o)=>{let{children:l,className:n}=e,i=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("td",Object.assign({ref:o,className:(0,a.tremorTwMerge)(s("root"),"align-middle whitespace-nowrap text-left p-4",n)},i),l))});o.displayName="TableCell",e.s(["TableCell",0,o],977572)},68155,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"}))});e.s(["TrashIcon",0,r],68155)},278587,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"}))});e.s(["RefreshIcon",0,r],278587)},502547,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9 5l7 7-7 7"}))});e.s(["ChevronRightIcon",0,r],502547)},263147,e=>{"use strict";var t=e.i(266027),r=e.i(243652),a=e.i(602869),s=e.i(431703),o=e.i(708347),l=e.i(135214);let n=(0,r.createQueryKeys)("accessGroups"),i=async e=>{let t=(0,a.getProxyBaseUrl)(),r=`${t}/v1/access_group`,o=await fetch(r,{method:"GET",headers:{[(0,a.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!o.ok){let e=await o.json(),t=(0,s.deriveErrorMessage)(e);throw(0,a.handleError)(t),Error(t)}return o.json()};e.s(["accessGroupKeys",0,n,"useAccessGroups",0,()=>{let{accessToken:e,userRole:r}=(0,l.default)();return(0,t.useQuery)({queryKey:n.list({}),queryFn:async()=>i(e),enabled:!!e&&o.all_admin_roles.includes(r||"")})}])},304911,e=>{"use strict";var t=e.i(843476),r=e.i(262218);let{Text:a}=e.i(898586).Typography;e.s(["default",0,function({userId:e}){return"default_user_id"===e?(0,t.jsx)(r.Tag,{color:"blue",children:"Default Proxy Admin"}):(0,t.jsx)(a,{children:e})}])},384767,e=>{"use strict";var t=e.i(843476),r=e.i(599724),a=e.i(271645),s=e.i(389083);let o=a.forwardRef(function(e,t){return a.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),a.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"}))});var l=e.i(602869);let n=function({vectorStores:e,accessToken:n}){let[i,c]=(0,a.useState)([]);return(0,a.useEffect)(()=>{(async()=>{if(n&&0!==e.length)try{let e=await (0,l.vectorStoreListCall)(n);e.data&&c(e.data.map(e=>({vector_store_id:e.vector_store_id,vector_store_name:e.vector_store_name})))}catch(e){console.error("Error fetching vector stores:",e)}})()},[n,e.length]),(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(o,{className:"h-4 w-4 text-blue-600"}),(0,t.jsx)(r.Text,{className:"font-semibold text-gray-900",children:"Vector Stores"}),(0,t.jsx)(s.Badge,{color:"blue",size:"xs",children:e.length})]}),e.length>0?(0,t.jsx)("div",{className:"flex flex-wrap gap-2",children:e.map((e,r)=>{let a;return(0,t.jsx)("div",{className:"inline-flex items-center px-3 py-1.5 rounded-lg bg-blue-50 border border-blue-200 text-blue-800 text-sm font-medium",children:(a=i.find(t=>t.vector_store_id===e))?`${a.vector_store_name||a.vector_store_id} (${a.vector_store_id})`:e},r)})}):(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-gray-50 border border-gray-200",children:[(0,t.jsx)(o,{className:"h-4 w-4 text-gray-400"}),(0,t.jsx)(r.Text,{className:"text-gray-500 text-sm",children:"No vector stores configured"})]})]})},i=a.forwardRef(function(e,t){return a.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),a.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01"}))});var c=e.i(871943),d=e.i(502547),m=e.i(592968),u=e.i(234713);let g=function({mcpServers:e,mcpAccessGroups:o=[],mcpToolPermissions:n={},mcpToolsets:g=[],accessToken:h}){let[f,p]=(0,a.useState)([]),[x,v]=(0,a.useState)([]),[b,w]=(0,a.useState)(new Set),[N,y]=(0,a.useState)(new Set);(0,a.useEffect)(()=>{(async()=>{if(h&&e.length>0)try{let e=await (0,l.fetchMCPServers)(h);e&&Array.isArray(e)?p(e):e.data&&Array.isArray(e.data)&&p(e.data)}catch(e){console.error("Error fetching MCP servers:",e)}})()},[h,e.length]),(0,a.useEffect)(()=>{(async()=>{if(h&&g.length>0)try{let e=await (0,l.fetchMCPToolsets)(h),t=Array.isArray(e)?e.filter(e=>g.includes(e.toolset_id)):[];v(t)}catch(e){console.error("Error fetching toolsets:",e)}})()},[h,g.length]);let C=e.includes(u.NO_MCP_SERVERS_SENTINEL),j=e.includes(u.ALL_PROXY_MCP_SERVERS_SENTINEL),k=[...e.filter(e=>e!==u.NO_MCP_SERVERS_SENTINEL&&e!==u.ALL_PROXY_MCP_SERVERS_SENTINEL).map(e=>({type:"server",value:e})),...o.map(e=>({type:"accessGroup",value:e}))],T=k.length+g.length;return(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(i,{className:"h-4 w-4 text-blue-600"}),(0,t.jsx)(r.Text,{className:"font-semibold text-gray-900",children:"MCP Servers"}),(0,t.jsx)(s.Badge,{color:C?"red":"blue",size:"xs",children:C?"Blocked":j?"All":T})]}),C?(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-red-50 border border-red-200",children:[(0,t.jsx)(i,{className:"h-4 w-4 text-red-400"}),(0,t.jsx)(r.Text,{className:"text-red-700 text-sm",children:"No MCP servers — this key is blocked from all MCP servers, including its team's servers"})]}):j?(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-blue-50 border border-blue-200",children:[(0,t.jsx)(i,{className:"h-4 w-4 text-blue-400"}),(0,t.jsx)(r.Text,{className:"text-blue-700 text-sm",children:"All Proxy MCP Servers"})]}):T>0?(0,t.jsxs)("div",{className:"max-h-[400px] overflow-y-auto space-y-2 pr-1",children:[k.map((e,r)=>{let a="server"===e.type?n[e.value]:void 0,s=a&&a.length>0,o=b.has(e.value);return(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{onClick:()=>{var t;return s&&(t=e.value,void w(e=>{let r=new Set(e);return r.has(t)?r.delete(t):r.add(t),r}))},className:`flex items-center gap-3 py-2 px-3 rounded-lg border border-gray-200 transition-all ${s?"cursor-pointer hover:bg-gray-50 hover:border-gray-300":"bg-white"}`,children:[(0,t.jsx)("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:"server"===e.type?(0,t.jsx)(m.Tooltip,{title:`Full ID: ${e.value}`,placement:"top",children:(0,t.jsxs)("div",{className:"inline-flex items-center gap-2 min-w-0",children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-blue-500 rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-gray-900 truncate",children:(e=>{let t=f.find(t=>t.server_id===e);if(t){let r=e.length>7?`${e.slice(0,3)}...${e.slice(-4)}`:e;return`${t.alias} (${r})`}return e})(e.value)})]})}):(0,t.jsxs)("div",{className:"inline-flex items-center gap-2 min-w-0",children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-green-500 rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-gray-900 truncate",children:e.value}),(0,t.jsx)("span",{className:"ml-1 px-1.5 py-0.5 text-[9px] font-semibold text-green-600 bg-green-50 border border-green-200 rounded-sm uppercase tracking-wide shrink-0",children:"Group"})]})}),s&&(0,t.jsxs)("div",{className:"flex items-center gap-1 shrink-0 whitespace-nowrap",children:[(0,t.jsx)("span",{className:"text-xs font-medium text-gray-600",children:a.length}),(0,t.jsx)("span",{className:"text-xs text-gray-500",children:1===a.length?"tool":"tools"}),o?(0,t.jsx)(c.ChevronDownIcon,{className:"h-3.5 w-3.5 text-gray-400 ml-0.5"}):(0,t.jsx)(d.ChevronRightIcon,{className:"h-3.5 w-3.5 text-gray-400 ml-0.5"})]})]}),s&&o&&(0,t.jsx)("div",{className:"ml-4 pl-4 border-l-2 border-blue-200 pb-1",children:(0,t.jsx)("div",{className:"flex flex-wrap gap-1.5",children:a.map((e,r)=>(0,t.jsx)("span",{className:"inline-flex items-center px-2.5 py-1 rounded-lg bg-blue-50 border border-blue-200 text-blue-800 text-xs font-medium",children:e},r))})})]},r)}),g.length>0&&g.map((e,r)=>{let a=x.find(t=>t.toolset_id===e),s=N.has(e),o=a?.tools.length??0;return(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{onClick:()=>o>0&&void y(t=>{let r=new Set(t);return r.has(e)?r.delete(e):r.add(e),r}),className:`flex items-center gap-3 py-2 px-3 rounded-lg border border-purple-200 transition-all ${o>0?"cursor-pointer hover:bg-purple-50 hover:border-purple-300":"bg-white"}`,children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-purple-500 rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-gray-900 truncate",children:a?.toolset_name??e}),(0,t.jsx)("span",{className:"ml-1 px-1.5 py-0.5 text-[9px] font-semibold text-purple-600 bg-purple-50 border border-purple-200 rounded-sm uppercase tracking-wide shrink-0",children:"Toolset"})]}),o>0&&(0,t.jsxs)("div",{className:"flex items-center gap-1 shrink-0 whitespace-nowrap",children:[(0,t.jsx)("span",{className:"text-xs font-medium text-gray-600",children:o}),(0,t.jsx)("span",{className:"text-xs text-gray-500",children:1===o?"tool":"tools"}),s?(0,t.jsx)(c.ChevronDownIcon,{className:"h-3.5 w-3.5 text-gray-400 ml-0.5"}):(0,t.jsx)(d.ChevronRightIcon,{className:"h-3.5 w-3.5 text-gray-400 ml-0.5"})]})]}),o>0&&s&&a&&(0,t.jsx)("div",{className:"ml-4 pl-4 border-l-2 border-purple-200 pb-1",children:(0,t.jsx)("div",{className:"flex flex-wrap gap-1.5",children:a.tools.map((e,r)=>(0,t.jsxs)("span",{className:"inline-flex items-center px-2.5 py-1 rounded-lg bg-purple-50 border border-purple-200 text-purple-800 text-xs font-medium",children:[(0,t.jsxs)("span",{className:"text-purple-400 mr-1 text-[10px]",children:[e.server_id.slice(0,6),"…"]}),e.tool_name]},r))})})]},`toolset-${r}`)})]}):(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-gray-50 border border-gray-200",children:[(0,t.jsx)(i,{className:"h-4 w-4 text-gray-400"}),(0,t.jsx)(r.Text,{className:"text-gray-500 text-sm",children:"No MCP servers, access groups, or toolsets configured"})]})]})},h=a.forwardRef(function(e,t){return a.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),a.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"}))}),f=function({agents:e,agentAccessGroups:o=[],accessToken:n}){let[i,c]=(0,a.useState)([]);(0,a.useEffect)(()=>{(async()=>{if(n&&e.length>0)try{let e=await (0,l.getAgentsList)(n);e&&e.agents&&Array.isArray(e.agents)&&c(e.agents)}catch(e){console.error("Error fetching agents:",e)}})()},[n,e.length]);let d=[...e.map(e=>({type:"agent",value:e})),...o.map(e=>({type:"accessGroup",value:e}))],u=d.length;return(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(h,{className:"h-4 w-4 text-purple-600"}),(0,t.jsx)(r.Text,{className:"font-semibold text-gray-900",children:"Agents"}),(0,t.jsx)(s.Badge,{color:"purple",size:"xs",children:u})]}),u>0?(0,t.jsx)("div",{className:"max-h-[400px] overflow-y-auto space-y-2 pr-1",children:d.map((e,r)=>(0,t.jsx)("div",{className:"space-y-2",children:(0,t.jsx)("div",{className:"flex items-center gap-3 py-2 px-3 rounded-lg border border-gray-200 bg-white",children:(0,t.jsx)("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:"agent"===e.type?(0,t.jsx)(m.Tooltip,{title:`Full ID: ${e.value}`,placement:"top",children:(0,t.jsxs)("div",{className:"inline-flex items-center gap-2 min-w-0",children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-purple-500 rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-gray-900 truncate",children:(e=>{let t=i.find(t=>t.agent_id===e);if(t){let r=e.length>7?`${e.slice(0,3)}...${e.slice(-4)}`:e;return`${t.agent_name} (${r})`}return e})(e.value)})]})}):(0,t.jsxs)("div",{className:"inline-flex items-center gap-2 min-w-0",children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-green-500 rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-gray-900 truncate",children:e.value}),(0,t.jsx)("span",{className:"ml-1 px-1.5 py-0.5 text-[9px] font-semibold text-green-600 bg-green-50 border border-green-200 rounded-sm uppercase tracking-wide shrink-0",children:"Group"})]})})})},r))}):(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-gray-50 border border-gray-200",children:[(0,t.jsx)(h,{className:"h-4 w-4 text-gray-400"}),(0,t.jsx)(r.Text,{className:"text-gray-500 text-sm",children:"No agents or access groups configured"})]})]})};e.s(["default",0,function({objectPermission:e,variant:a="card",className:s="",accessToken:o}){let l=e?.vector_stores||[],i=e?.mcp_servers||[],c=e?.mcp_access_groups||[],d=e?.mcp_tool_permissions||{},m=e?.mcp_toolsets||[],u=e?.agents||[],h=e?.agent_access_groups||[],p=e?.search_tools||[],x=(0,t.jsxs)("div",{className:"card"===a?"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6":"space-y-4",children:[(0,t.jsx)(n,{vectorStores:l,accessToken:o}),(0,t.jsx)(g,{mcpServers:i,mcpAccessGroups:c,mcpToolPermissions:d,mcpToolsets:m,accessToken:o}),(0,t.jsx)(f,{agents:u,agentAccessGroups:h,accessToken:o}),(0,t.jsxs)("div",{className:"rounded-md border border-gray-100 p-4",children:[(0,t.jsx)(r.Text,{className:"text-sm font-medium text-gray-800",children:"Search tools"}),0===p.length?(0,t.jsx)(r.Text,{className:"mt-1 block text-xs text-gray-500",children:"No restriction — all configured search tools are allowed for this team."}):(0,t.jsx)(r.Text,{className:"mt-1 block text-xs text-gray-700",children:p.join(", ")})]})]});return"card"===a?(0,t.jsxs)("div",{className:`bg-white border border-gray-200 rounded-lg p-6 ${s}`,children:[(0,t.jsx)("div",{className:"flex items-center gap-2 mb-6",children:(0,t.jsxs)("div",{children:[(0,t.jsx)(r.Text,{className:"font-semibold text-gray-900",children:"Object Permissions"}),(0,t.jsx)(r.Text,{className:"text-xs text-gray-500",children:"Access control for Vector Stores and MCP Servers"})]})}),x]}):(0,t.jsxs)("div",{className:`${s}`,children:[(0,t.jsx)(r.Text,{className:"font-medium text-gray-900 mb-3",children:"Object Permissions"}),x]})}],384767)},637235,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"}},{tag:"path",attrs:{d:"M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z"}}]},name:"clock-circle",theme:"outlined"};var s=e.i(9583),o=r.forwardRef(function(e,o){return r.createElement(s.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["ClockCircleOutlined",0,o],637235)},597440,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"}}]},name:"delete",theme:"outlined"};var s=e.i(9583),o=r.forwardRef(function(e,o){return r.createElement(s.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["default",0,o],597440)},955135,e=>{"use strict";var t=e.i(597440);e.s(["DeleteOutlined",()=>t.default])},646563,e=>{"use strict";var t=e.i(959013);e.s(["PlusOutlined",()=>t.default])},599724,936325,e=>{"use strict";var t=e.i(95779),r=e.i(444755),a=e.i(673706),s=e.i(271645);let o=s.default.forwardRef((e,o)=>{let{color:l,className:n,children:i}=e;return s.default.createElement("p",{ref:o,className:(0,r.tremorTwMerge)("text-tremor-default",l?(0,a.getColorClassNames)(l,t.colorPalette.text).textColor:(0,r.tremorTwMerge)("text-tremor-content","dark:text-dark-tremor-content"),n)},i)});o.displayName="Text",e.s(["default",0,o],936325),e.s(["Text",0,o],599724)},994388,e=>{"use strict";var t=e.i(290571),r=e.i(829087),a=e.i(271645);let s=["preEnter","entering","entered","preExit","exiting","exited","unmounted"],o=e=>({_s:e,status:s[e],isEnter:e<3,isMounted:6!==e,isResolved:2===e||e>4}),l=e=>e?6:5,n=(e,t,r,a,s)=>{clearTimeout(a.current);let l=o(e);t(l),r.current=l,s&&s({current:l})};var i=e.i(480731),c=e.i(444755),d=e.i(673706);let m=e=>{var r=(0,t.__rest)(e,[]);return a.default.createElement("svg",Object.assign({},r,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"}),a.default.createElement("path",{fill:"none",d:"M0 0h24v24H0z"}),a.default.createElement("path",{d:"M18.364 5.636L16.95 7.05A7 7 0 1 0 19 12h2a9 9 0 1 1-2.636-6.364z"}))};var u=e.i(95779);let g={xs:{height:"h-4",width:"w-4"},sm:{height:"h-5",width:"w-5"},md:{height:"h-5",width:"w-5"},lg:{height:"h-6",width:"w-6"},xl:{height:"h-6",width:"w-6"}},h=(e,t)=>{switch(e){case"primary":return{textColor:t?(0,d.getColorClassNames)("white").textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",hoverTextColor:t?(0,d.getColorClassNames)("white").textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:t?(0,d.getColorClassNames)(t,u.colorPalette.background).bgColor:"bg-tremor-brand dark:bg-dark-tremor-brand",hoverBgColor:t?(0,d.getColorClassNames)(t,u.colorPalette.darkBackground).hoverBgColor:"hover:bg-tremor-brand-emphasis dark:hover:bg-dark-tremor-brand-emphasis",borderColor:t?(0,d.getColorClassNames)(t,u.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand",hoverBorderColor:t?(0,d.getColorClassNames)(t,u.colorPalette.darkBorder).hoverBorderColor:"hover:border-tremor-brand-emphasis dark:hover:border-dark-tremor-brand-emphasis"};case"secondary":return{textColor:t?(0,d.getColorClassNames)(t,u.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",hoverTextColor:t?(0,d.getColorClassNames)(t,u.colorPalette.text).textColor:"hover:text-tremor-brand-emphasis dark:hover:text-dark-tremor-brand-emphasis",bgColor:(0,d.getColorClassNames)("transparent").bgColor,hoverBgColor:t?(0,c.tremorTwMerge)((0,d.getColorClassNames)(t,u.colorPalette.background).hoverBgColor,"hover:bg-opacity-20 dark:hover:bg-opacity-20"):"hover:bg-tremor-brand-faint dark:hover:bg-dark-tremor-brand-faint",borderColor:t?(0,d.getColorClassNames)(t,u.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand"};case"light":return{textColor:t?(0,d.getColorClassNames)(t,u.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",hoverTextColor:t?(0,d.getColorClassNames)(t,u.colorPalette.darkText).hoverTextColor:"hover:text-tremor-brand-emphasis dark:hover:text-dark-tremor-brand-emphasis",bgColor:(0,d.getColorClassNames)("transparent").bgColor,borderColor:"",hoverBorderColor:""}}},f=(0,d.makeClassName)("Button"),p=({loading:e,iconSize:t,iconPosition:r,Icon:s,needMargin:o,transitionStatus:l})=>{let n=o?r===i.HorizontalPositions.Left?(0,c.tremorTwMerge)("-ml-1","mr-1.5"):(0,c.tremorTwMerge)("-mr-1","ml-1.5"):"",d=(0,c.tremorTwMerge)("w-0 h-0"),u={default:d,entering:d,entered:t,exiting:t,exited:d};return e?a.default.createElement(m,{className:(0,c.tremorTwMerge)(f("icon"),"animate-spin shrink-0",n,u.default,u[l]),style:{transition:"width 150ms"}}):a.default.createElement(s,{className:(0,c.tremorTwMerge)(f("icon"),"shrink-0",t,n)})},x=a.default.forwardRef((e,s)=>{let{icon:m,iconPosition:u=i.HorizontalPositions.Left,size:x=i.Sizes.SM,color:v,variant:b="primary",disabled:w,loading:N=!1,loadingText:y,children:C,tooltip:j,className:k}=e,T=(0,t.__rest)(e,["icon","iconPosition","size","color","variant","disabled","loading","loadingText","children","tooltip","className"]),E=N||w,_=void 0!==m||N,M=N&&y,S=!(!C&&!M),P=(0,c.tremorTwMerge)(g[x].height,g[x].width),R="light"!==b?(0,c.tremorTwMerge)("rounded-tremor-default border","shadow-tremor-input","dark:shadow-dark-tremor-input"):"",L=h(b,v),z=("light"!==b?{xs:{paddingX:"px-2.5",paddingY:"py-1.5",fontSize:"text-xs"},sm:{paddingX:"px-4",paddingY:"py-2",fontSize:"text-sm"},md:{paddingX:"px-4",paddingY:"py-2",fontSize:"text-md"},lg:{paddingX:"px-4",paddingY:"py-2.5",fontSize:"text-lg"},xl:{paddingX:"px-4",paddingY:"py-3",fontSize:"text-xl"}}:{xs:{paddingX:"",paddingY:"",fontSize:"text-xs"},sm:{paddingX:"",paddingY:"",fontSize:"text-sm"},md:{paddingX:"",paddingY:"",fontSize:"text-md"},lg:{paddingX:"",paddingY:"",fontSize:"text-lg"},xl:{paddingX:"",paddingY:"",fontSize:"text-xl"}})[x],{tooltipProps:B,getReferenceProps:$}=(0,r.useTooltip)(300),[O,H]=(({enter:e=!0,exit:t=!0,preEnter:r,preExit:s,timeout:i,initialEntered:c,mountOnEnter:d,unmountOnExit:m,onStateChange:u}={})=>{let[g,h]=(0,a.useState)(()=>o(c?2:l(d))),f=(0,a.useRef)(g),p=(0,a.useRef)(0),[x,v]="object"==typeof i?[i.enter,i.exit]:[i,i],b=(0,a.useCallback)(()=>{let e=((e,t)=>{switch(e){case 1:case 0:return 2;case 4:case 3:return l(t)}})(f.current._s,m);e&&n(e,h,f,p,u)},[u,m]);return[g,(0,a.useCallback)(a=>{let o=e=>{switch(n(e,h,f,p,u),e){case 1:x>=0&&(p.current=((...e)=>setTimeout(...e))(b,x));break;case 4:v>=0&&(p.current=((...e)=>setTimeout(...e))(b,v));break;case 0:case 3:p.current=((...e)=>setTimeout(...e))(()=>{isNaN(document.body.offsetTop)||o(e+1)},0)}},i=f.current.isEnter;"boolean"!=typeof a&&(a=!i),a?i||o(e?+!r:2):i&&o(t?s?3:4:l(m))},[b,u,e,t,r,s,x,v,m]),b]})({timeout:50});return(0,a.useEffect)(()=>{H(N)},[N]),a.default.createElement("button",Object.assign({ref:(0,d.mergeRefs)([s,B.refs.setReference]),className:(0,c.tremorTwMerge)(f("root"),"shrink-0 inline-flex justify-center items-center group font-medium outline-none",R,z.paddingX,z.paddingY,z.fontSize,L.textColor,L.bgColor,L.borderColor,L.hoverBorderColor,E?"opacity-50 cursor-not-allowed":(0,c.tremorTwMerge)(h(b,v).hoverTextColor,h(b,v).hoverBgColor,h(b,v).hoverBorderColor),k),disabled:E},$,T),a.default.createElement(r.default,Object.assign({text:j},B)),_&&u!==i.HorizontalPositions.Right?a.default.createElement(p,{loading:N,iconSize:P,iconPosition:u,Icon:m,transitionStatus:O.status,needMargin:S}):null,M||C?a.default.createElement("span",{className:(0,c.tremorTwMerge)(f("text"),"text-tremor-default whitespace-nowrap")},M?y:C):null,_&&u===i.HorizontalPositions.Right?a.default.createElement(p,{loading:N,iconSize:P,iconPosition:u,Icon:m,transitionStatus:O.status,needMargin:S}):null)});x.displayName="Button",e.s(["Button",0,x],994388)},304967,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(480731),s=e.i(95779),o=e.i(444755),l=e.i(673706);let n=(0,l.makeClassName)("Card"),i=r.default.forwardRef((e,i)=>{let{decoration:c="",decorationColor:d,children:m,className:u}=e,g=(0,t.__rest)(e,["decoration","decorationColor","children","className"]);return r.default.createElement("div",Object.assign({ref:i,className:(0,o.tremorTwMerge)(n("root"),"relative w-full text-left ring-1 rounded-tremor-default p-6","bg-tremor-background ring-tremor-ring shadow-tremor-card","dark:bg-dark-tremor-background dark:ring-dark-tremor-ring dark:shadow-dark-tremor-card",d?(0,l.getColorClassNames)(d,s.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand",(e=>{if(!e)return"";switch(e){case a.HorizontalPositions.Left:return"border-l-4";case a.VerticalPositions.Top:return"border-t-4";case a.HorizontalPositions.Right:return"border-r-4";case a.VerticalPositions.Bottom:return"border-b-4";default:return""}})(c),u)},g),m)});i.displayName="Card",e.s(["Card",0,i],304967)},629569,e=>{"use strict";var t=e.i(290571),r=e.i(95779),a=e.i(444755),s=e.i(673706),o=e.i(271645);let l=o.default.forwardRef((e,l)=>{let{color:n,children:i,className:c}=e,d=(0,t.__rest)(e,["color","children","className"]);return o.default.createElement("p",Object.assign({ref:l,className:(0,a.tremorTwMerge)("font-medium text-tremor-title",n?(0,s.getColorClassNames)(n,r.colorPalette.darkText).textColor:"text-tremor-content-strong dark:text-dark-tremor-content-strong",c)},d),i)});l.displayName="Title",e.s(["Title",0,l],629569)},653496,e=>{"use strict";var t=e.i(721369);e.s(["Tabs",()=>t.default])},536916,e=>{"use strict";var t=e.i(374276);e.s(["Checkbox",()=>t.default])},891547,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(199133),s=e.i(602869);e.s(["default",0,({onChange:e,value:o,className:l,accessToken:n,disabled:i})=>{let[c,d]=(0,r.useState)([]),[m,u]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{(async()=>{if(n){u(!0);try{let e=await (0,s.getGuardrailsList)(n);e.guardrails&&d(e.guardrails)}catch(e){console.error("Error fetching guardrails:",e)}finally{u(!1)}}})()},[n]),(0,t.jsx)("div",{children:(0,t.jsx)(a.Select,{mode:"multiple",disabled:i,placeholder:i?"Setting guardrails is a premium feature.":"Select guardrails",onChange:t=>{e(t)},value:o,loading:m,className:l,allowClear:!0,options:c.map(e=>({label:`${e.guardrail_name}`,value:e.guardrail_name})),optionFilterProp:"label",showSearch:!0,style:{width:"100%"}})})}])},921511,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(199133),s=e.i(602869);function o(e){return e.filter(e=>(e.version_status??"draft")!=="draft").map(e=>{var t;let r=e.version_number??1,a=e.version_status??"draft";return{label:`${e.policy_name} — v${r} (${a})${e.description?` — ${e.description}`:""}`,value:"production"===a?e.policy_name:e.policy_id?(t=e.policy_id,`policy_${t}`):e.policy_name}})}e.s(["default",0,({onChange:e,value:l,className:n,accessToken:i,disabled:c,onPoliciesLoaded:d})=>{let[m,u]=(0,r.useState)([]),[g,h]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{(async()=>{if(i){h(!0);try{let e=await (0,s.getPoliciesList)(i);e.policies&&(u(e.policies),d?.(e.policies))}catch(e){console.error("Error fetching policies:",e)}finally{h(!1)}}})()},[i,d]),(0,t.jsx)("div",{children:(0,t.jsx)(a.Select,{mode:"multiple",disabled:c,placeholder:c?"Setting policies is a premium feature.":"Select policies (production or published versions)",onChange:t=>{e(t)},value:l,loading:g,className:n,allowClear:!0,options:o(m),optionFilterProp:"label",showSearch:!0,style:{width:"100%"}})})},"getPolicyOptionEntries",0,o])},530212,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10 19l-7-7m0 0l7-7m-7 7h18"}))});e.s(["ArrowLeftIcon",0,r],530212)},482725,e=>{"use strict";var t=e.i(244451);e.s(["Spin",()=>t.default])},555987,e=>{"use strict";var t=e.i(221688),r=e.i(950643);let a=/^(https?:|data:|blob:|\/\/)/i;e.s(["resolveLogoSrc",0,(e,s=t.serverRootPath)=>{if(e){let t;return a.test(e)?e:(t=(0,r.normalizeRootPath)(s),`${t}${e.startsWith("/")?e:`/${e}`}`)}}])},500330,e=>{"use strict";var t=e.i(727749);let r=(e,t=0,r=!1,a=!0)=>{if(null==e||!Number.isFinite(e)||0===e&&!a)return"-";let s={minimumFractionDigits:t,maximumFractionDigits:t};if(!r)return e.toLocaleString("en-US",s);let o=e<0?"-":"",l=Math.abs(e),n=l,i="";return l>=1e6?(n=l/1e6,i="M"):l>=1e3&&(n=l/1e3,i="K"),`${o}${n.toLocaleString("en-US",s)}${i}`},a=async(e,r="Copied to clipboard")=>{if(!e)return!1;if(!navigator||!navigator.clipboard||!navigator.clipboard.writeText)return s(e,r);try{return await navigator.clipboard.writeText(e),t.default.success(r),!0}catch(t){return console.error("Clipboard API failed: ",t),s(e,r)}},s=(e,r)=>{try{let a=document.createElement("textarea");a.value=e,a.style.position="fixed",a.style.left="-999999px",a.style.top="-999999px",a.setAttribute("readonly",""),document.body.appendChild(a),a.focus(),a.select();let s=document.execCommand("copy");if(document.body.removeChild(a),s)return t.default.success(r),!0;throw Error("execCommand failed")}catch(e){return t.default.fromBackend("Failed to copy to clipboard"),console.error("Failed to copy: ",e),!1}};e.s(["copyToClipboard",0,a,"formatNumberWithCommas",0,r,"getSpendString",0,(e,t=6)=>{if(null==e||!Number.isFinite(e)||0===e)return"-";let a=r(e,t,!1,!1);if(0===Number(a.replace(/,/g,""))){let e=(1/10**t).toFixed(t);return`< $${e}`}return`$${a}`},"updateExistingKeys",0,function(e,t){let r=structuredClone(e);for(let[e,a]of Object.entries(t))e in r&&(r[e]=a);return r}])},91739,e=>{"use strict";var t=e.i(544195);e.s(["Radio",()=>t.default])},211576,e=>{"use strict";var t=e.i(131757);e.s(["Col",()=>t.default])},178654,e=>{"use strict";let t=e.i(211576).Col;e.s(["Col",0,t],178654)},621192,e=>{"use strict";let t=e.i(264042).Row;e.s(["Row",0,t],621192)},962944,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M848 359.3H627.7L825.8 109c4.1-5.3.4-13-6.3-13H436c-2.8 0-5.5 1.5-6.9 4L170 547.5c-3.1 5.3.7 12 6.9 12h174.4l-89.4 357.6c-1.9 7.8 7.5 13.3 13.3 7.7L853.5 373c5.2-4.9 1.7-13.7-5.5-13.7zM378.2 732.5l60.3-241H281.1l189.6-327.4h224.6L487 427.4h211L378.2 732.5z"}}]},name:"thunderbolt",theme:"outlined"};var s=e.i(9583),o=r.forwardRef(function(e,o){return r.createElement(s.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["ThunderboltOutlined",0,o],962944)},72713,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V460h656v380zM184 392V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v136H184z"}}]},name:"calendar",theme:"outlined"};var s=e.i(9583),o=r.forwardRef(function(e,o){return r.createElement(s.default,(0,t.default)({},e,{ref:o,icon:a}))});e.s(["CalendarOutlined",0,o],72713)},439189,435684,96226,497245,e=>{"use strict";function t(e){let t=Object.prototype.toString.call(e);return e instanceof Date||"object"==typeof e&&"[object Date]"===t?new e.constructor(+e):new Date("number"==typeof e||"[object Number]"===t||"string"==typeof e||"[object String]"===t?e:NaN)}function r(e,t){return e instanceof Date?new e.constructor(t):new Date(t)}e.s(["toDate",0,t],435684),e.s(["constructFrom",0,r],96226),e.s(["addDays",0,function(e,a){let s=t(e);return isNaN(a)?r(e,NaN):(a&&s.setDate(s.getDate()+a),s)}],439189),e.s(["addMonths",0,function(e,a){let s=t(e);if(isNaN(a))return r(e,NaN);if(!a)return s;let o=s.getDate(),l=r(e,s.getTime());return(l.setMonth(s.getMonth()+a+1,0),o>=l.getDate())?l:(s.setFullYear(l.getFullYear(),l.getMonth(),o),s)}],497245)},24529,e=>{"use strict";var t=e.i(439189),r=e.i(497245),a=e.i(96226),s=e.i(435684);function o(e,o){let{years:l=0,months:n=0,weeks:i=0,days:c=0,hours:d=0,minutes:m=0,seconds:u=0}=o,g=(0,s.toDate)(e),h=n||l?(0,r.addMonths)(g,n+12*l):g,f=c||i?(0,t.addDays)(h,c+7*i):h;return(0,a.constructFrom)(e,f.getTime()+1e3*(u+60*(m+60*d)))}let l=/[zZ]$|[+-]\d{2}:?\d{2}$/;function n(e){return Date.parse(l.test(e)?e:`${e}Z`)}e.s(["calculateExpiryPreviewFromDuration",0,function(e){if(!e)return null;try{let t,r=parseInt(e);if(Number.isNaN(r))throw Error("Invalid duration format");let a=new Date;if(e.endsWith("mo"))t=o(a,{months:r});else if(e.endsWith("s"))t=o(a,{seconds:r});else if(e.endsWith("m"))t=o(a,{minutes:r});else if(e.endsWith("h"))t=o(a,{hours:r});else if(e.endsWith("d"))t=o(a,{days:r});else if(e.endsWith("w"))t=o(a,{weeks:r});else throw Error("Invalid duration format");return t.toLocaleString()}catch{return null}},"formatExpiresUtc",0,function(e){let t=n(e);return Number.isNaN(t)?e:new Date(t).toLocaleString()},"isKeyExpired",0,function(e){if(!e)return!1;let t=n(e);return!Number.isNaN(t)&&t{"use strict";var t=e.i(616303);e.s(["Empty",()=>t.default])},94629,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"}))});e.s(["SwitchVerticalIcon",0,r],94629)},728889,e=>{"use strict";var t=e.i(290571),r=e.i(271645),o=e.i(829087),a=e.i(480731),s=e.i(444755),n=e.i(673706),i=e.i(95779);let l={xs:{paddingX:"px-1.5",paddingY:"py-1.5"},sm:{paddingX:"px-1.5",paddingY:"py-1.5"},md:{paddingX:"px-2",paddingY:"py-2"},lg:{paddingX:"px-2",paddingY:"py-2"},xl:{paddingX:"px-2.5",paddingY:"py-2.5"}},d={xs:{height:"h-3",width:"w-3"},sm:{height:"h-5",width:"w-5"},md:{height:"h-5",width:"w-5"},lg:{height:"h-7",width:"w-7"},xl:{height:"h-9",width:"w-9"}},c={simple:{rounded:"",border:"",ring:"",shadow:""},light:{rounded:"rounded-tremor-default",border:"",ring:"",shadow:""},shadow:{rounded:"rounded-tremor-default",border:"border",ring:"",shadow:"shadow-tremor-card dark:shadow-dark-tremor-card"},solid:{rounded:"rounded-tremor-default",border:"border-2",ring:"ring-1",shadow:""},outlined:{rounded:"rounded-tremor-default",border:"border",ring:"ring-2",shadow:""}},u=(0,n.makeClassName)("Icon"),m=r.default.forwardRef((e,m)=>{let{icon:g,variant:h="simple",tooltip:b,size:f=a.Sizes.SM,color:p,className:C}=e,w=(0,t.__rest)(e,["icon","variant","tooltip","size","color","className"]),k=((e,t)=>{switch(e){case"simple":return{textColor:t?(0,n.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:"",borderColor:"",ringColor:""};case"light":return{textColor:t?(0,n.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,s.tremorTwMerge)((0,n.getColorClassNames)(t,i.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-brand-muted dark:bg-dark-tremor-brand-muted",borderColor:"",ringColor:""};case"shadow":return{textColor:t?(0,n.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,s.tremorTwMerge)((0,n.getColorClassNames)(t,i.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:"border-tremor-border dark:border-dark-tremor-border",ringColor:""};case"solid":return{textColor:t?(0,n.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:t?(0,s.tremorTwMerge)((0,n.getColorClassNames)(t,i.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-brand dark:bg-dark-tremor-brand",borderColor:"border-tremor-brand-inverted dark:border-dark-tremor-brand-inverted",ringColor:"ring-tremor-ring dark:ring-dark-tremor-ring"};case"outlined":return{textColor:t?(0,n.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,s.tremorTwMerge)((0,n.getColorClassNames)(t,i.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:t?(0,n.getColorClassNames)(t,i.colorPalette.ring).borderColor:"border-tremor-brand-subtle dark:border-dark-tremor-brand-subtle",ringColor:t?(0,s.tremorTwMerge)((0,n.getColorClassNames)(t,i.colorPalette.ring).ringColor,"ring-opacity-40"):"ring-tremor-brand-muted dark:ring-dark-tremor-brand-muted"}}})(h,p),{tooltipProps:x,getReferenceProps:v}=(0,o.useTooltip)();return r.default.createElement("span",Object.assign({ref:(0,n.mergeRefs)([m,x.refs.setReference]),className:(0,s.tremorTwMerge)(u("root"),"inline-flex shrink-0 items-center justify-center",k.bgColor,k.textColor,k.borderColor,k.ringColor,c[h].rounded,c[h].border,c[h].shadow,c[h].ring,l[f].paddingX,l[f].paddingY,C)},v,w),r.default.createElement(o.default,Object.assign({text:b},x)),r.default.createElement(g,{className:(0,s.tremorTwMerge)(u("icon"),"shrink-0",d[f].height,d[f].width)}))});m.displayName="Icon",e.s(["default",0,m],728889)},752978,e=>{"use strict";var t=e.i(728889);e.s(["Icon",()=>t.default])},360820,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 15l7-7 7 7"}))});e.s(["ChevronUpIcon",0,r],360820)},871943,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"}))});e.s(["ChevronDownIcon",0,r],871943)},994388,e=>{"use strict";var t=e.i(290571),r=e.i(829087),o=e.i(271645);let a=["preEnter","entering","entered","preExit","exiting","exited","unmounted"],s=e=>({_s:e,status:a[e],isEnter:e<3,isMounted:6!==e,isResolved:2===e||e>4}),n=e=>e?6:5,i=(e,t,r,o,a)=>{clearTimeout(o.current);let n=s(e);t(n),r.current=n,a&&a({current:n})};var l=e.i(480731),d=e.i(444755),c=e.i(673706);let u=e=>{var r=(0,t.__rest)(e,[]);return o.default.createElement("svg",Object.assign({},r,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"}),o.default.createElement("path",{fill:"none",d:"M0 0h24v24H0z"}),o.default.createElement("path",{d:"M18.364 5.636L16.95 7.05A7 7 0 1 0 19 12h2a9 9 0 1 1-2.636-6.364z"}))};var m=e.i(95779);let g={xs:{height:"h-4",width:"w-4"},sm:{height:"h-5",width:"w-5"},md:{height:"h-5",width:"w-5"},lg:{height:"h-6",width:"w-6"},xl:{height:"h-6",width:"w-6"}},h=(e,t)=>{switch(e){case"primary":return{textColor:t?(0,c.getColorClassNames)("white").textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",hoverTextColor:t?(0,c.getColorClassNames)("white").textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:t?(0,c.getColorClassNames)(t,m.colorPalette.background).bgColor:"bg-tremor-brand dark:bg-dark-tremor-brand",hoverBgColor:t?(0,c.getColorClassNames)(t,m.colorPalette.darkBackground).hoverBgColor:"hover:bg-tremor-brand-emphasis dark:hover:bg-dark-tremor-brand-emphasis",borderColor:t?(0,c.getColorClassNames)(t,m.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand",hoverBorderColor:t?(0,c.getColorClassNames)(t,m.colorPalette.darkBorder).hoverBorderColor:"hover:border-tremor-brand-emphasis dark:hover:border-dark-tremor-brand-emphasis"};case"secondary":return{textColor:t?(0,c.getColorClassNames)(t,m.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",hoverTextColor:t?(0,c.getColorClassNames)(t,m.colorPalette.text).textColor:"hover:text-tremor-brand-emphasis dark:hover:text-dark-tremor-brand-emphasis",bgColor:(0,c.getColorClassNames)("transparent").bgColor,hoverBgColor:t?(0,d.tremorTwMerge)((0,c.getColorClassNames)(t,m.colorPalette.background).hoverBgColor,"hover:bg-opacity-20 dark:hover:bg-opacity-20"):"hover:bg-tremor-brand-faint dark:hover:bg-dark-tremor-brand-faint",borderColor:t?(0,c.getColorClassNames)(t,m.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand"};case"light":return{textColor:t?(0,c.getColorClassNames)(t,m.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",hoverTextColor:t?(0,c.getColorClassNames)(t,m.colorPalette.darkText).hoverTextColor:"hover:text-tremor-brand-emphasis dark:hover:text-dark-tremor-brand-emphasis",bgColor:(0,c.getColorClassNames)("transparent").bgColor,borderColor:"",hoverBorderColor:""}}},b=(0,c.makeClassName)("Button"),f=({loading:e,iconSize:t,iconPosition:r,Icon:a,needMargin:s,transitionStatus:n})=>{let i=s?r===l.HorizontalPositions.Left?(0,d.tremorTwMerge)("-ml-1","mr-1.5"):(0,d.tremorTwMerge)("-mr-1","ml-1.5"):"",c=(0,d.tremorTwMerge)("w-0 h-0"),m={default:c,entering:c,entered:t,exiting:t,exited:c};return e?o.default.createElement(u,{className:(0,d.tremorTwMerge)(b("icon"),"animate-spin shrink-0",i,m.default,m[n]),style:{transition:"width 150ms"}}):o.default.createElement(a,{className:(0,d.tremorTwMerge)(b("icon"),"shrink-0",t,i)})},p=o.default.forwardRef((e,a)=>{let{icon:u,iconPosition:m=l.HorizontalPositions.Left,size:p=l.Sizes.SM,color:C,variant:w="primary",disabled:k,loading:x=!1,loadingText:v,children:N,tooltip:y,className:M}=e,T=(0,t.__rest)(e,["icon","iconPosition","size","color","variant","disabled","loading","loadingText","children","tooltip","className"]),E=x||k,R=void 0!==u||x,P=x&&v,O=!(!N&&!P),j=(0,d.tremorTwMerge)(g[p].height,g[p].width),S="light"!==w?(0,d.tremorTwMerge)("rounded-tremor-default border","shadow-tremor-input","dark:shadow-dark-tremor-input"):"",z=h(w,C),L=("light"!==w?{xs:{paddingX:"px-2.5",paddingY:"py-1.5",fontSize:"text-xs"},sm:{paddingX:"px-4",paddingY:"py-2",fontSize:"text-sm"},md:{paddingX:"px-4",paddingY:"py-2",fontSize:"text-md"},lg:{paddingX:"px-4",paddingY:"py-2.5",fontSize:"text-lg"},xl:{paddingX:"px-4",paddingY:"py-3",fontSize:"text-xl"}}:{xs:{paddingX:"",paddingY:"",fontSize:"text-xs"},sm:{paddingX:"",paddingY:"",fontSize:"text-sm"},md:{paddingX:"",paddingY:"",fontSize:"text-md"},lg:{paddingX:"",paddingY:"",fontSize:"text-lg"},xl:{paddingX:"",paddingY:"",fontSize:"text-xl"}})[p],{tooltipProps:B,getReferenceProps:_}=(0,r.useTooltip)(300),[H,X]=(({enter:e=!0,exit:t=!0,preEnter:r,preExit:a,timeout:l,initialEntered:d,mountOnEnter:c,unmountOnExit:u,onStateChange:m}={})=>{let[g,h]=(0,o.useState)(()=>s(d?2:n(c))),b=(0,o.useRef)(g),f=(0,o.useRef)(0),[p,C]="object"==typeof l?[l.enter,l.exit]:[l,l],w=(0,o.useCallback)(()=>{let e=((e,t)=>{switch(e){case 1:case 0:return 2;case 4:case 3:return n(t)}})(b.current._s,u);e&&i(e,h,b,f,m)},[m,u]);return[g,(0,o.useCallback)(o=>{let s=e=>{switch(i(e,h,b,f,m),e){case 1:p>=0&&(f.current=((...e)=>setTimeout(...e))(w,p));break;case 4:C>=0&&(f.current=((...e)=>setTimeout(...e))(w,C));break;case 0:case 3:f.current=((...e)=>setTimeout(...e))(()=>{isNaN(document.body.offsetTop)||s(e+1)},0)}},l=b.current.isEnter;"boolean"!=typeof o&&(o=!l),o?l||s(e?+!r:2):l&&s(t?a?3:4:n(u))},[w,m,e,t,r,a,p,C,u]),w]})({timeout:50});return(0,o.useEffect)(()=>{X(x)},[x]),o.default.createElement("button",Object.assign({ref:(0,c.mergeRefs)([a,B.refs.setReference]),className:(0,d.tremorTwMerge)(b("root"),"shrink-0 inline-flex justify-center items-center group font-medium outline-none",S,L.paddingX,L.paddingY,L.fontSize,z.textColor,z.bgColor,z.borderColor,z.hoverBorderColor,E?"opacity-50 cursor-not-allowed":(0,d.tremorTwMerge)(h(w,C).hoverTextColor,h(w,C).hoverBgColor,h(w,C).hoverBorderColor),M),disabled:E},_,T),o.default.createElement(r.default,Object.assign({text:y},B)),R&&m!==l.HorizontalPositions.Right?o.default.createElement(f,{loading:x,iconSize:j,iconPosition:m,Icon:u,transitionStatus:H.status,needMargin:O}):null,P||N?o.default.createElement("span",{className:(0,d.tremorTwMerge)(b("text"),"text-tremor-default whitespace-nowrap")},P?v:N):null,R&&m===l.HorizontalPositions.Right?o.default.createElement(f,{loading:x,iconSize:j,iconPosition:m,Icon:u,transitionStatus:H.status,needMargin:O}):null)});p.displayName="Button",e.s(["Button",0,p],994388)},304967,e=>{"use strict";var t=e.i(290571),r=e.i(271645),o=e.i(480731),a=e.i(95779),s=e.i(444755),n=e.i(673706);let i=(0,n.makeClassName)("Card"),l=r.default.forwardRef((e,l)=>{let{decoration:d="",decorationColor:c,children:u,className:m}=e,g=(0,t.__rest)(e,["decoration","decorationColor","children","className"]);return r.default.createElement("div",Object.assign({ref:l,className:(0,s.tremorTwMerge)(i("root"),"relative w-full text-left ring-1 rounded-tremor-default p-6","bg-tremor-background ring-tremor-ring shadow-tremor-card","dark:bg-dark-tremor-background dark:ring-dark-tremor-ring dark:shadow-dark-tremor-card",c?(0,n.getColorClassNames)(c,a.colorPalette.border).borderColor:"border-tremor-brand dark:border-dark-tremor-brand",(e=>{if(!e)return"";switch(e){case o.HorizontalPositions.Left:return"border-l-4";case o.VerticalPositions.Top:return"border-t-4";case o.HorizontalPositions.Right:return"border-r-4";case o.VerticalPositions.Bottom:return"border-b-4";default:return""}})(d),m)},g),u)});l.displayName="Card",e.s(["Card",0,l],304967)},269200,e=>{"use strict";var t=e.i(290571),r=e.i(271645),o=e.i(444755);let a=(0,e.i(673706).makeClassName)("Table"),s=r.default.forwardRef((e,s)=>{let{children:n,className:i}=e,l=(0,t.__rest)(e,["children","className"]);return r.default.createElement("div",{className:(0,o.tremorTwMerge)(a("root"),"overflow-auto",i)},r.default.createElement("table",Object.assign({ref:s,className:(0,o.tremorTwMerge)(a("table"),"w-full text-tremor-default","text-tremor-content","dark:text-dark-tremor-content")},l),n))});s.displayName="Table",e.s(["Table",0,s],269200)},942232,e=>{"use strict";var t=e.i(290571),r=e.i(271645),o=e.i(444755);let a=(0,e.i(673706).makeClassName)("TableBody"),s=r.default.forwardRef((e,s)=>{let{children:n,className:i}=e,l=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("tbody",Object.assign({ref:s,className:(0,o.tremorTwMerge)(a("root"),"align-top divide-y","divide-tremor-border","dark:divide-dark-tremor-border",i)},l),n))});s.displayName="TableBody",e.s(["TableBody",0,s],942232)},977572,e=>{"use strict";var t=e.i(290571),r=e.i(271645),o=e.i(444755);let a=(0,e.i(673706).makeClassName)("TableCell"),s=r.default.forwardRef((e,s)=>{let{children:n,className:i}=e,l=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("td",Object.assign({ref:s,className:(0,o.tremorTwMerge)(a("root"),"align-middle whitespace-nowrap text-left p-4",i)},l),n))});s.displayName="TableCell",e.s(["TableCell",0,s],977572)},427612,e=>{"use strict";var t=e.i(290571),r=e.i(271645),o=e.i(444755);let a=(0,e.i(673706).makeClassName)("TableHead"),s=r.default.forwardRef((e,s)=>{let{children:n,className:i}=e,l=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("thead",Object.assign({ref:s,className:(0,o.tremorTwMerge)(a("root"),"text-left","text-tremor-content","dark:text-dark-tremor-content",i)},l),n))});s.displayName="TableHead",e.s(["TableHead",0,s],427612)},64848,e=>{"use strict";var t=e.i(290571),r=e.i(271645),o=e.i(444755);let a=(0,e.i(673706).makeClassName)("TableHeaderCell"),s=r.default.forwardRef((e,s)=>{let{children:n,className:i}=e,l=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("th",Object.assign({ref:s,className:(0,o.tremorTwMerge)(a("root"),"whitespace-nowrap text-left font-semibold top-0 px-4 py-3.5","text-tremor-content-strong","dark:text-dark-tremor-content-strong",i)},l),n))});s.displayName="TableHeaderCell",e.s(["TableHeaderCell",0,s],64848)},496020,e=>{"use strict";var t=e.i(290571),r=e.i(271645),o=e.i(444755);let a=(0,e.i(673706).makeClassName)("TableRow"),s=r.default.forwardRef((e,s)=>{let{children:n,className:i}=e,l=(0,t.__rest)(e,["children","className"]);return r.default.createElement(r.default.Fragment,null,r.default.createElement("tr",Object.assign({ref:s,className:(0,o.tremorTwMerge)(a("row"),i)},l),n))});s.displayName="TableRow",e.s(["TableRow",0,s],496020)},68155,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"}))});e.s(["TrashIcon",0,r],68155)},530212,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10 19l-7-7m0 0l7-7m-7 7h18"}))});e.s(["ArrowLeftIcon",0,r],530212)},91739,e=>{"use strict";var t=e.i(544195);e.s(["Radio",()=>t.default])},482725,e=>{"use strict";var t=e.i(244451);e.s(["Spin",()=>t.default])},536916,e=>{"use strict";var t=e.i(374276);e.s(["Checkbox",()=>t.default])},988297,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 4v16m8-8H4"}))});e.s(["PlusIcon",0,r],988297)},797672,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"}))});e.s(["PencilIcon",0,r],797672)},954616,e=>{"use strict";var t=e.i(271645),r=e.i(114272),o=e.i(540143),a=e.i(915823),s=e.i(619273),n=class extends a.Subscribable{#e;#t=void 0;#r;#o;constructor(e,t){super(),this.#e=e,this.setOptions(t),this.bindMethods(),this.#a()}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(e){let t=this.options;this.options=this.#e.defaultMutationOptions(e),(0,s.shallowEqualObjects)(this.options,t)||this.#e.getMutationCache().notify({type:"observerOptionsUpdated",mutation:this.#r,observer:this}),t?.mutationKey&&this.options.mutationKey&&(0,s.hashKey)(t.mutationKey)!==(0,s.hashKey)(this.options.mutationKey)?this.reset():this.#r?.state.status==="pending"&&this.#r.setOptions(this.options)}onUnsubscribe(){this.hasListeners()||this.#r?.removeObserver(this)}onMutationUpdate(e){this.#a(),this.#s(e)}getCurrentResult(){return this.#t}reset(){this.#r?.removeObserver(this),this.#r=void 0,this.#a(),this.#s()}mutate(e,t){return this.#o=t,this.#r?.removeObserver(this),this.#r=this.#e.getMutationCache().build(this.#e,this.options),this.#r.addObserver(this),this.#r.execute(e)}#a(){let e=this.#r?.state??(0,r.getDefaultState)();this.#t={...e,isPending:"pending"===e.status,isSuccess:"success"===e.status,isError:"error"===e.status,isIdle:"idle"===e.status,mutate:this.mutate,reset:this.reset}}#s(e){o.notifyManager.batch(()=>{if(this.#o&&this.hasListeners()){let t=this.#t.variables,r=this.#t.context,o={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};if(e?.type==="success"){try{this.#o.onSuccess?.(e.data,t,r,o)}catch(e){Promise.reject(e)}try{this.#o.onSettled?.(e.data,null,t,r,o)}catch(e){Promise.reject(e)}}else if(e?.type==="error"){try{this.#o.onError?.(e.error,t,r,o)}catch(e){Promise.reject(e)}try{this.#o.onSettled?.(void 0,e.error,t,r,o)}catch(e){Promise.reject(e)}}}this.listeners.forEach(e=>{e(this.#t)})})}},i=e.i(912598);e.s(["useMutation",0,function(e,r){let a=(0,i.useQueryClient)(r),[l]=t.useState(()=>new n(a,e));t.useEffect(()=>{l.setOptions(e)},[l,e]);let d=t.useSyncExternalStore(t.useCallback(e=>l.subscribe(o.notifyManager.batchCalls(e)),[l]),()=>l.getCurrentResult(),()=>l.getCurrentResult()),c=t.useCallback((e,t)=>{l.mutate(e,t).catch(s.noop)},[l]);if(d.error&&(0,s.shouldThrowError)(l.options.throwOnError,[d.error]))throw d.error;return{...d,mutate:c,mutateAsync:d.mutate}}],954616)},220508,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"}))});e.s(["CheckCircleIcon",0,r],220508)},888288,e=>{"use strict";var t=e.i(271645);e.s(["default",0,(e,r)=>{let o=void 0!==r,[a,s]=(0,t.useState)(e);return[o?r:a,e=>{o||s(e)}]}])},240647,e=>{"use strict";var t=e.i(286612);e.s(["RightOutlined",()=>t.default])},245704,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let o={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M699 353h-46.9c-10.2 0-19.9 4.9-25.9 13.3L469 584.3l-71.2-98.8c-6-8.3-15.6-13.3-25.9-13.3H325c-6.5 0-10.3 7.4-6.5 12.7l124.6 172.8a31.8 31.8 0 0051.7 0l210.6-292c3.9-5.3.1-12.7-6.4-12.7z"}},{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"}}]},name:"check-circle",theme:"outlined"};var a=e.i(9583),s=r.forwardRef(function(e,s){return r.createElement(a.default,(0,t.default)({},e,{ref:s,icon:o}))});e.s(["CheckCircleOutlined",0,s],245704)},518617,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let o={icon:{tag:"svg",attrs:{"fill-rule":"evenodd",viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm0 76c-205.4 0-372 166.6-372 372s166.6 372 372 372 372-166.6 372-372-166.6-372-372-372zm128.01 198.83c.03 0 .05.01.09.06l45.02 45.01a.2.2 0 01.05.09.12.12 0 010 .07c0 .02-.01.04-.05.08L557.25 512l127.87 127.86a.27.27 0 01.05.06v.02a.12.12 0 010 .07c0 .03-.01.05-.05.09l-45.02 45.02a.2.2 0 01-.09.05.12.12 0 01-.07 0c-.02 0-.04-.01-.08-.05L512 557.25 384.14 685.12c-.04.04-.06.05-.08.05a.12.12 0 01-.07 0c-.03 0-.05-.01-.09-.05l-45.02-45.02a.2.2 0 01-.05-.09.12.12 0 010-.07c0-.02.01-.04.06-.08L466.75 512 338.88 384.14a.27.27 0 01-.05-.06l-.01-.02a.12.12 0 010-.07c0-.03.01-.05.05-.09l45.02-45.02a.2.2 0 01.09-.05.12.12 0 01.07 0c.02 0 .04.01.08.06L512 466.75l127.86-127.86c.04-.05.06-.06.08-.06a.12.12 0 01.07 0z"}}]},name:"close-circle",theme:"outlined"};var a=e.i(9583),s=r.forwardRef(function(e,s){return r.createElement(a.default,(0,t.default)({},e,{ref:s,icon:o}))});e.s(["CloseCircleOutlined",0,s],518617)},848725,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"}),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"}))});e.s(["EyeIcon",0,r],848725)},78085,e=>{"use strict";var t=e.i(290571),r=e.i(103471),o=e.i(888288),a=e.i(271645),s=e.i(444755),n=e.i(673706);let i=(0,n.makeClassName)("Textarea"),l=a.default.forwardRef((e,l)=>{let{value:d,defaultValue:c="",placeholder:u="Type...",error:m=!1,errorMessage:g,disabled:h=!1,className:b,onChange:f,onValueChange:p,autoHeight:C=!1}=e,w=(0,t.__rest)(e,["value","defaultValue","placeholder","error","errorMessage","disabled","className","onChange","onValueChange","autoHeight"]),[k,x]=(0,o.default)(c,d),v=(0,a.useRef)(null),N=(0,r.hasValue)(k);return(0,a.useEffect)(()=>{let e=v.current;if(C&&e){e.style.height="60px";let t=e.scrollHeight;e.style.height=t+"px"}},[C,v,k]),a.default.createElement(a.default.Fragment,null,a.default.createElement("textarea",Object.assign({ref:(0,n.mergeRefs)([v,l]),value:k,placeholder:u,disabled:h,className:(0,s.tremorTwMerge)(i("Textarea"),"w-full flex items-center outline-none rounded-tremor-default px-3 py-2 text-tremor-default focus:ring-2 transition duration-100 border","shadow-tremor-input focus:border-tremor-brand-subtle focus:ring-tremor-brand-muted","dark:shadow-dark-tremor-input focus:dark:border-dark-tremor-brand-subtle focus:dark:ring-dark-tremor-brand-muted",(0,r.getSelectButtonColors)(N,h,m),h?"placeholder:text-tremor-content-subtle dark:placeholder:text-dark-tremor-content-subtle":"placeholder:text-tremor-content dark:placeholder:text-dark-tremor-content",b),"data-testid":"text-area",onChange:e=>{null==f||f(e),x(e.target.value),null==p||p(e.target.value)}},w)),m&&g?a.default.createElement("p",{className:(0,s.tremorTwMerge)(i("errorMessage"),"text-sm text-red-500 mt-1")},g):null)});l.displayName="Textarea",e.s(["Textarea",0,l],78085)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/03~yq9q893hmn.js b/litellm/proxy/_experimental/out/_next/static/chunks/03~yq9q893hmn.js new file mode 100644 index 00000000000..ab422b94a4f --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/03~yq9q893hmn.js @@ -0,0 +1 @@ +!function(){var t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function e(t){var e={exports:{}};return t(e,e.exports),e.exports}var r,n,o=function(t){return t&&t.Math===Math&&t},i=o("object"==typeof globalThis&&globalThis)||o("object"==typeof window&&window)||o("object"==typeof self&&self)||o("object"==typeof t&&t)||o("object"==typeof t&&t)||function(){return this}()||Function("return this")(),a=function(t){try{return!!t()}catch(t){return!0}},u=!a(function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]}),s=!a(function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")}),c=Function.prototype.call,f=s?c.bind(c):function(){return c.apply(c,arguments)},l={}.propertyIsEnumerable,h=Object.getOwnPropertyDescriptor,p=h&&!l.call({1:2},1)?function(t){var e=h(this,t);return!!e&&e.enumerable}:l,v={f:p},d=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}},g=Function.prototype,y=g.call,m=s&&g.bind.bind(y,y),b=s?m:function(t){return function(){return y.apply(t,arguments)}},w=b({}.toString),S=b("".slice),E=function(t){return S(w(t),8,-1)},O=Object,x=b("".split),R=a(function(){return!O("z").propertyIsEnumerable(0)})?function(t){return"String"===E(t)?x(t,""):O(t)}:O,P=function(t){return null==t},A=TypeError,j=function(t){if(P(t))throw new A("Can't call method on "+t);return t},k=function(t){return R(j(t))},I="object"==typeof document&&document.all,T=void 0===I&&void 0!==I?function(t){return"function"==typeof t||t===I}:function(t){return"function"==typeof t},M=function(t){return"object"==typeof t?null!==t:T(t)},L=function(t,e){return arguments.length<2?T(r=i[t])?r:void 0:i[t]&&i[t][e];var r},U=b({}.isPrototypeOf),N=i.navigator,C=N&&N.userAgent,_=C?String(C):"",F=i.process,B=i.Deno,D=F&&F.versions||B&&B.version,z=D&&D.v8;z&&(n=(r=z.split("."))[0]>0&&r[0]<4?1:+(r[0]+r[1])),!n&&_&&(!(r=_.match(/Edge\/(\d+)/))||r[1]>=74)&&(r=_.match(/Chrome\/(\d+)/))&&(n=+r[1]);var W=n,q=i.String,H=!!Object.getOwnPropertySymbols&&!a(function(){var t=Symbol("symbol detection");return!q(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&W&&W<41}),$=H&&!Symbol.sham&&"symbol"==typeof Symbol.iterator,K=Object,G=$?function(t){return"symbol"==typeof t}:function(t){var e=L("Symbol");return T(e)&&U(e.prototype,K(t))},V=String,Y=function(t){try{return V(t)}catch(t){return"Object"}},X=TypeError,J=function(t){if(T(t))return t;throw new X(Y(t)+" is not a function")},Q=function(t,e){var r=t[e];return P(r)?void 0:J(r)},Z=TypeError,tt=Object.defineProperty,et=function(t,e){try{tt(i,t,{value:e,configurable:!0,writable:!0})}catch(r){i[t]=e}return e},rt=e(function(t){var e="__core-js_shared__",r=t.exports=i[e]||et(e,{});(r.versions||(r.versions=[])).push({version:"3.38.1",mode:"global",copyright:"© 2014-2024 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.38.1/LICENSE",source:"https://github.com/zloirock/core-js"})}),nt=function(t,e){return rt[t]||(rt[t]=e||{})},ot=Object,it=function(t){return ot(j(t))},at=b({}.hasOwnProperty),ut=Object.hasOwn||function(t,e){return at(it(t),e)},st=0,ct=Math.random(),ft=b(1..toString),lt=function(t){return"Symbol("+(void 0===t?"":t)+")_"+ft(++st+ct,36)},ht=i.Symbol,pt=nt("wks"),vt=$?ht.for||ht:ht&&ht.withoutSetter||lt,dt=function(t){return ut(pt,t)||(pt[t]=H&&ut(ht,t)?ht[t]:vt("Symbol."+t)),pt[t]},gt=TypeError,yt=dt("toPrimitive"),mt=function(t,e){if(!M(t)||G(t))return t;var r,n=Q(t,yt);if(n){if(void 0===e&&(e="default"),r=f(n,t,e),!M(r)||G(r))return r;throw new gt("Can't convert object to primitive value")}return void 0===e&&(e="number"),function(t,e){var r,n;if("string"===e&&T(r=t.toString)&&!M(n=f(r,t)))return n;if(T(r=t.valueOf)&&!M(n=f(r,t)))return n;if("string"!==e&&T(r=t.toString)&&!M(n=f(r,t)))return n;throw new Z("Can't convert object to primitive value")}(t,e)},bt=function(t){var e=mt(t,"string");return G(e)?e:e+""},wt=i.document,St=M(wt)&&M(wt.createElement),Et=function(t){return St?wt.createElement(t):{}},Ot=!u&&!a(function(){return 7!==Object.defineProperty(Et("div"),"a",{get:function(){return 7}}).a}),xt=Object.getOwnPropertyDescriptor,Rt={f:u?xt:function(t,e){if(t=k(t),e=bt(e),Ot)try{return xt(t,e)}catch(t){}if(ut(t,e))return d(!f(v.f,t,e),t[e])}},Pt=u&&a(function(){return 42!==Object.defineProperty(function(){},"prototype",{value:42,writable:!1}).prototype}),At=String,jt=TypeError,kt=function(t){if(M(t))return t;throw new jt(At(t)+" is not an object")},It=TypeError,Tt=Object.defineProperty,Mt=Object.getOwnPropertyDescriptor,Lt="enumerable",Ut="configurable",Nt="writable",Ct={f:u?Pt?function(t,e,r){if(kt(t),e=bt(e),kt(r),"function"==typeof t&&"prototype"===e&&"value"in r&&Nt in r&&!r[Nt]){var n=Mt(t,e);n&&n[Nt]&&(t[e]=r.value,r={configurable:Ut in r?r[Ut]:n[Ut],enumerable:Lt in r?r[Lt]:n[Lt],writable:!1})}return Tt(t,e,r)}:Tt:function(t,e,r){if(kt(t),e=bt(e),kt(r),Ot)try{return Tt(t,e,r)}catch(t){}if("get"in r||"set"in r)throw new It("Accessors not supported");return"value"in r&&(t[e]=r.value),t}},_t=u?function(t,e,r){return Ct.f(t,e,d(1,r))}:function(t,e,r){return t[e]=r,t},Ft=Function.prototype,Bt=u&&Object.getOwnPropertyDescriptor,Dt=ut(Ft,"name"),zt={EXISTS:Dt,PROPER:Dt&&"something"===function(){}.name,CONFIGURABLE:Dt&&(!u||u&&Bt(Ft,"name").configurable)},Wt=b(Function.toString);T(rt.inspectSource)||(rt.inspectSource=function(t){return Wt(t)});var qt,Ht,$t,Kt=rt.inspectSource,Gt=i.WeakMap,Vt=T(Gt)&&/native code/.test(String(Gt)),Yt=nt("keys"),Xt=function(t){return Yt[t]||(Yt[t]=lt(t))},Jt={},Qt="Object already initialized",Zt=i.TypeError;if(Vt||rt.state){var te=rt.state||(rt.state=new(0,i.WeakMap));te.get=te.get,te.has=te.has,te.set=te.set,qt=function(t,e){if(te.has(t))throw new Zt(Qt);return e.facade=t,te.set(t,e),e},Ht=function(t){return te.get(t)||{}},$t=function(t){return te.has(t)}}else{var ee=Xt("state");Jt[ee]=!0,qt=function(t,e){if(ut(t,ee))throw new Zt(Qt);return e.facade=t,_t(t,ee,e),e},Ht=function(t){return ut(t,ee)?t[ee]:{}},$t=function(t){return ut(t,ee)}}var re,ne={set:qt,get:Ht,has:$t,enforce:function(t){return $t(t)?Ht(t):qt(t,{})},getterFor:function(t){return function(e){var r;if(!M(e)||(r=Ht(e)).type!==t)throw new Zt("Incompatible receiver, "+t+" required");return r}}},oe=e(function(t){var e=zt.CONFIGURABLE,r=ne.enforce,n=ne.get,o=String,i=Object.defineProperty,s=b("".slice),c=b("".replace),f=b([].join),l=u&&!a(function(){return 8!==i(function(){},"length",{value:8}).length}),h=String(String).split("String"),p=t.exports=function(t,n,a){"Symbol("===s(o(n),0,7)&&(n="["+c(o(n),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),a&&a.getter&&(n="get "+n),a&&a.setter&&(n="set "+n),(!ut(t,"name")||e&&t.name!==n)&&(u?i(t,"name",{value:n,configurable:!0}):t.name=n),l&&a&&ut(a,"arity")&&t.length!==a.arity&&i(t,"length",{value:a.arity});try{a&&ut(a,"constructor")&&a.constructor?u&&i(t,"prototype",{writable:!1}):t.prototype&&(t.prototype=void 0)}catch(t){}var p=r(t);return ut(p,"source")||(p.source=f(h,"string"==typeof n?n:"")),t};Function.prototype.toString=p(function(){return T(this)&&n(this).source||Kt(this)},"toString")}),ie=function(t,e,r,n){n||(n={});var o=n.enumerable,i=void 0!==n.name?n.name:e;if(T(r)&&oe(r,i,n),n.global)o?t[e]=r:et(e,r);else{try{n.unsafe?t[e]&&(o=!0):delete t[e]}catch(t){}o?t[e]=r:Ct.f(t,e,{value:r,enumerable:!1,configurable:!n.nonConfigurable,writable:!n.nonWritable})}return t},ae=Math.ceil,ue=Math.floor,se=Math.trunc||function(t){var e=+t;return(e>0?ue:ae)(e)},ce=function(t){var e=+t;return e!=e||0===e?0:se(e)},fe=Math.max,le=Math.min,he=function(t,e){var r=ce(t);return r<0?fe(r+e,0):le(r,e)},pe=Math.min,ve=function(t){var e=ce(t);return e>0?pe(e,9007199254740991):0},de=function(t){return ve(t.length)},ge=function(t){return function(e,r,n){var o=k(e),i=de(o);if(0===i)return!t&&-1;var a,u=he(n,i);if(t&&r!=r){for(;i>u;)if((a=o[u++])!=a)return!0}else for(;i>u;u++)if((t||u in o)&&o[u]===r)return t||u||0;return!t&&-1}},ye={includes:ge(!0),indexOf:ge(!1)},me=ye.indexOf,be=b([].push),we=function(t,e){var r,n=k(t),o=0,i=[];for(r in n)!ut(Jt,r)&&ut(n,r)&&be(i,r);for(;e.length>o;)ut(n,r=e[o++])&&(~me(i,r)||be(i,r));return i},Se=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],Ee=Se.concat("length","prototype"),Oe={f:Object.getOwnPropertyNames||function(t){return we(t,Ee)}},xe={f:Object.getOwnPropertySymbols},Re=b([].concat),Pe=L("Reflect","ownKeys")||function(t){var e=Oe.f(kt(t)),r=xe.f;return r?Re(e,r(t)):e},Ae=function(t,e,r){for(var n=Pe(e),o=Ct.f,i=Rt.f,a=0;aa;)Ct.f(t,r=o[a++],n[r]);return t},Be={f:Fe},De=L("document","documentElement"),ze="prototype",We="script",qe=Xt("IE_PROTO"),He=function(){},$e=function(t){return"<"+We+">"+t+""},Ke=function(t){t.write($e("")),t.close();var e=t.parentWindow.Object;return t=null,e},Ge=function(){try{re=new ActiveXObject("htmlfile")}catch(t){}var t,e,r;Ge="undefined"!=typeof document?document.domain&&re?Ke(re):(e=Et("iframe"),r="java"+We+":",e.style.display="none",De.appendChild(e),e.src=String(r),(t=e.contentWindow.document).open(),t.write($e("document.F=Object")),t.close(),t.F):Ke(re);for(var n=Se.length;n--;)delete Ge[ze][Se[n]];return Ge()};Jt[qe]=!0;var Ve=Object.create||function(t,e){var r;return null!==t?(He[ze]=kt(t),r=new He,He[ze]=null,r[qe]=t):r=Ge(),void 0===e?r:Be.f(r,e)},Ye=Ct.f,Xe=dt("unscopables"),Je=Array.prototype;void 0===Je[Xe]&&Ye(Je,Xe,{configurable:!0,value:Ve(null)});var Qe=function(t){Je[Xe][t]=!0};Ce({target:"Array",proto:!0},{at:function(t){var e=it(this),r=de(e),n=ce(t),o=n>=0?n:r+n;return o<0||o>=r?void 0:e[o]}}),Qe("at");var Ze=function(t,e){return b(i[t].prototype[e])},tr=(Ze("Array","at"),TypeError),er=function(t,e){if(!delete t[e])throw new tr("Cannot delete property "+Y(e)+" of "+Y(t))},rr=Math.min,nr=[].copyWithin||function(t,e){var r=it(this),n=de(r),o=he(t,n),i=he(e,n),a=arguments.length>2?arguments[2]:void 0,u=rr((void 0===a?n:he(a,n))-i,n-o),s=1;for(i0;)i in r?r[o]=r[i]:er(r,o),o+=s,i+=s;return r};Ce({target:"Array",proto:!0},{copyWithin:nr}),Qe("copyWithin"),Ze("Array","copyWithin"),Ce({target:"Array",proto:!0},{fill:function(t){for(var e=it(this),r=de(e),n=arguments.length,o=he(n>1?arguments[1]:void 0,r),i=n>2?arguments[2]:void 0,a=void 0===i?r:he(i,r);a>o;)e[o++]=t;return e}}),Qe("fill"),Ze("Array","fill");var or=function(t){if("Function"===E(t))return b(t)},ir=or(or.bind),ar=function(t,e){return J(t),void 0===e?t:s?ir(t,e):function(){return t.apply(e,arguments)}},ur=Array.isArray||function(t){return"Array"===E(t)},sr={};sr[dt("toStringTag")]="z";var cr="[object z]"===String(sr),fr=dt("toStringTag"),lr=Object,hr="Arguments"===E(function(){return arguments}()),pr=cr?E:function(t){var e,r,n;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(r=function(t,e){try{return t[e]}catch(t){}}(e=lr(t),fr))?r:hr?E(e):"Object"===(n=E(e))&&T(e.callee)?"Arguments":n},vr=function(){},dr=L("Reflect","construct"),gr=/^\s*(?:class|function)\b/,yr=b(gr.exec),mr=!gr.test(vr),br=function(t){if(!T(t))return!1;try{return dr(vr,[],t),!0}catch(t){return!1}},wr=function(t){if(!T(t))return!1;switch(pr(t)){case"AsyncFunction":case"GeneratorFunction":case"AsyncGeneratorFunction":return!1}try{return mr||!!yr(gr,Kt(t))}catch(t){return!0}};wr.sham=!0;var Sr=!dr||a(function(){var t;return br(br.call)||!br(Object)||!br(function(){t=!0})||t})?wr:br,Er=dt("species"),Or=Array,xr=function(t,e){return new(function(t){var e;return ur(t)&&(Sr(e=t.constructor)&&(e===Or||ur(e.prototype))||M(e)&&null===(e=e[Er]))&&(e=void 0),void 0===e?Or:e}(t))(0===e?0:e)},Rr=b([].push),Pr=function(t){var e=1===t,r=2===t,n=3===t,o=4===t,i=6===t,a=7===t,u=5===t||i;return function(s,c,f,l){for(var h,p,v=it(s),d=R(v),g=de(d),y=ar(c,f),m=0,b=l||xr,w=e?b(s,g):r||a?b(s,0):void 0;g>m;m++)if((u||m in d)&&(p=y(h=d[m],m,v),t))if(e)w[m]=p;else if(p)switch(t){case 3:return!0;case 5:return h;case 6:return m;case 2:Rr(w,h)}else switch(t){case 4:return!1;case 7:Rr(w,h)}return i?-1:n||o?o:w}},Ar={forEach:Pr(0),map:Pr(1),filter:Pr(2),some:Pr(3),every:Pr(4),find:Pr(5),findIndex:Pr(6),filterReject:Pr(7)},jr=Ar.find,kr="find",Ir=!0;kr in[]&&Array(1)[kr](function(){Ir=!1}),Ce({target:"Array",proto:!0,forced:Ir},{find:function(t){return jr(this,t,arguments.length>1?arguments[1]:void 0)}}),Qe(kr),Ze("Array","find");var Tr=Ar.findIndex,Mr="findIndex",Lr=!0;Mr in[]&&Array(1)[Mr](function(){Lr=!1}),Ce({target:"Array",proto:!0,forced:Lr},{findIndex:function(t){return Tr(this,t,arguments.length>1?arguments[1]:void 0)}}),Qe(Mr),Ze("Array","findIndex");var Ur=TypeError,Nr=function(t){if(t>9007199254740991)throw Ur("Maximum allowed index exceeded");return t},Cr=function(t,e,r,n,o,i,a,u){for(var s,c,f=o,l=0,h=!!a&&ar(a,u);l0&&ur(s)?(c=de(s),f=Cr(t,e,s,c,f,i-1)-1):(Nr(f+1),t[f]=s),f++),l++;return f},_r=Cr;Ce({target:"Array",proto:!0},{flatMap:function(t){var e,r=it(this),n=de(r);return J(t),(e=xr(r,0)).length=_r(e,r,r,n,0,1,t,arguments.length>1?arguments[1]:void 0),e}}),Qe("flatMap"),Ze("Array","flatMap"),Ce({target:"Array",proto:!0},{flat:function(){var t=arguments.length?arguments[0]:void 0,e=it(this),r=de(e),n=xr(e,0);return n.length=_r(n,e,e,r,0,void 0===t?1:ce(t)),n}}),Qe("flat"),Ze("Array","flat");var Fr,Br,Dr,zr=String,Wr=function(t){if("Symbol"===pr(t))throw new TypeError("Cannot convert a Symbol value to a string");return zr(t)},qr=b("".charAt),Hr=b("".charCodeAt),$r=b("".slice),Kr=function(t){return function(e,r){var n,o,i=Wr(j(e)),a=ce(r),u=i.length;return a<0||a>=u?t?"":void 0:(n=Hr(i,a))<55296||n>56319||a+1===u||(o=Hr(i,a+1))<56320||o>57343?t?qr(i,a):n:t?$r(i,a,a+2):o-56320+(n-55296<<10)+65536}},Gr={codeAt:Kr(!1),charAt:Kr(!0)},Vr=!a(function(){function t(){}return t.prototype.constructor=null,Object.getPrototypeOf(new t)!==t.prototype}),Yr=Xt("IE_PROTO"),Xr=Object,Jr=Xr.prototype,Qr=Vr?Xr.getPrototypeOf:function(t){var e=it(t);if(ut(e,Yr))return e[Yr];var r=e.constructor;return T(r)&&e instanceof r?r.prototype:e instanceof Xr?Jr:null},Zr=dt("iterator"),tn=!1;[].keys&&("next"in(Dr=[].keys())?(Br=Qr(Qr(Dr)))!==Object.prototype&&(Fr=Br):tn=!0);var en=!M(Fr)||a(function(){var t={};return Fr[Zr].call(t)!==t});en&&(Fr={}),T(Fr[Zr])||ie(Fr,Zr,function(){return this});var rn={IteratorPrototype:Fr,BUGGY_SAFARI_ITERATORS:tn},nn=Ct.f,on=dt("toStringTag"),an=function(t,e,r){t&&!r&&(t=t.prototype),t&&!ut(t,on)&&nn(t,on,{configurable:!0,value:e})},un={},sn=rn.IteratorPrototype,cn=function(){return this},fn=function(t,e,r,n){var o=e+" Iterator";return t.prototype=Ve(sn,{next:d(+!n,r)}),an(t,o,!1),un[o]=cn,t},ln=function(t,e,r){try{return b(J(Object.getOwnPropertyDescriptor(t,e)[r]))}catch(t){}},hn=String,pn=TypeError,vn=function(t){if(function(t){return M(t)||null===t}(t))return t;throw new pn("Can't set "+hn(t)+" as a prototype")},dn=Object.setPrototypeOf||("__proto__"in{}?function(){var t,e=!1,r={};try{(t=ln(Object.prototype,"__proto__","set"))(r,[]),e=r instanceof Array}catch(t){}return function(r,n){return j(r),vn(n),M(r)?(e?t(r,n):r.__proto__=n,r):r}}():void 0),gn=zt.PROPER,yn=zt.CONFIGURABLE,mn=rn.IteratorPrototype,bn=rn.BUGGY_SAFARI_ITERATORS,wn=dt("iterator"),Sn="keys",En="values",On="entries",xn=function(){return this},Rn=function(t,e,r,n,o,i,a){fn(r,e,n);var u,s,c,l=function(t){if(t===o&&g)return g;if(!bn&&t&&t in v)return v[t];switch(t){case Sn:case En:case On:return function(){return new r(this,t)}}return function(){return new r(this)}},h=e+" Iterator",p=!1,v=t.prototype,d=v[wn]||v["@@iterator"]||o&&v[o],g=!bn&&d||l(o),y="Array"===e&&v.entries||d;if(y&&(u=Qr(y.call(new t)))!==Object.prototype&&u.next&&(Qr(u)!==mn&&(dn?dn(u,mn):T(u[wn])||ie(u,wn,xn)),an(u,h,!0)),gn&&o===En&&d&&d.name!==En&&(yn?_t(v,"name",En):(p=!0,g=function(){return f(d,this)})),o)if(s={values:l(En),keys:i?g:l(Sn),entries:l(On)},a)for(c in s)(bn||p||!(c in v))&&ie(v,c,s[c]);else Ce({target:e,proto:!0,forced:bn||p},s);return v[wn]!==g&&ie(v,wn,g,{name:o}),un[e]=g,s},Pn=function(t,e){return{value:t,done:e}},An=Gr.charAt,jn="String Iterator",kn=ne.set,In=ne.getterFor(jn);Rn(String,"String",function(t){kn(this,{type:jn,string:Wr(t),index:0})},function(){var t,e=In(this),r=e.string,n=e.index;return n>=r.length?Pn(void 0,!0):(t=An(r,n),e.index+=t.length,Pn(t,!1))});var Tn=function(t,e,r){var n,o;kt(t);try{if(!(n=Q(t,"return"))){if("throw"===e)throw r;return r}n=f(n,t)}catch(t){o=!0,n=t}if("throw"===e)throw r;if(o)throw n;return kt(n),r},Mn=function(t,e,r,n){try{return n?e(kt(r)[0],r[1]):e(r)}catch(e){Tn(t,"throw",e)}},Ln=dt("iterator"),Un=Array.prototype,Nn=function(t){return void 0!==t&&(un.Array===t||Un[Ln]===t)},Cn=function(t,e,r){u?Ct.f(t,e,d(0,r)):t[e]=r},_n=dt("iterator"),Fn=function(t){if(!P(t))return Q(t,_n)||Q(t,"@@iterator")||un[pr(t)]},Bn=TypeError,Dn=function(t,e){var r=arguments.length<2?Fn(t):e;if(J(r))return kt(f(r,t));throw new Bn(Y(t)+" is not iterable")},zn=Array,Wn=function(t){var e=it(t),r=Sr(this),n=arguments.length,o=n>1?arguments[1]:void 0,i=void 0!==o;i&&(o=ar(o,n>2?arguments[2]:void 0));var a,u,s,c,l,h,p=Fn(e),v=0;if(!p||this===zn&&Nn(p))for(a=de(e),u=r?new this(a):zn(a);a>v;v++)h=i?o(e[v],v):e[v],Cn(u,v,h);else for(u=r?new this:[],l=(c=Dn(e,p)).next;!(s=f(l,c)).done;v++)h=i?Mn(c,o,[s.value,v],!0):s.value,Cn(u,v,h);return u.length=v,u},qn=dt("iterator"),Hn=!1;try{var $n=0,Kn={next:function(){return{done:!!$n++}},return:function(){Hn=!0}};Kn[qn]=function(){return this},Array.from(Kn,function(){throw 2})}catch(t){}var Gn=function(t,e){try{if(!e&&!Hn)return!1}catch(t){return!1}var r=!1;try{var n={};n[qn]=function(){return{next:function(){return{done:r=!0}}}},t(n)}catch(t){}return r},Vn=!Gn(function(t){Array.from(t)});Ce({target:"Array",stat:!0,forced:Vn},{from:Wn});var Yn=i,Xn=ye.includes,Jn=a(function(){return!Array(1).includes()});Ce({target:"Array",proto:!0,forced:Jn},{includes:function(t){return Xn(this,t,arguments.length>1?arguments[1]:void 0)}}),Qe("includes"),Ze("Array","includes");var Qn=Ct.f,Zn="Array Iterator",to=ne.set,eo=ne.getterFor(Zn),ro=Rn(Array,"Array",function(t,e){to(this,{type:Zn,target:k(t),index:0,kind:e})},function(){var t=eo(this),e=t.target,r=t.index++;if(!e||r>=e.length)return t.target=null,Pn(void 0,!0);switch(t.kind){case"keys":return Pn(r,!1);case"values":return Pn(e[r],!1)}return Pn([r,e[r]],!1)},"values"),no=un.Arguments=un.Array;if(Qe("keys"),Qe("values"),Qe("entries"),u&&"values"!==no.name)try{Qn(no,"name",{value:"values"})}catch(t){}cr||ie(Object.prototype,"toString",cr?{}.toString:function(){return"[object "+pr(this)+"]"},{unsafe:!0}),Ze("Array","values");var oo=Array,io=a(function(){function t(){}return!(oo.of.call(t)instanceof t)});Ce({target:"Array",stat:!0,forced:io},{of:function(){for(var t=0,e=arguments.length,r=new(Sr(this)?this:oo)(e);e>t;)Cn(r,t,arguments[t++]);return r.length=e,r}});var ao=dt("hasInstance"),uo=Function.prototype;ao in uo||Ct.f(uo,ao,{value:oe(function(t){if(!T(this)||!M(t))return!1;var e=this.prototype;return M(e)?U(e,t):t instanceof this},ao)}),dt("hasInstance");var so=function(t,e,r){return r.get&&oe(r.get,e,{getter:!0}),r.set&&oe(r.set,e,{setter:!0}),Ct.f(t,e,r)},co=zt.EXISTS,fo=Function.prototype,lo=b(fo.toString),ho=/function\b(?:\s|\/\*[\S\s]*?\*\/|\/\/[^\n\r]*[\n\r]+)*([^\s(/]*)/,po=b(ho.exec);u&&!co&&so(fo,"name",{configurable:!0,get:function(){try{return po(ho,lo(this))[1]}catch(t){return""}}});var vo=b([].slice),go=Oe.f,yo="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],mo={f:function(t){return yo&&"Window"===E(t)?function(t){try{return go(t)}catch(t){return vo(yo)}}(t):go(k(t))}},bo=a(function(){if("function"==typeof ArrayBuffer){var t=new ArrayBuffer(8);Object.isExtensible(t)&&Object.defineProperty(t,"a",{value:8})}}),wo=Object.isExtensible,So=a(function(){wo(1)})||bo?function(t){return!!M(t)&&(!bo||"ArrayBuffer"!==E(t))&&(!wo||wo(t))}:wo,Eo=!a(function(){return Object.isExtensible(Object.preventExtensions({}))}),Oo=e(function(t){var e=Ct.f,r=!1,n=lt("meta"),o=0,i=function(t){e(t,n,{value:{objectID:"O"+o++,weakData:{}}})},a=t.exports={enable:function(){a.enable=function(){},r=!0;var t=Oe.f,e=b([].splice),o={};o[n]=1,t(o).length&&(Oe.f=function(r){for(var o=t(r),i=0,a=o.length;ii;i++)if((u=y(t[i]))&&U(Po,u))return u;return new Ro(!1)}n=Dn(t,o)}for(s=h?t.next:n.next;!(c=f(s,n)).done;){try{u=y(c.value)}catch(t){Tn(n,"throw",t)}if("object"==typeof u&&u&&U(Po,u))return u}return new Ro(!1)},jo=TypeError,ko=function(t,e){if(U(e,t))return t;throw new jo("Incorrect invocation")},Io=function(t,e,r){var n,o;return dn&&T(n=e.constructor)&&n!==r&&M(o=n.prototype)&&o!==r.prototype&&dn(t,o),t},To=function(t,e,r){var n=-1!==t.indexOf("Map"),o=-1!==t.indexOf("Weak"),u=n?"set":"add",s=i[t],c=s&&s.prototype,f=s,l={},h=function(t){var e=b(c[t]);ie(c,t,"add"===t?function(t){return e(this,0===t?0:t),this}:"delete"===t?function(t){return!(o&&!M(t))&&e(this,0===t?0:t)}:"get"===t?function(t){return o&&!M(t)?void 0:e(this,0===t?0:t)}:"has"===t?function(t){return!(o&&!M(t))&&e(this,0===t?0:t)}:function(t,r){return e(this,0===t?0:t,r),this})};if(Ue(t,!T(s)||!(o||c.forEach&&!a(function(){(new s).entries().next()}))))f=r.getConstructor(e,t,n,u),Oo.enable();else if(Ue(t,!0)){var p=new f,v=p[u](o?{}:-0,1)!==p,d=a(function(){p.has(1)}),g=Gn(function(t){new s(t)}),y=!o&&a(function(){for(var t=new s,e=5;e--;)t[u](e,e);return!t.has(-0)});g||((f=e(function(t,e){ko(t,c);var r=Io(new s,t,f);return P(e)||Ao(e,r[u],{that:r,AS_ENTRIES:n}),r})).prototype=c,c.constructor=f),(d||y)&&(h("delete"),h("has"),n&&h("get")),(y||v)&&h(u),o&&c.clear&&delete c.clear}return l[t]=f,Ce({global:!0,constructor:!0,forced:f!==s},l),an(f,t),o||r.setStrong(f,t,n),f},Mo=function(t,e,r){for(var n in e)ie(t,n,e[n],r);return t},Lo=dt("species"),Uo=function(t){var e=L(t);u&&e&&!e[Lo]&&so(e,Lo,{configurable:!0,get:function(){return this}})},No=Oo.fastKey,Co=ne.set,_o=ne.getterFor,Fo={getConstructor:function(t,e,r,n){var o=t(function(t,o){ko(t,i),Co(t,{type:e,index:Ve(null),first:null,last:null,size:0}),u||(t.size=0),P(o)||Ao(o,t[n],{that:t,AS_ENTRIES:r})}),i=o.prototype,a=_o(e),s=function(t,e,r){var n,o,i=a(t),s=c(t,e);return s?s.value=r:(i.last=s={index:o=No(e,!0),key:e,value:r,previous:n=i.last,next:null,removed:!1},i.first||(i.first=s),n&&(n.next=s),u?i.size++:t.size++,"F"!==o&&(i.index[o]=s)),t},c=function(t,e){var r,n=a(t),o=No(e);if("F"!==o)return n.index[o];for(r=n.first;r;r=r.next)if(r.key===e)return r};return Mo(i,{clear:function(){for(var t=a(this),e=t.first;e;)e.removed=!0,e.previous&&(e.previous=e.previous.next=null),e=e.next;t.first=t.last=null,t.index=Ve(null),u?t.size=0:this.size=0},delete:function(t){var e=this,r=a(e),n=c(e,t);if(n){var o=n.next,i=n.previous;delete r.index[n.index],n.removed=!0,i&&(i.next=o),o&&(o.previous=i),r.first===n&&(r.first=o),r.last===n&&(r.last=i),u?r.size--:e.size--}return!!n},forEach:function(t){for(var e,r=a(this),n=ar(t,arguments.length>1?arguments[1]:void 0);e=e?e.next:r.first;)for(n(e.value,e.key,this);e&&e.removed;)e=e.previous},has:function(t){return!!c(this,t)}}),Mo(i,r?{get:function(t){var e=c(this,t);return e&&e.value},set:function(t,e){return s(this,0===t?0:t,e)}}:{add:function(t){return s(this,t=0===t?0:t,t)}}),u&&so(i,"size",{configurable:!0,get:function(){return a(this).size}}),o},setStrong:function(t,e,r){var n=e+" Iterator",o=_o(e),i=_o(n);Rn(t,e,function(t,e){Co(this,{type:n,target:t,state:o(t),kind:e,last:null})},function(){for(var t=i(this),e=t.kind,r=t.last;r&&r.removed;)r=r.previous;return t.target&&(t.last=r=r?r.next:t.state.first)?Pn("keys"===e?r.key:"values"===e?r.value:[r.key,r.value],!1):(t.target=null,Pn(void 0,!0))},r?"entries":"values",!r,!0),Uo(e)}};To("Map",function(t){return function(){return t(this,arguments.length?arguments[0]:void 0)}},Fo);var Bo=Map.prototype,Do={Map:Map,set:b(Bo.set),get:b(Bo.get),has:b(Bo.has),remove:b(Bo.delete),proto:Bo},zo=Do.Map,Wo=Do.has,qo=Do.get,Ho=Do.set,$o=b([].push),Ko=a(function(){return 1!==zo.groupBy("ab",function(t){return t}).get("a").length});Ce({target:"Map",stat:!0,forced:Ko},{groupBy:function(t,e){j(t),J(e);var r=new zo,n=0;return Ao(t,function(t){var o=e(t,n++);Wo(r,o)?$o(qo(r,o),t):Ho(r,o,[t])}),r}});var Go={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0},Vo=Et("span").classList,Yo=Vo&&Vo.constructor&&Vo.constructor.prototype,Xo=Yo===Object.prototype?void 0:Yo,Jo=dt("iterator"),Qo=ro.values,Zo=function(t,e){if(t){if(t[Jo]!==Qo)try{_t(t,Jo,Qo)}catch(e){t[Jo]=Qo}if(an(t,e,!0),Go[e])for(var r in ro)if(t[r]!==ro[r])try{_t(t,r,ro[r])}catch(e){t[r]=ro[r]}}};for(var ti in Go)Zo(i[ti]&&i[ti].prototype,ti);Zo(Xo,"DOMTokenList");var ei=function(t,e,r){return function(n){var o=it(n),i=arguments.length,a=i>1?arguments[1]:void 0,u=void 0!==a,s=u?ar(a,i>2?arguments[2]:void 0):void 0,c=new t,f=0;return Ao(o,function(t){var n=u?s(t,f++):t;r?e(c,kt(n)[0],n[1]):e(c,n)}),c}};Ce({target:"Map",stat:!0,forced:!0},{from:ei(Do.Map,Do.set,!0)});var ri=function(t,e,r){return function(){for(var n=new t,o=arguments.length,i=0;i1?arguments[1]:void 0);return!1!==di(e,function(t,n){if(!r(t,n,e))return!1},!0)}});var gi=Do.Map,yi=Do.set;Ce({target:"Map",proto:!0,real:!0,forced:!0},{filter:function(t){var e=oi(this),r=ar(t,arguments.length>1?arguments[1]:void 0),n=new gi;return di(e,function(t,o){r(t,o,e)&&yi(n,o,t)}),n}}),Ce({target:"Map",proto:!0,real:!0,forced:!0},{find:function(t){var e=oi(this),r=ar(t,arguments.length>1?arguments[1]:void 0),n=di(e,function(t,n){if(r(t,n,e))return{value:t}},!0);return n&&n.value}}),Ce({target:"Map",proto:!0,real:!0,forced:!0},{findKey:function(t){var e=oi(this),r=ar(t,arguments.length>1?arguments[1]:void 0),n=di(e,function(t,n){if(r(t,n,e))return{key:n}},!0);return n&&n.key}}),Ce({target:"Map",proto:!0,real:!0,forced:!0},{includes:function(t){return!0===di(oi(this),function(e){if((r=e)===(n=t)||r!=r&&n!=n)return!0;var r,n},!0)}});var mi=Do.Map;Ce({target:"Map",stat:!0,forced:!0},{keyBy:function(t,e){var r=new(T(this)?this:mi);J(e);var n=J(r.set);return Ao(t,function(t){f(n,r,e(t),t)}),r}}),Ce({target:"Map",proto:!0,real:!0,forced:!0},{keyOf:function(t){var e=di(oi(this),function(e,r){if(e===t)return{key:r}},!0);return e&&e.key}});var bi=Do.Map,wi=Do.set;Ce({target:"Map",proto:!0,real:!0,forced:!0},{mapKeys:function(t){var e=oi(this),r=ar(t,arguments.length>1?arguments[1]:void 0),n=new bi;return di(e,function(t,o){wi(n,r(t,o,e),t)}),n}});var Si=Do.Map,Ei=Do.set;Ce({target:"Map",proto:!0,real:!0,forced:!0},{mapValues:function(t){var e=oi(this),r=ar(t,arguments.length>1?arguments[1]:void 0),n=new Si;return di(e,function(t,o){Ei(n,o,r(t,o,e))}),n}});var Oi=Do.set;Ce({target:"Map",proto:!0,real:!0,arity:1,forced:!0},{merge:function(t){for(var e=oi(this),r=arguments.length,n=0;n1?arguments[1]:void 0);return!0===di(e,function(t,n){if(r(t,n,e))return!0},!0)}});var Ri=TypeError,Pi=Do.get,Ai=Do.has,ji=Do.set;Ce({target:"Map",proto:!0,real:!0,forced:!0},{update:function(t,e){var r=oi(this),n=arguments.length;J(e);var o=Ai(r,t);if(!o&&n<3)throw new Ri("Updating absent value");var i=o?Pi(r,t):J(n>2?arguments[2]:void 0)(t,r);return ji(r,t,e(i,t,r)),r}});var ki=TypeError,Ii=function(t,e){var r,n=kt(this),o=J(n.get),i=J(n.has),a=J(n.set),u=arguments.length>2?arguments[2]:void 0;if(!T(e)&&!T(u))throw new ki("At least one callback required");return f(i,n,t)?(r=f(o,n,t),T(e)&&(r=e(r),f(a,n,t,r))):T(u)&&(r=u(),f(a,n,t,r)),r};Ce({target:"Map",proto:!0,real:!0,forced:!0},{upsert:Ii}),Ce({target:"Map",proto:!0,real:!0,name:"upsert",forced:!0},{updateOrInsert:Ii});var Ti=b(1..valueOf),Mi="\t\n\v\f\r                 \u2028\u2029\ufeff",Li=b("".replace),Ui=RegExp("^["+Mi+"]+"),Ni=RegExp("(^|[^"+Mi+"])["+Mi+"]+$"),Ci=function(t){return function(e){var r=Wr(j(e));return 1&t&&(r=Li(r,Ui,"")),2&t&&(r=Li(r,Ni,"$1")),r}},_i={start:Ci(1),end:Ci(2),trim:Ci(3)},Fi=Oe.f,Bi=Rt.f,Di=Ct.f,zi=_i.trim,Wi="Number",qi=i[Wi],Hi=qi.prototype,$i=i.TypeError,Ki=b("".slice),Gi=b("".charCodeAt),Vi=Ue(Wi,!qi(" 0o1")||!qi("0b1")||qi("+0x1")),Yi=function(t){var e,r=arguments.length<1?0:qi(function(t){var e=mt(t,"number");return"bigint"==typeof e?e:function(t){var e,r,n,o,i,a,u,s,c=mt(t,"number");if(G(c))throw new $i("Cannot convert a Symbol value to a number");if("string"==typeof c&&c.length>2)if(c=zi(c),43===(e=Gi(c,0))||45===e){if(88===(r=Gi(c,2))||120===r)return NaN}else if(48===e){switch(Gi(c,1)){case 66:case 98:n=2,o=49;break;case 79:case 111:n=8,o=55;break;default:return+c}for(a=(i=Ki(c,2)).length,u=0;uo)return NaN;return parseInt(i,n)}return+c}(e)}(t));return U(Hi,e=this)&&a(function(){Ti(e)})?Io(Object(r),this,Yi):r};Yi.prototype=Hi,Vi&&(Hi.constructor=Yi),Ce({global:!0,constructor:!0,wrap:!0,forced:Vi},{Number:Yi}),Vi&&function(t,e){for(var r,n=u?Fi(e):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,isFinite,isInteger,isNaN,isSafeInteger,parseFloat,parseInt,fromString,range".split(","),o=0;n.length>o;o++)ut(e,r=n[o])&&!ut(t,r)&&Di(t,r,Bi(e,r))}(Yn[Wi],qi),Ce({target:"Number",stat:!0,nonConfigurable:!0,nonWritable:!0},{EPSILON:Math.pow(2,-52)});var Xi=i.isFinite;Ce({target:"Number",stat:!0},{isFinite:Number.isFinite||function(t){return"number"==typeof t&&Xi(t)}});var Ji=Math.floor,Qi=Number.isInteger||function(t){return!M(t)&&isFinite(t)&&Ji(t)===t};Ce({target:"Number",stat:!0},{isInteger:Qi}),Ce({target:"Number",stat:!0},{isNaN:function(t){return t!=t}});var Zi=Math.abs;Ce({target:"Number",stat:!0},{isSafeInteger:function(t){return Qi(t)&&Zi(t)<=9007199254740991}}),Ce({target:"Number",stat:!0,nonConfigurable:!0,nonWritable:!0},{MAX_SAFE_INTEGER:9007199254740991}),Ce({target:"Number",stat:!0,nonConfigurable:!0,nonWritable:!0},{MIN_SAFE_INTEGER:-9007199254740991});var ta=_i.trim,ea=b("".charAt),ra=i.parseFloat,na=i.Symbol,oa=na&&na.iterator,ia=1/ra(Mi+"-0")!=-Infinity||oa&&!a(function(){ra(Object(oa))})?function(t){var e=ta(Wr(t)),r=ra(e);return 0===r&&"-"===ea(e,0)?-0:r}:ra;Ce({target:"Number",stat:!0,forced:Number.parseFloat!==ia},{parseFloat:ia});var aa=_i.trim,ua=i.parseInt,sa=i.Symbol,ca=sa&&sa.iterator,fa=/^[+-]?0x/i,la=b(fa.exec),ha=8!==ua(Mi+"08")||22!==ua(Mi+"0x16")||ca&&!a(function(){ua(Object(ca))})?function(t,e){var r=aa(Wr(t));return ua(r,e>>>0||(la(fa,r)?16:10))}:ua;Ce({target:"Number",stat:!0,forced:Number.parseInt!==ha},{parseInt:ha});var pa=b(v.f),va=b([].push),da=u&&a(function(){var t=Object.create(null);return t[2]=2,!pa(t,2)}),ga=function(t){return function(e){for(var r,n=k(e),o=_e(n),i=da&&null===Qr(n),a=o.length,s=0,c=[];a>s;)r=o[s++],u&&!(i?r in n:pa(n,r))||va(c,t?[r,n[r]]:n[r]);return c}},ya={entries:ga(!0),values:ga(!1)},ma=ya.entries;Ce({target:"Object",stat:!0},{entries:function(t){return ma(t)}}),Ce({target:"Object",stat:!0,sham:!u},{getOwnPropertyDescriptors:function(t){for(var e,r,n=k(t),o=Rt.f,i=Pe(n),a={},u=0;i.length>u;)void 0!==(r=o(n,e=i[u++]))&&Cn(a,e,r);return a}});var ba=a(function(){_e(1)});Ce({target:"Object",stat:!0,forced:ba},{keys:function(t){return _e(it(t))}});var wa=Object.is||function(t,e){return t===e?0!==t||1/t==1/e:t!=t&&e!=e};Ce({target:"Object",stat:!0},{is:wa});var Sa=ya.values;Ce({target:"Object",stat:!0},{values:function(t){return Sa(t)}}),Ce({target:"Object",stat:!0},{hasOwn:ut});var Ea=Function.prototype,Oa=Ea.apply,xa=Ea.call,Ra="object"==typeof Reflect&&Reflect.apply||(s?xa.bind(Oa):function(){return xa.apply(Oa,arguments)}),Pa=!a(function(){Reflect.apply(function(){})});Ce({target:"Reflect",stat:!0,forced:Pa},{apply:function(t,e,r){return Ra(J(t),e,kt(r))}});var Aa=Function,ja=b([].concat),ka=b([].join),Ia={},Ta=s?Aa.bind:function(t){var e=J(this),r=e.prototype,n=vo(arguments,1),o=function(){var r=ja(n,vo(arguments));return this instanceof o?function(t,e,r){if(!ut(Ia,e)){for(var n=[],o=0;ob)","g");return"b"!==t.exec("b").groups.a||"bc"!=="b".replace(t,"$c")}),gs=Oe.f,ys=ne.enforce,ms=dt("match"),bs=i.RegExp,ws=bs.prototype,Ss=i.SyntaxError,Es=b(ws.exec),Os=b("".charAt),xs=b("".replace),Rs=b("".indexOf),Ps=b("".slice),As=/^\?<[^\s\d!#%&*+<=>@^][^\s!#%&*+<=>@^]*>/,js=/a/g,ks=/a/g,Is=new bs(js)!==js,Ts=cs.MISSED_STICKY,Ms=cs.UNSUPPORTED_Y,Ls=u&&(!Is||Ts||ps||ds||a(function(){return ks[ms]=!1,bs(js)!==js||bs(ks)===ks||"/a/i"!==String(bs(js,"i"))}));if(Ue("RegExp",Ls)){for(var Us=function(t,e){var r,n,o,i,a,u,s=U(ws,this),c=es(t),f=void 0===e,l=[],h=t;if(!s&&c&&f&&t.constructor===Us)return t;if((c||U(ws,t))&&(t=t.source,f&&(e=os(h))),t=void 0===t?"":Wr(t),e=void 0===e?"":Wr(e),h=t,ps&&"dotAll"in js&&(n=!!e&&Rs(e,"s")>-1)&&(e=xs(e,/s/g,"")),r=e,Ts&&"sticky"in js&&(o=!!e&&Rs(e,"y")>-1)&&Ms&&(e=xs(e,/y/g,"")),ds&&(i=function(t){for(var e,r=t.length,n=0,o="",i=[],a=Ve(null),u=!1,s=!1,c=0,f="";n<=r;n++){if("\\"===(e=Os(t,n)))e+=Os(t,++n);else if("]"===e)u=!1;else if(!u)switch(!0){case"["===e:u=!0;break;case"("===e:if(o+=e,"?:"===Ps(t,n+1,n+3))continue;Es(As,Ps(t,n+1))&&(n+=2,s=!0),c++;continue;case">"===e&&s:if(""===f||ut(a,f))throw new Ss("Invalid capture group name");a[f]=!0,i[i.length]=[f,c],s=!1,f="";continue}s?f+=e:o+=e}return[o,i]}(t),t=i[0],l=i[1]),a=Io(bs(t,e),s?this:ws,Us),(n||o||l.length)&&(u=ys(a),n&&(u.dotAll=!0,u.raw=Us(function(t){for(var e,r=t.length,n=0,o="",i=!1;n<=r;n++)"\\"!==(e=Os(t,n))?i||"."!==e?("["===e?i=!0:"]"===e&&(i=!1),o+=e):o+="[\\s\\S]":o+=e+Os(t,++n);return o}(t),r)),o&&(u.sticky=!0),l.length&&(u.groups=l)),t!==h)try{_t(a,"source",""===h?"(?:)":h)}catch(t){}return a},Ns=gs(bs),Cs=0;Ns.length>Cs;)ls(Us,bs,Ns[Cs++]);ws.constructor=Us,Us.prototype=ws,ie(i,"RegExp",Us,{constructor:!0})}Uo("RegExp");var _s=zt.PROPER,Fs="toString",Bs=RegExp.prototype,Ds=Bs[Fs];(a(function(){return"/a/b"!==Ds.call({source:"a",flags:"b"})})||_s&&Ds.name!==Fs)&&ie(Bs,Fs,function(){var t=kt(this);return"/"+Wr(t.source)+"/"+Wr(os(t))},{unsafe:!0});var zs=ne.get,Ws=RegExp.prototype,qs=TypeError;u&&ps&&so(Ws,"dotAll",{configurable:!0,get:function(){if(this!==Ws){if("RegExp"===E(this))return!!zs(this).dotAll;throw new qs("Incompatible receiver, RegExp required")}}});var Hs=ne.get,$s=nt("native-string-replace",String.prototype.replace),Ks=RegExp.prototype.exec,Gs=Ks,Vs=b("".charAt),Ys=b("".indexOf),Xs=b("".replace),Js=b("".slice),Qs=function(){var t=/a/,e=/b*/g;return f(Ks,t,"a"),f(Ks,e,"a"),0!==t.lastIndex||0!==e.lastIndex}(),Zs=cs.BROKEN_CARET,tc=void 0!==/()??/.exec("")[1];(Qs||tc||Zs||ps||ds)&&(Gs=function(t){var e,r,n,o,i,a,u,s=this,c=Hs(s),l=Wr(t),h=c.raw;if(h)return h.lastIndex=s.lastIndex,e=f(Gs,h,l),s.lastIndex=h.lastIndex,e;var p=c.groups,v=Zs&&s.sticky,d=f(rs,s),g=s.source,y=0,m=l;if(v&&(d=Xs(d,"y",""),-1===Ys(d,"g")&&(d+="g"),m=Js(l,s.lastIndex),s.lastIndex>0&&(!s.multiline||s.multiline&&"\n"!==Vs(l,s.lastIndex-1))&&(g="(?: "+g+")",m=" "+m,y++),r=new RegExp("^(?:"+g+")",d)),tc&&(r=new RegExp("^"+g+"$(?!\\s)",d)),Qs&&(n=s.lastIndex),o=f(Ks,v?r:s,m),v?o?(o.input=Js(o.input,y),o[0]=Js(o[0],y),o.index=s.lastIndex,s.lastIndex+=o[0].length):s.lastIndex=0:Qs&&o&&(s.lastIndex=s.global?o.index+o[0].length:n),tc&&o&&o.length>1&&f($s,o[0],r,function(){for(i=1;i]*>)/g,Oc=/\$([$&'`]|\d{1,2})/g,xc=function(t,e,r,n,o,i){var a=r+t.length,u=n.length,s=Oc;return void 0!==o&&(o=it(o),s=Ec),wc(i,s,function(i,s){var c;switch(bc(s,0)){case"$":return"$";case"&":return t;case"`":return Sc(e,0,r);case"'":return Sc(e,a);case"<":c=o[Sc(s,1,-1)];break;default:var f=+s;if(0===f)return i;if(f>u){var l=mc(f/10);return 0===l?i:l<=u?void 0===n[l-1]?bc(s,1):n[l-1]+bc(s,1):i}c=n[f-1]}return void 0===c?"":c})},Rc=dt("replace"),Pc=Math.max,Ac=Math.min,jc=b([].concat),kc=b([].push),Ic=b("".indexOf),Tc=b("".slice),Mc="$0"==="a".replace(/./,"$0"),Lc=!!/./[Rc]&&""===/./[Rc]("a","$0"),Uc=!a(function(){var t=/./;return t.exec=function(){var t=[];return t.groups={a:"7"},t},"7"!=="".replace(t,"$")});pc("replace",function(t,e,r){var n=Lc?"$":"$0";return[function(t,r){var n=j(this),o=P(t)?void 0:Q(t,Rc);return o?f(o,t,n,r):f(e,Wr(n),t,r)},function(t,o){var i=kt(this),a=Wr(t);if("string"==typeof o&&-1===Ic(o,n)&&-1===Ic(o,"$<")){var u=r(e,i,a,o);if(u.done)return u.value}var s=T(o);s||(o=Wr(o));var c,f=i.global;f&&(c=i.unicode,i.lastIndex=0);for(var l,h=[];null!==(l=yc(i,a))&&(kc(h,l),f);)""===Wr(l[0])&&(i.lastIndex=dc(a,ve(i.lastIndex),c));for(var p,v="",d=0,g=0;g=d&&(v+=Tc(a,d,b)+y,d=b+m.length)}return v+Tc(a,d)}]},!Uc||!Mc||Lc),pc("search",function(t,e,r){return[function(e){var r=j(this),n=P(e)?void 0:Q(e,t);return n?f(n,e,r):new RegExp(e)[t](Wr(r))},function(t){var n=kt(this),o=Wr(t),i=r(e,n,o);if(i.done)return i.value;var a=n.lastIndex;wa(a,0)||(n.lastIndex=0);var u=yc(n,o);return wa(n.lastIndex,a)||(n.lastIndex=a),null===u?-1:u.index}]});var Nc=dt("species"),Cc=function(t,e){var r,n=kt(t).constructor;return void 0===n||P(r=kt(n)[Nc])?e:La(r)},_c=cs.UNSUPPORTED_Y,Fc=Math.min,Bc=b([].push),Dc=b("".slice),zc=!a(function(){var t=/(?:)/,e=t.exec;t.exec=function(){return e.apply(this,arguments)};var r="ab".split(t);return 2!==r.length||"a"!==r[0]||"b"!==r[1]}),Wc="c"==="abbc".split(/(b)*/)[1]||4!=="test".split(/(?:)/,-1).length||2!=="ab".split(/(?:ab)*/).length||4!==".".split(/(.?)(.?)/).length||".".split(/()()/).length>1||"".split(/.?/).length;pc("split",function(t,e,r){var n="0".split(void 0,0).length?function(t,r){return void 0===t&&0===r?[]:f(e,this,t,r)}:e;return[function(e,r){var o=j(this),i=P(e)?void 0:Q(e,t);return i?f(i,e,o,r):f(n,Wr(o),e,r)},function(t,o){var i=kt(this),a=Wr(t);if(!Wc){var u=r(n,i,a,o,n!==e);if(u.done)return u.value}var s=Cc(i,RegExp),c=i.unicode,f=new s(_c?"^(?:"+i.source+")":i,(i.ignoreCase?"i":"")+(i.multiline?"m":"")+(i.unicode?"u":"")+(_c?"g":"y")),l=void 0===o?4294967295:o>>>0;if(0===l)return[];if(0===a.length)return null===yc(f,a)?[a]:[];for(var h=0,p=0,v=[];p0;(n>>>=1)&&(e+=e))1&n&&(r+=e);return r},Kc=b($c),Gc=b("".slice),Vc=Math.ceil,Yc=function(t){return function(e,r,n){var o,i,a=Wr(j(e)),u=ve(r),s=a.length,c=void 0===n?" ":Wr(n);return u<=s||""===c?a:((i=Kc(c,Vc((o=u-s)/c.length))).length>o&&(i=Gc(i,0,o)),t?a+i:i+a)}},Xc={start:Yc(!1),end:Yc(!0)},Jc=Xc.start,Qc=Array,Zc=RegExp.escape,tf=b("".charAt),ef=b("".charCodeAt),rf=b(1.1.toString),nf=b([].join),of=/^[0-9a-z]/i,af=/^[$()*+./?[\\\]^{|}]/,uf=RegExp("^[!\"#%&',\\-:;<=>@`~"+Mi+"]"),sf=b(of.exec),cf={"\t":"t","\n":"n","\v":"v","\f":"f","\r":"r"},ff=function(t){var e=rf(ef(t,0),16);return e.length<3?"\\x"+Jc(e,2,"0"):"\\u"+Jc(e,4,"0")},lf=!Zc||"\\x61b"!==Zc("ab");Ce({target:"RegExp",stat:!0,forced:lf},{escape:function(t){!function(t){if("string"==typeof t)return t;throw new qc("Argument is not a string")}(t);for(var e=t.length,r=Qc(e),n=0;n=56320||n+1>=e||56320!=(64512&ef(t,n+1))?r[n]=ff(o):(r[n]=o,r[++n]=tf(t,n))}}return nf(r,"")}}),To("Set",function(t){return function(){return t(this,arguments.length?arguments[0]:void 0)}},Fo);var hf=Set.prototype,pf={Set:Set,add:b(hf.add),has:b(hf.has),remove:b(hf.delete),proto:hf},vf=pf.has,df=function(t){return vf(t),t},gf=pf.Set,yf=pf.proto,mf=b(yf.forEach),bf=b(yf.keys),wf=bf(new gf).next,Sf=function(t,e,r){return r?ci({iterator:bf(t),next:wf},e):mf(t,e)},Ef=pf.Set,Of=pf.add,xf=function(t){var e=new Ef;return Sf(t,function(t){Of(e,t)}),e},Rf=ln(pf.proto,"size","get")||function(t){return t.size},Pf="Invalid size",Af=RangeError,jf=TypeError,kf=Math.max,If=function(t,e){this.set=t,this.size=kf(e,0),this.has=J(t.has),this.keys=J(t.keys)};If.prototype={getIterator:function(){return{iterator:t=kt(f(this.keys,this.set)),next:t.next,done:!1};var t},includes:function(t){return f(this.has,this.set,t)}};var Tf=function(t){kt(t);var e=+t.size;if(e!=e)throw new jf(Pf);var r=ce(e);if(r<0)throw new Af(Pf);return new If(t,r)},Mf=pf.has,Lf=pf.remove,Uf=function(t){var e=df(this),r=Tf(t),n=xf(e);return Rf(e)<=r.size?Sf(e,function(t){r.includes(t)&&Lf(n,t)}):ci(r.getIterator(),function(t){Mf(e,t)&&Lf(n,t)}),n},Nf=function(t){return{size:t,has:function(){return!1},keys:function(){return{next:function(){return{done:!0}}}}}},Cf=function(t){var e=L("Set");try{(new e)[t](Nf(0));try{return(new e)[t](Nf(-1)),!1}catch(t){return!0}}catch(t){return!1}};Ce({target:"Set",proto:!0,real:!0,forced:!Cf("difference")},{difference:Uf});var _f=pf.Set,Ff=pf.add,Bf=pf.has,Df=function(t){var e=df(this),r=Tf(t),n=new _f;return Rf(e)>r.size?ci(r.getIterator(),function(t){Bf(e,t)&&Ff(n,t)}):Sf(e,function(t){r.includes(t)&&Ff(n,t)}),n},zf=!Cf("intersection")||a(function(){return"3,2"!==String(Array.from(new Set([1,2,3]).intersection(new Set([3,2]))))});Ce({target:"Set",proto:!0,real:!0,forced:zf},{intersection:Df});var Wf=pf.has,qf=function(t){var e=df(this),r=Tf(t);if(Rf(e)<=r.size)return!1!==Sf(e,function(t){if(r.includes(t))return!1},!0);var n=r.getIterator();return!1!==ci(n,function(t){if(Wf(e,t))return Tn(n,"normal",!1)})};Ce({target:"Set",proto:!0,real:!0,forced:!Cf("isDisjointFrom")},{isDisjointFrom:qf});var Hf=function(t){var e=df(this),r=Tf(t);return!(Rf(e)>r.size)&&!1!==Sf(e,function(t){if(!r.includes(t))return!1},!0)};Ce({target:"Set",proto:!0,real:!0,forced:!Cf("isSubsetOf")},{isSubsetOf:Hf});var $f=pf.has,Kf=function(t){var e=df(this),r=Tf(t);if(Rf(e)1?arguments[1]:void 0);return!1!==Sf(e,function(t){if(!r(t,t,e))return!1},!0)}});var el=dt("iterator"),rl=Object,nl=L("Set"),ol=function(t){return function(t){return M(t)&&"number"==typeof t.size&&T(t.has)&&T(t.keys)}(t)?t:function(t){if(P(t))return!1;var e=rl(t);return void 0!==e[el]||"@@iterator"in e||ut(un,pr(e))}(t)?new nl(t):t};Ce({target:"Set",proto:!0,real:!0,forced:!0},{difference:function(t){return f(Uf,this,ol(t))}});var il=pf.Set,al=pf.add;Ce({target:"Set",proto:!0,real:!0,forced:!0},{filter:function(t){var e=df(this),r=ar(t,arguments.length>1?arguments[1]:void 0),n=new il;return Sf(e,function(t){r(t,t,e)&&al(n,t)}),n}}),Ce({target:"Set",proto:!0,real:!0,forced:!0},{find:function(t){var e=df(this),r=ar(t,arguments.length>1?arguments[1]:void 0),n=Sf(e,function(t){if(r(t,t,e))return{value:t}},!0);return n&&n.value}}),Ce({target:"Set",proto:!0,real:!0,forced:!0},{intersection:function(t){return f(Df,this,ol(t))}}),Ce({target:"Set",proto:!0,real:!0,forced:!0},{isDisjointFrom:function(t){return f(qf,this,ol(t))}}),Ce({target:"Set",proto:!0,real:!0,forced:!0},{isSubsetOf:function(t){return f(Hf,this,ol(t))}}),Ce({target:"Set",proto:!0,real:!0,forced:!0},{isSupersetOf:function(t){return f(Kf,this,ol(t))}});var ul=b([].join),sl=b([].push);Ce({target:"Set",proto:!0,real:!0,forced:!0},{join:function(t){var e=df(this),r=void 0===t?",":Wr(t),n=[];return Sf(e,function(t){sl(n,t)}),ul(n,r)}});var cl=pf.Set,fl=pf.add;Ce({target:"Set",proto:!0,real:!0,forced:!0},{map:function(t){var e=df(this),r=ar(t,arguments.length>1?arguments[1]:void 0),n=new cl;return Sf(e,function(t){fl(n,r(t,t,e))}),n}});var ll=TypeError;Ce({target:"Set",proto:!0,real:!0,forced:!0},{reduce:function(t){var e=df(this),r=arguments.length<2,n=r?void 0:arguments[1];if(J(t),Sf(e,function(o){r?(r=!1,n=o):n=t(n,o,o,e)}),r)throw new ll("Reduce of empty set with no initial value");return n}}),Ce({target:"Set",proto:!0,real:!0,forced:!0},{some:function(t){var e=df(this),r=ar(t,arguments.length>1?arguments[1]:void 0);return!0===Sf(e,function(t){if(r(t,t,e))return!0},!0)}}),Ce({target:"Set",proto:!0,real:!0,forced:!0},{symmetricDifference:function(t){return f(Xf,this,ol(t))}}),Ce({target:"Set",proto:!0,real:!0,forced:!0},{union:function(t){return f(Qf,this,ol(t))}});var hl=dt("species"),pl=dt("isConcatSpreadable"),vl=W>=51||!a(function(){var t=[];return t[pl]=!1,t.concat()[0]!==t}),dl=function(t){if(!M(t))return!1;var e=t[pl];return void 0!==e?!!e:ur(t)},gl=!(vl&&(W>=51||!a(function(){var t=[];return(t.constructor={})[hl]=function(){return{foo:1}},1!==t.concat(Boolean).foo})));Ce({target:"Array",proto:!0,arity:1,forced:gl},{concat:function(t){var e,r,n,o,i,a=it(this),u=xr(a,0),s=0;for(e=-1,n=arguments.length;e1?arguments[1]:void 0,n=e.length,o=void 0===r?n:ip(ve(r),n),i=Wr(t);return op(e,o-i.length,o)===i}}),Ze("String","endsWith");var sp=RangeError,cp=String.fromCharCode,fp=String.fromCodePoint,lp=b([].join);Ce({target:"String",stat:!0,arity:1,forced:!!fp&&1!==fp.length},{fromCodePoint:function(t){for(var e,r=[],n=arguments.length,o=0;n>o;){if(e=+arguments[o++],he(e,1114111)!==e)throw new sp(e+" is not a valid code point");r[o]=e<65536?cp(e):cp(55296+((e-=65536)>>10),e%1024+56320)}return lp(r,"")}});var hp=b("".indexOf);Ce({target:"String",proto:!0,forced:!rp("includes")},{includes:function(t){return!!~hp(Wr(j(this)),Wr(tp(t)),arguments.length>1?arguments[1]:void 0)}}),Ze("String","includes"),b(un.String);var pp=/Version\/10(?:\.\d+){1,2}(?: [\w./]+)?(?: Mobile\/\w+)? Safari\//.test(_),vp=Xc.start;Ce({target:"String",proto:!0,forced:pp},{padStart:function(t){return vp(this,t,arguments.length>1?arguments[1]:void 0)}}),Ze("String","padStart");var dp=Xc.end;Ce({target:"String",proto:!0,forced:pp},{padEnd:function(t){return dp(this,t,arguments.length>1?arguments[1]:void 0)}}),Ze("String","padEnd");var gp=b([].push),yp=b([].join);Ce({target:"String",stat:!0},{raw:function(t){var e=k(it(t).raw),r=de(e);if(!r)return"";for(var n=arguments.length,o=[],i=0;;){if(gp(o,Wr(e[i++])),i===r)return yp(o,"");i1?arguments[1]:void 0,e.length)),n=Wr(t);return bp(e,r,r+n.length)===n}}),Ze("String","startsWith");var Op=zt.PROPER,xp=function(t){return a(function(){return!!Mi[t]()||"​…᠎"!=="​…᠎"[t]()||Op&&Mi[t].name!==t})},Rp=_i.start,Pp=xp("trimStart")?function(){return Rp(this)}:"".trimStart;Ce({target:"String",proto:!0,name:"trimStart",forced:"".trimLeft!==Pp},{trimLeft:Pp}),Ce({target:"String",proto:!0,name:"trimStart",forced:"".trimStart!==Pp},{trimStart:Pp}),Ze("String","trimLeft");var Ap=_i.end,jp=xp("trimEnd")?function(){return Ap(this)}:"".trimEnd;Ce({target:"String",proto:!0,name:"trimEnd",forced:"".trimRight!==jp},{trimRight:jp}),Ce({target:"String",proto:!0,name:"trimEnd",forced:"".trimEnd!==jp},{trimEnd:jp}),Ze("String","trimRight");var kp=Object.getOwnPropertyDescriptor,Ip=function(t){if(!u)return i[t];var e=kp(i,t);return e&&e.value},Tp=dt("iterator"),Mp=!a(function(){var t=new URL("b?a=1&b=2&c=3","https://a"),e=t.searchParams,r=new URLSearchParams("a=1&a=2&b=3"),n="";return t.pathname="c%20d",e.forEach(function(t,r){e.delete("b"),n+=r+t}),r.delete("a",2),r.delete("b",void 0),!e.size&&!u||!e.sort||"https://a/c%20d?a=1&c=3"!==t.href||"3"!==e.get("c")||"a=1"!==String(new URLSearchParams("?a=1"))||!e[Tp]||"a"!==new URL("https://a@b").username||"b"!==new URLSearchParams(new URLSearchParams("a=b")).get("a")||"xn--e1aybc"!==new URL("https://тест").host||"#%D0%B1"!==new URL("https://a#б").hash||"a1c3"!==n||"x"!==new URL("https://x",void 0).host}),Lp=TypeError,Up=function(t,e){if(t0;)t[o]=t[--o];o!==i++&&(t[o]=n)}else for(var a=Np(r/2),u=Cp(vo(t,0,a),e),s=Cp(vo(t,a),e),c=u.length,f=s.length,l=0,h=0;l0&&0!=(t&r);r>>=1)e++;return e},pv=function(t){var e=null;switch(t.length){case 1:e=t[0];break;case 2:e=(31&t[0])<<6|63&t[1];break;case 3:e=(15&t[0])<<12|(63&t[1])<<6|63&t[2];break;case 4:e=(7&t[0])<<18|(63&t[1])<<12|(63&t[2])<<6|63&t[3]}return e>1114111?null:e},vv=function(t){for(var e=(t=nv(t,cv," ")).length,r="",n=0;ne){r+="%",n++;continue}var i=lv(t,n+1);if(i!=i){r+=o,n++;continue}n+=2;var a=hv(i);if(0===a)o=Jp(i);else{if(1===a||a>4){r+="�",n++;continue}for(var u=[i],s=1;se||"%"!==tv(t,n));){var c=lv(t,n+1);if(c!=c){n+=3;break}if(c>191||c<128)break;rv(u,c),n+=2,s++}if(u.length!==a){r+="�";continue}var f=pv(u);null===f?r+="�":o=Qp(f)}}r+=o,n++}return r},dv=/[!'()~]|%20/g,gv={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+"},yv=function(t){return gv[t]},mv=function(t){return nv(Xp(t),dv,yv)},bv=fn(function(t,e){zp(this,{type:Dp,target:Wp(t).entries,index:0,kind:e})},Bp,function(){var t=qp(this),e=t.target,r=t.index++;if(!e||r>=e.length)return t.target=null,Pn(void 0,!0);var n=e[r];switch(t.kind){case"keys":return Pn(n.key,!1);case"values":return Pn(n.value,!1)}return Pn([n.key,n.value],!1)},!0),wv=function(t){this.entries=[],this.url=null,void 0!==t&&(M(t)?this.parseObject(t):this.parseQuery("string"==typeof t?"?"===tv(t,0)?uv(t,1):t:Wr(t)))};wv.prototype={type:Bp,bindURL:function(t){this.url=t,this.update()},parseObject:function(t){var e,r,n,o,i,a,u,s=this.entries,c=Fn(t);if(c)for(r=(e=Dn(t,c)).next;!(n=f(r,e)).done;){if(o=Dn(kt(n.value)),(a=f(i=o.next,o)).done||(u=f(i,o)).done||!f(i,o).done)throw new Yp("Expected sequence with length 2");rv(s,{key:Wr(a.value),value:Wr(u.value)})}else for(var l in t)ut(t,l)&&rv(s,{key:l,value:Wr(t[l])})},parseQuery:function(t){if(t)for(var e,r,n=this.entries,o=av(t,"&"),i=0;i0?arguments[0]:void 0));u||(this.size=t.entries.length)},Ev=Sv.prototype;if(Mo(Ev,{append:function(t,e){var r=Wp(this);Up(arguments.length,2),rv(r.entries,{key:Wr(t),value:Wr(e)}),u||this.length++,r.updateURL()},delete:function(t){for(var e=Wp(this),r=Up(arguments.length,1),n=e.entries,o=Wr(t),i=r<2?void 0:arguments[1],a=void 0===i?i:Wr(i),s=0;se.key?1:-1}),t.updateURL()},forEach:function(t){for(var e,r=Wp(this).entries,n=ar(t,arguments.length>1?arguments[1]:void 0),o=0;o1?Rv(arguments[1]):{})}}),T($p)){var Pv=function(t){return ko(this,Gp),new $p(t,arguments.length>1?Rv(arguments[1]):{})};Gp.constructor=Pv,Pv.prototype=Gp,Ce({global:!0,constructor:!0,dontCallGetSet:!0,forced:!0},{Request:Pv})}}var Av={URLSearchParams:Sv,getState:Wp},jv=URLSearchParams,kv=jv.prototype,Iv=b(kv.append),Tv=b(kv.delete),Mv=b(kv.forEach),Lv=b([].push),Uv=new jv("a=1&a=2&b=3");Uv.delete("a",1),Uv.delete("b",void 0),Uv+""!="a=2"&&ie(kv,"delete",function(t){var e=arguments.length,r=e<2?void 0:arguments[1];if(e&&void 0===r)return Tv(this,t);var n=[];Mv(this,function(t,e){Lv(n,{key:e,value:t})}),Up(e,1);for(var o,i=Wr(t),a=Wr(r),u=0,s=0,c=!1,f=n.length;uo;)for(var s,c=R(arguments[o++]),l=i?$v(_e(c),i(c)):_e(c),h=l.length,p=0;h>p;)s=l[p++],u&&!f(a,c,s)||(r[s]=c[s]);return r}:qv,Gv=2147483647,Vv=/[^\0-\u007E]/,Yv=/[.\u3002\uFF0E\uFF61]/g,Xv="Overflow: input needs wider integers to process",Jv=RangeError,Qv=b(Yv.exec),Zv=Math.floor,td=String.fromCharCode,ed=b("".charCodeAt),rd=b([].join),nd=b([].push),od=b("".replace),id=b("".split),ad=b("".toLowerCase),ud=function(t){return t+22+75*(t<26)},sd=function(t,e,r){var n=0;for(t=r?Zv(t/700):t>>1,t+=Zv(t/e);t>455;)t=Zv(t/35),n+=36;return Zv(n+36*t/(t+38))},cd=function(t){var e=[];t=function(t){for(var e=[],r=0,n=t.length;r=55296&&o<=56319&&r=i&&nZv((Gv-a)/l))throw new Jv(Xv);for(a+=(f-i)*l,i=f,r=0;rGv)throw new Jv(Xv);if(n===i){for(var h=a,p=36;;){var v=p<=u?1:p>=u+26?26:p-u;if(h?@[\\\]^|]/,qd=/[\0\t\n\r #/:<>?@[\\\]^|]/,Hd=/^[\u0000-\u0020]+/,$d=/(^|[^\u0000-\u0020])[\u0000-\u0020]+$/,Kd=/[\t\n\r]/g,Gd=function(t){var e,r,n,o;if("number"==typeof t){for(e=[],r=0;r<4;r++)Td(e,t%256),t=md(t/256);return Ed(e,".")}if("object"==typeof t){for(e="",n=function(t){for(var e=null,r=1,n=null,o=0,i=0;i<8;i++)0!==t[i]?(o>r&&(e=n,r=o),n=null,o=0):(null===n&&(n=i),++o);return o>r?n:e}(t),r=0;r<8;r++)o&&0===t[r]||(o&&(o=!1),n===r?(e+=r?":":"::",o=!0):(e+=Od(t[r],16),r<7&&(e+=":")));return"["+e+"]"}return t},Vd={},Yd=Kv({},Vd,{" ":1,'"':1,"<":1,">":1,"`":1}),Xd=Kv({},Yd,{"#":1,"?":1,"{":1,"}":1}),Jd=Kv({},Xd,{"/":1,":":1,";":1,"=":1,"@":1,"[":1,"\\":1,"]":1,"^":1,"|":1}),Qd=function(t,e){var r=fd(t,0);return r>32&&r<127&&!ut(e,t)?t:encodeURIComponent(t)},Zd={ftp:21,file:null,http:80,https:443,ws:80,wss:443},tg=function(t,e){var r;return 2===t.length&&Sd(Nd,wd(t,0))&&(":"===(r=wd(t,1))||!e&&"|"===r)},eg=function(t){var e;return t.length>1&&tg(kd(t,0,2))&&(2===t.length||"/"===(e=wd(t,2))||"\\"===e||"?"===e||"#"===e)},rg=function(t){return"."===t||"%2e"===Id(t)},ng={},og={},ig={},ag={},ug={},sg={},cg={},fg={},lg={},hg={},pg={},vg={},dg={},gg={},yg={},mg={},bg={},wg={},Sg={},Eg={},Og={},xg=function(t,e,r){var n,o,i,a=Wr(t);if(e){if(o=this.parse(a))throw new gd(o);this.searchParams=null}else{if(void 0!==r&&(n=new xg(r,!0)),o=this.parse(a,null,n))throw new gd(o);(i=vd(new pd)).bindURL(this),this.searchParams=i}};xg.prototype={type:"URL",parse:function(t,e,r){var n,o,i,a,u,s=this,c=e||ng,f=0,l="",h=!1,p=!1,v=!1;for(t=Wr(t),e||(s.scheme="",s.username="",s.password="",s.host=null,s.port=null,s.path=[],s.query=null,s.fragment=null,s.cannotBeABaseURL=!1,t=Pd(t,Hd,""),t=Pd(t,$d,"$1")),t=Pd(t,Kd,""),n=Wn(t);f<=n.length;){switch(o=n[f],c){case ng:if(!o||!Sd(Nd,o)){if(e)return Md;c=ig;continue}l+=Id(o),c=og;break;case og:if(o&&(Sd(Cd,o)||"+"===o||"-"===o||"."===o))l+=Id(o);else{if(":"!==o){if(e)return Md;l="",c=ig,f=0;continue}if(e&&(s.isSpecial()!==ut(Zd,l)||"file"===l&&(s.includesCredentials()||null!==s.port)||"file"===s.scheme&&!s.host))return;if(s.scheme=l,e)return void(s.isSpecial()&&Zd[s.scheme]===s.port&&(s.port=null));l="","file"===s.scheme?c=gg:s.isSpecial()&&r&&r.scheme===s.scheme?c=ag:s.isSpecial()?c=fg:"/"===n[f+1]?(c=ug,f++):(s.cannotBeABaseURL=!0,Rd(s.path,""),c=Sg)}break;case ig:if(!r||r.cannotBeABaseURL&&"#"!==o)return Md;if(r.cannotBeABaseURL&&"#"===o){s.scheme=r.scheme,s.path=vo(r.path),s.query=r.query,s.fragment="",s.cannotBeABaseURL=!0,c=Og;break}c="file"===r.scheme?gg:sg;continue;case ag:if("/"!==o||"/"!==n[f+1]){c=sg;continue}c=lg,f++;break;case ug:if("/"===o){c=hg;break}c=wg;continue;case sg:if(s.scheme=r.scheme,o===Wv)s.username=r.username,s.password=r.password,s.host=r.host,s.port=r.port,s.path=vo(r.path),s.query=r.query;else if("/"===o||"\\"===o&&s.isSpecial())c=cg;else if("?"===o)s.username=r.username,s.password=r.password,s.host=r.host,s.port=r.port,s.path=vo(r.path),s.query="",c=Eg;else{if("#"!==o){s.username=r.username,s.password=r.password,s.host=r.host,s.port=r.port,s.path=vo(r.path),s.path.length--,c=wg;continue}s.username=r.username,s.password=r.password,s.host=r.host,s.port=r.port,s.path=vo(r.path),s.query=r.query,s.fragment="",c=Og}break;case cg:if(!s.isSpecial()||"/"!==o&&"\\"!==o){if("/"!==o){s.username=r.username,s.password=r.password,s.host=r.host,s.port=r.port,c=wg;continue}c=hg}else c=lg;break;case fg:if(c=lg,"/"!==o||"/"!==wd(l,f+1))continue;f++;break;case lg:if("/"!==o&&"\\"!==o){c=hg;continue}break;case hg:if("@"===o){h&&(l="%40"+l),h=!0,i=Wn(l);for(var d=0;d65535)return Ud;s.port=s.isSpecial()&&m===Zd[s.scheme]?null:m,l=""}if(e)return;c=bg;continue}return Ud}l+=o;break;case gg:if(s.scheme="file","/"===o||"\\"===o)c=yg;else{if(!r||"file"!==r.scheme){c=wg;continue}switch(o){case Wv:s.host=r.host,s.path=vo(r.path),s.query=r.query;break;case"?":s.host=r.host,s.path=vo(r.path),s.query="",c=Eg;break;case"#":s.host=r.host,s.path=vo(r.path),s.query=r.query,s.fragment="",c=Og;break;default:eg(Ed(vo(n,f),""))||(s.host=r.host,s.path=vo(r.path),s.shortenPath()),c=wg;continue}}break;case yg:if("/"===o||"\\"===o){c=mg;break}r&&"file"===r.scheme&&!eg(Ed(vo(n,f),""))&&(tg(r.path[0],!0)?Rd(s.path,r.path[0]):s.host=r.host),c=wg;continue;case mg:if(o===Wv||"/"===o||"\\"===o||"?"===o||"#"===o){if(!e&&tg(l))c=wg;else if(""===l){if(s.host="",e)return;c=bg}else{if(a=s.parseHost(l))return a;if("localhost"===s.host&&(s.host=""),e)return;l="",c=bg}continue}l+=o;break;case bg:if(s.isSpecial()){if(c=wg,"/"!==o&&"\\"!==o)continue}else if(e||"?"!==o)if(e||"#"!==o){if(o!==Wv&&(c=wg,"/"!==o))continue}else s.fragment="",c=Og;else s.query="",c=Eg;break;case wg:if(o===Wv||"/"===o||"\\"===o&&s.isSpecial()||!e&&("?"===o||"#"===o)){if(".."===(u=Id(u=l))||"%2e."===u||".%2e"===u||"%2e%2e"===u?(s.shortenPath(),"/"===o||"\\"===o&&s.isSpecial()||Rd(s.path,"")):rg(l)?"/"===o||"\\"===o&&s.isSpecial()||Rd(s.path,""):("file"===s.scheme&&!s.path.length&&tg(l)&&(s.host&&(s.host=""),l=wd(l,0)+":"),Rd(s.path,l)),l="","file"===s.scheme&&(o===Wv||"?"===o||"#"===o))for(;s.path.length>1&&""===s.path[0];)Ad(s.path);"?"===o?(s.query="",c=Eg):"#"===o&&(s.fragment="",c=Og)}else l+=Qd(o,Xd);break;case Sg:"?"===o?(s.query="",c=Eg):"#"===o?(s.fragment="",c=Og):o!==Wv&&(s.path[0]+=Qd(o,Vd));break;case Eg:e||"#"!==o?o!==Wv&&("'"===o&&s.isSpecial()?s.query+="%27":s.query+="#"===o?"%23":Qd(o,Vd)):(s.fragment="",c=Og);break;case Og:o!==Wv&&(s.fragment+=Qd(o,Yd))}f++}},parseHost:function(t){var e,r,n;if("["===wd(t,0)){if("]"!==wd(t,t.length-1))return Ld;if(e=function(t){var e,r,n,o,i,a,u,s=[0,0,0,0,0,0,0,0],c=0,f=null,l=0,h=function(){return wd(t,l)};if(":"===h()){if(":"!==wd(t,1))return;l+=2,f=++c}for(;h();){if(8===c)return;if(":"!==h()){for(e=r=0;r<4&&Sd(zd,h());)e=16*e+yd(h(),16),l++,r++;if("."===h()){if(0===r)return;if(l-=r,c>6)return;for(n=0;h();){if(o=null,n>0){if(!("."===h()&&n<4))return;l++}if(!Sd(_d,h()))return;for(;Sd(_d,h());){if(i=yd(h(),10),null===o)o=i;else{if(0===o)return;o=10*o+i}if(o>255)return;l++}s[c]=256*s[c]+o,2!=++n&&4!==n||c++}if(4!==n)return;break}if(":"===h()){if(l++,!h())return}else if(h())return;s[c++]=e}else{if(null!==f)return;l++,f=++c}}if(null!==f)for(a=c-f,c=7;0!==c&&a>0;)u=s[c],s[c--]=s[f+a-1],s[f+--a]=u;else if(8!==c)return;return s}(kd(t,1,-1)),!e)return Ld;this.host=e}else if(this.isSpecial()){if(t=function(t){var e,r,n=[],o=id(od(ad(t),Yv,"."),".");for(e=0;e4)return t;for(r=[],n=0;n1&&"0"===wd(o,0)&&(i=Sd(Fd,o)?16:8,o=kd(o,8===i?1:2)),""===o)a=0;else{if(!Sd(10===i?Dd:8===i?Bd:zd,o))return t;a=yd(o,i)}Rd(r,a)}for(n=0;n=bd(256,5-e))return null}else if(a>255)return null;for(u=xd(r),n=0;n1?arguments[1]:void 0,n=ld(e,new xg(t,!1,r));u||(e.href=n.serialize(),e.origin=n.getOrigin(),e.protocol=n.getProtocol(),e.username=n.getUsername(),e.password=n.getPassword(),e.host=n.getHost(),e.hostname=n.getHostname(),e.port=n.getPort(),e.pathname=n.getPathname(),e.search=n.getSearch(),e.searchParams=n.getSearchParams(),e.hash=n.getHash())},Pg=Rg.prototype,Ag=function(t,e){return{get:function(){return hd(this)[t]()},set:e&&function(t){return hd(this)[e](t)},configurable:!0,enumerable:!0}};if(u&&(so(Pg,"href",Ag("serialize","setHref")),so(Pg,"origin",Ag("getOrigin")),so(Pg,"protocol",Ag("getProtocol","setProtocol")),so(Pg,"username",Ag("getUsername","setUsername")),so(Pg,"password",Ag("getPassword","setPassword")),so(Pg,"host",Ag("getHost","setHost")),so(Pg,"hostname",Ag("getHostname","setHostname")),so(Pg,"port",Ag("getPort","setPort")),so(Pg,"pathname",Ag("getPathname","setPathname")),so(Pg,"search",Ag("getSearch","setSearch")),so(Pg,"searchParams",Ag("getSearchParams")),so(Pg,"hash",Ag("getHash","setHash"))),ie(Pg,"toJSON",function(){return hd(this).serialize()},{enumerable:!0}),ie(Pg,"toString",function(){return hd(this).serialize()},{enumerable:!0}),dd){var jg=dd.createObjectURL,kg=dd.revokeObjectURL;jg&&ie(Rg,"createObjectURL",ar(jg,dd)),kg&&ie(Rg,"revokeObjectURL",ar(kg,dd))}an(Rg,"URL"),Ce({global:!0,constructor:!0,forced:!Mp,sham:!u},{URL:Rg});var Ig=L("URL"),Tg=Mp&&a(function(){Ig.canParse()}),Mg=a(function(){return 1!==Ig.canParse.length});Ce({target:"URL",stat:!0,forced:!Tg||Mg},{canParse:function(t){var e=Up(arguments.length,1),r=Wr(t),n=e<2||void 0===arguments[1]?void 0:Wr(arguments[1]);try{return!!new Ig(r,n)}catch(t){return!1}}});var Lg=L("URL");Ce({target:"URL",stat:!0,forced:!Mp},{parse:function(t){var e=Up(arguments.length,1),r=Wr(t),n=e<2||void 0===arguments[1]?void 0:Wr(arguments[1]);try{return new Lg(r,n)}catch(t){return null}}}),Ce({target:"URL",proto:!0,enumerable:!0},{toJSON:function(){return f(URL.prototype.toString,this)}});var Ug=WeakMap.prototype,Ng={WeakMap:WeakMap,set:b(Ug.set),get:b(Ug.get),has:b(Ug.has),remove:b(Ug.delete)},Cg=Ng.has,_g=function(t){return Cg(t),t},Fg=Ng.get,Bg=Ng.has,Dg=Ng.set;Ce({target:"WeakMap",proto:!0,real:!0,forced:!0},{emplace:function(t,e){var r,n,o=_g(this);return Bg(o,t)?(r=Fg(o,t),"update"in e&&(r=e.update(r,t,o),Dg(o,t,r)),r):(n=e.insert(t,o),Dg(o,t,n),n)}}),Ce({target:"WeakMap",stat:!0,forced:!0},{from:ei(Ng.WeakMap,Ng.set,!0)}),Ce({target:"WeakMap",stat:!0,forced:!0},{of:ri(Ng.WeakMap,Ng.set,!0)});var zg=Ng.remove;Ce({target:"WeakMap",proto:!0,real:!0,forced:!0},{deleteAll:function(){for(var t,e=_g(this),r=!0,n=0,o=arguments.length;n2&&(n=r,M(o=arguments[2])&&"cause"in o&&_t(n,"cause",o.cause));var s=[];return Ao(t,ny,{that:s}),_t(r,"errors",s),r};dn?dn(oy,ry):Ae(oy,ry,{name:!0});var iy=oy.prototype=Ve(ry.prototype,{constructor:d(1,oy),message:d(1,""),name:d(1,"AggregateError")});Ce({global:!0,constructor:!0,arity:2},{AggregateError:oy});var ay,uy,sy,cy,fy=function(t){return _.slice(0,t.length)===t},ly=fy("Bun/")?"BUN":fy("Cloudflare-Workers")?"CLOUDFLARE":fy("Deno/")?"DENO":fy("Node.js/")?"NODE":i.Bun&&"string"==typeof Bun.version?"BUN":i.Deno&&"object"==typeof Deno.version?"DENO":"process"===E(i.process)?"NODE":i.window&&i.document?"BROWSER":"REST",hy="NODE"===ly,py=/(?:ipad|iphone|ipod).*applewebkit/i.test(_),vy=i.setImmediate,dy=i.clearImmediate,gy=i.process,yy=i.Dispatch,my=i.Function,by=i.MessageChannel,wy=i.String,Sy=0,Ey={},Oy="onreadystatechange";a(function(){ay=i.location});var xy=function(t){if(ut(Ey,t)){var e=Ey[t];delete Ey[t],e()}},Ry=function(t){return function(){xy(t)}},Py=function(t){xy(t.data)},Ay=function(t){i.postMessage(wy(t),ay.protocol+"//"+ay.host)};vy&&dy||(vy=function(t){Up(arguments.length,1);var e=T(t)?t:my(t),r=vo(arguments,1);return Ey[++Sy]=function(){Ra(e,void 0,r)},uy(Sy),Sy},dy=function(t){delete Ey[t]},hy?uy=function(t){gy.nextTick(Ry(t))}:yy&&yy.now?uy=function(t){yy.now(Ry(t))}:by&&!py?(cy=(sy=new by).port2,sy.port1.onmessage=Py,uy=ar(cy.postMessage,cy)):i.addEventListener&&T(i.postMessage)&&!i.importScripts&&ay&&"file:"!==ay.protocol&&!a(Ay)?(uy=Ay,i.addEventListener("message",Py,!1)):uy=Oy in Et("script")?function(t){De.appendChild(Et("script"))[Oy]=function(){De.removeChild(this),xy(t)}}:function(t){setTimeout(Ry(t),0)});var jy={set:vy,clear:dy},ky=function(){this.head=null,this.tail=null};ky.prototype={add:function(t){var e={item:t,next:null},r=this.tail;r?r.next=e:this.head=e,this.tail=e},get:function(){var t=this.head;if(t)return null===(this.head=t.next)&&(this.tail=null),t.item}};var Iy,Ty,My,Ly,Uy,Ny=ky,Cy=/ipad|iphone|ipod/i.test(_)&&"undefined"!=typeof Pebble,_y=/web0s(?!.*chrome)/i.test(_),Fy=jy.set,By=i.MutationObserver||i.WebKitMutationObserver,Dy=i.document,zy=i.process,Wy=i.Promise,qy=Ip("queueMicrotask");if(!qy){var Hy=new Ny,$y=function(){var t,e;for(hy&&(t=zy.domain)&&t.exit();e=Hy.get();)try{e()}catch(t){throw Hy.head&&Iy(),t}t&&t.enter()};py||hy||_y||!By||!Dy?!Cy&&Wy&&Wy.resolve?((Ly=Wy.resolve(void 0)).constructor=Wy,Uy=ar(Ly.then,Ly),Iy=function(){Uy($y)}):hy?Iy=function(){zy.nextTick($y)}:(Fy=ar(Fy,i),Iy=function(){Fy($y)}):(Ty=!0,My=Dy.createTextNode(""),new By($y).observe(My,{characterData:!0}),Iy=function(){My.data=Ty=!Ty}),qy=function(t){Hy.head||Iy(),Hy.add(t)}}var Ky,Gy,Vy,Yy=qy,Xy=function(t){try{return{error:!1,value:t()}}catch(t){return{error:!0,value:t}}},Jy=i.Promise,Qy=dt("species"),Zy=!1,tm=T(i.PromiseRejectionEvent),em=Ue("Promise",function(){var t=Kt(Jy),e=t!==String(Jy);if(!e&&66===W)return!0;if(!W||W<51||!/native code/.test(t)){var r=new Jy(function(t){t(1)}),n=function(t){t(function(){},function(){})};if((r.constructor={})[Qy]=n,!(Zy=r.then(function(){})instanceof n))return!0}return!(e||"BROWSER"!==ly&&"DENO"!==ly||tm)}),rm={CONSTRUCTOR:em,REJECTION_EVENT:tm,SUBCLASSING:Zy},nm=TypeError,om=function(t){var e,r;this.promise=new t(function(t,n){if(void 0!==e||void 0!==r)throw new nm("Bad Promise constructor");e=t,r=n}),this.resolve=J(e),this.reject=J(r)},im={f:function(t){return new om(t)}},am=jy.set,um="Promise",sm=rm.CONSTRUCTOR,cm=rm.REJECTION_EVENT,fm=rm.SUBCLASSING,lm=ne.getterFor(um),hm=ne.set,pm=Jy&&Jy.prototype,vm=Jy,dm=pm,gm=i.TypeError,ym=i.document,mm=i.process,bm=im.f,wm=bm,Sm=!!(ym&&ym.createEvent&&i.dispatchEvent),Em="unhandledrejection",Om=function(t){var e;return!(!M(t)||!T(e=t.then))&&e},xm=function(t,e){var r,n,o,i=e.value,a=1===e.state,u=a?t.ok:t.fail,s=t.resolve,c=t.reject,l=t.domain;try{u?(a||(2===e.rejection&&km(e),e.rejection=1),!0===u?r=i:(l&&l.enter(),r=u(i),l&&(l.exit(),o=!0)),r===t.promise?c(new gm("Promise-chain cycle")):(n=Om(r))?f(n,r,s,c):s(r)):c(i)}catch(t){l&&!o&&l.exit(),c(t)}},Rm=function(t,e){t.notified||(t.notified=!0,Yy(function(){for(var r,n=t.reactions;r=n.get();)xm(r,t);t.notified=!1,e&&!t.rejection&&Am(t)}))},Pm=function(t,e,r){var n,o;Sm?((n=ym.createEvent("Event")).promise=e,n.reason=r,n.initEvent(t,!1,!0),i.dispatchEvent(n)):n={promise:e,reason:r},!cm&&(o=i["on"+t])?o(n):t===Em&&function(t,e){try{1===arguments.length?console.error(t):console.error(t,e)}catch(t){}}("Unhandled promise rejection",r)},Am=function(t){f(am,i,function(){var e,r=t.facade,n=t.value;if(jm(t)&&(e=Xy(function(){hy?mm.emit("unhandledRejection",n,r):Pm(Em,r,n)}),t.rejection=hy||jm(t)?2:1,e.error))throw e.value})},jm=function(t){return 1!==t.rejection&&!t.parent},km=function(t){f(am,i,function(){var e=t.facade;hy?mm.emit("rejectionHandled",e):Pm("rejectionhandled",e,t.value)})},Im=function(t,e,r){return function(n){t(e,n,r)}},Tm=function(t,e,r){t.done||(t.done=!0,r&&(t=r),t.value=e,t.state=2,Rm(t,!0))},Mm=function(t,e,r){if(!t.done){t.done=!0,r&&(t=r);try{if(t.facade===e)throw new gm("Promise can't be resolved itself");var n=Om(e);n?Yy(function(){var r={done:!1};try{f(n,e,Im(Mm,r,t),Im(Tm,r,t))}catch(e){Tm(r,e,t)}}):(t.value=e,t.state=1,Rm(t,!1))}catch(e){Tm({done:!1},e,t)}}};if(sm&&(vm=function(t){ko(this,dm),J(t),f(Ky,this);var e=lm(this);try{t(Im(Mm,e),Im(Tm,e))}catch(t){Tm(e,t)}},(Ky=function(t){hm(this,{type:um,done:!1,notified:!1,parent:!1,reactions:new Ny,rejection:!1,state:0,value:null})}).prototype=ie(dm=vm.prototype,"then",function(t,e){var r=lm(this),n=bm(Cc(this,vm));return r.parent=!0,n.ok=!T(t)||t,n.fail=T(e)&&e,n.domain=hy?mm.domain:void 0,0===r.state?r.reactions.add(n):Yy(function(){xm(n,r)}),n.promise}),Gy=function(){var t=new Ky,e=lm(t);this.promise=t,this.resolve=Im(Mm,e),this.reject=Im(Tm,e)},im.f=bm=function(t){return t===vm||void 0===t?new Gy(t):wm(t)},T(Jy)&&pm!==Object.prototype)){Vy=pm.then,fm||ie(pm,"then",function(t,e){var r=this;return new vm(function(t,e){f(Vy,r,t,e)}).then(t,e)},{unsafe:!0});try{delete pm.constructor}catch(t){}dn&&dn(pm,dm)}Ce({global:!0,constructor:!0,wrap:!0,forced:sm},{Promise:vm}),an(vm,um,!1),Uo(um);var Lm=rm.CONSTRUCTOR||!Gn(function(t){Jy.all(t).then(void 0,function(){})});Ce({target:"Promise",stat:!0,forced:Lm},{all:function(t){var e=this,r=im.f(e),n=r.resolve,o=r.reject,i=Xy(function(){var r=J(e.resolve),i=[],a=0,u=1;Ao(t,function(t){var s=a++,c=!1;u++,f(r,e,t).then(function(t){c||(c=!0,i[s]=t,--u||n(i))},o)}),--u||n(i)});return i.error&&o(i.value),r.promise}});var Um=Jy&&Jy.prototype;if(Ce({target:"Promise",proto:!0,forced:rm.CONSTRUCTOR,real:!0},{catch:function(t){return this.then(void 0,t)}}),T(Jy)){var Nm=L("Promise").prototype.catch;Um.catch!==Nm&&ie(Um,"catch",Nm,{unsafe:!0})}Ce({target:"Promise",stat:!0,forced:Lm},{race:function(t){var e=this,r=im.f(e),n=r.reject,o=Xy(function(){var o=J(e.resolve);Ao(t,function(t){f(o,e,t).then(r.resolve,n)})});return o.error&&n(o.value),r.promise}}),Ce({target:"Promise",stat:!0,forced:rm.CONSTRUCTOR},{reject:function(t){var e=im.f(this);return(0,e.reject)(t),e.promise}});var Cm=function(t,e){if(kt(t),M(e)&&e.constructor===t)return e;var r=im.f(t);return(0,r.resolve)(e),r.promise};Ce({target:"Promise",stat:!0,forced:rm.CONSTRUCTOR},{resolve:function(t){return Cm(this,t)}}),Ce({target:"Promise",stat:!0,forced:Lm},{allSettled:function(t){var e=this,r=im.f(e),n=r.resolve,o=r.reject,i=Xy(function(){var r=J(e.resolve),o=[],i=0,a=1;Ao(t,function(t){var u=i++,s=!1;a++,f(r,e,t).then(function(t){s||(s=!0,o[u]={status:"fulfilled",value:t},--a||n(o))},function(t){s||(s=!0,o[u]={status:"rejected",reason:t},--a||n(o))})}),--a||n(o)});return i.error&&o(i.value),r.promise}});var _m="No one promise resolved";Ce({target:"Promise",stat:!0,forced:Lm},{any:function(t){var e=this,r=L("AggregateError"),n=im.f(e),o=n.resolve,i=n.reject,a=Xy(function(){var n=J(e.resolve),a=[],u=0,s=1,c=!1;Ao(t,function(t){var l=u++,h=!1;s++,f(n,e,t).then(function(t){h||c||(c=!0,o(t))},function(t){h||c||(h=!0,a[l]=t,--s||i(new r(a,_m)))})}),--s||i(new r(a,_m))});return a.error&&i(a.value),n.promise}}),Ce({target:"Promise",stat:!0},{withResolvers:function(){var t=im.f(this);return{promise:t.promise,resolve:t.resolve,reject:t.reject}}});var Fm=Jy&&Jy.prototype,Bm=!!Jy&&a(function(){Fm.finally.call({then:function(){}},function(){})});if(Ce({target:"Promise",proto:!0,real:!0,forced:Bm},{finally:function(t){var e=Cc(this,L("Promise")),r=T(t);return this.then(r?function(r){return Cm(e,t()).then(function(){return r})}:t,r?function(r){return Cm(e,t()).then(function(){throw r})}:t)}}),T(Jy)){var Dm=L("Promise").prototype.finally;Fm.finally!==Dm&&ie(Fm,"finally",Dm,{unsafe:!0})}var zm=i.Promise,Wm=!1,qm=!zm||!zm.try||Xy(function(){zm.try(function(t){Wm=8===t},8)}).error||!Wm;Ce({target:"Promise",stat:!0,forced:qm},{try:function(t){var e=arguments.length>1?vo(arguments,1):[],r=im.f(this),n=Xy(function(){return Ra(J(t),void 0,e)});return(n.error?r.reject:r.resolve)(n.value),r.promise}}),Ze("Promise","finally");var Hm="URLSearchParams"in self,$m="Symbol"in self&&"iterator"in Symbol,Km="FileReader"in self&&"Blob"in self&&function(){try{return new Blob,!0}catch(t){return!1}}(),Gm="FormData"in self,Vm="ArrayBuffer"in self;if(Vm)var Ym=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],Xm=ArrayBuffer.isView||function(t){return t&&Ym.indexOf(Object.prototype.toString.call(t))>-1};function Jm(t){if("string"!=typeof t&&(t=String(t)),/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(t))throw new TypeError("Invalid character in header field name");return t.toLowerCase()}function Qm(t){return"string"!=typeof t&&(t=String(t)),t}function Zm(t){var e={next:function(){var e=t.shift();return{done:void 0===e,value:e}}};return $m&&(e[Symbol.iterator]=function(){return e}),e}function tb(t){this.map={},t instanceof tb?t.forEach(function(t,e){this.append(e,t)},this):Array.isArray(t)?t.forEach(function(t){this.append(t[0],t[1])},this):t&&Object.getOwnPropertyNames(t).forEach(function(e){this.append(e,t[e])},this)}function eb(t){if(t.bodyUsed)return Promise.reject(new TypeError("Already read"));t.bodyUsed=!0}function rb(t){return new Promise(function(e,r){t.onload=function(){e(t.result)},t.onerror=function(){r(t.error)}})}function nb(t){var e=new FileReader,r=rb(e);return e.readAsArrayBuffer(t),r}function ob(t){if(t.slice)return t.slice(0);var e=new Uint8Array(t.byteLength);return e.set(new Uint8Array(t)),e.buffer}function ib(){return this.bodyUsed=!1,this._initBody=function(t){var e;this._bodyInit=t,t?"string"==typeof t?this._bodyText=t:Km&&Blob.prototype.isPrototypeOf(t)?this._bodyBlob=t:Gm&&FormData.prototype.isPrototypeOf(t)?this._bodyFormData=t:Hm&&URLSearchParams.prototype.isPrototypeOf(t)?this._bodyText=t.toString():Vm&&Km&&(e=t)&&DataView.prototype.isPrototypeOf(e)?(this._bodyArrayBuffer=ob(t.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer])):Vm&&(ArrayBuffer.prototype.isPrototypeOf(t)||Xm(t))?this._bodyArrayBuffer=ob(t):this._bodyText=t=Object.prototype.toString.call(t):this._bodyText="",this.headers.get("content-type")||("string"==typeof t?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):Hm&&URLSearchParams.prototype.isPrototypeOf(t)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},Km&&(this.blob=function(){var t=eb(this);if(t)return t;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this._bodyArrayBuffer?eb(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(nb)}),this.text=function(){var t=eb(this);if(t)return t;if(this._bodyBlob)return function(t){var e=new FileReader,r=rb(e);return e.readAsText(t),r}(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(function(t){for(var e=new Uint8Array(t),r=new Array(e.length),n=0;n-1?e:t}(e.method||this.method||"GET"),this.mode=e.mode||this.mode||null,this.signal=e.signal||this.signal,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&r)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(r)}function sb(t){var e=new FormData;return t.trim().split("&").forEach(function(t){if(t){var r=t.split("="),n=r.shift().replace(/\+/g," "),o=r.join("=").replace(/\+/g," ");e.append(decodeURIComponent(n),decodeURIComponent(o))}}),e}function cb(t,e){e||(e={}),this.type="default",this.status=void 0===e.status?200:e.status,this.ok=this.status>=200&&this.status<300,this.statusText="statusText"in e?e.statusText:"OK",this.headers=new tb(e.headers),this.url=e.url||"",this._initBody(t)}ub.prototype.clone=function(){return new ub(this,{body:this._bodyInit})},ib.call(ub.prototype),ib.call(cb.prototype),cb.prototype.clone=function(){return new cb(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new tb(this.headers),url:this.url})},cb.error=function(){var t=new cb(null,{status:0,statusText:""});return t.type="error",t};var fb=[301,302,303,307,308];cb.redirect=function(t,e){if(-1===fb.indexOf(e))throw new RangeError("Invalid status code");return new cb(null,{status:e,headers:{location:t}})};var lb=self.DOMException;try{new lb}catch(t){(lb=function(t,e){this.message=t,this.name=e;var r=Error(t);this.stack=r.stack}).prototype=Object.create(Error.prototype),lb.prototype.constructor=lb}function hb(t,e){return new Promise(function(r,n){var o=new ub(t,e);if(o.signal&&o.signal.aborted)return n(new lb("Aborted","AbortError"));var i=new XMLHttpRequest;function a(){i.abort()}i.onload=function(){var t,e,n={status:i.status,statusText:i.statusText,headers:(t=i.getAllResponseHeaders()||"",e=new tb,t.replace(/\r?\n[\t ]+/g," ").split(/\r?\n/).forEach(function(t){var r=t.split(":"),n=r.shift().trim();if(n){var o=r.join(":").trim();e.append(n,o)}}),e)};n.url="responseURL"in i?i.responseURL:n.headers.get("X-Request-URL"),r(new cb("response"in i?i.response:i.responseText,n))},i.onerror=function(){n(new TypeError("Network request failed"))},i.ontimeout=function(){n(new TypeError("Network request failed"))},i.onabort=function(){n(new lb("Aborted","AbortError"))},i.open(o.method,o.url,!0),"include"===o.credentials?i.withCredentials=!0:"omit"===o.credentials&&(i.withCredentials=!1),"responseType"in i&&Km&&(i.responseType="blob"),o.headers.forEach(function(t,e){i.setRequestHeader(e,t)}),o.signal&&(o.signal.addEventListener("abort",a),i.onreadystatechange=function(){4===i.readyState&&o.signal.removeEventListener("abort",a)}),i.send(void 0===o._bodyInit?null:o._bodyInit)})}hb.polyfill=!0,self.fetch||(self.fetch=hb,self.Headers=tb,self.Request=ub,self.Response=cb);var pb=Object.getOwnPropertySymbols,vb=Object.prototype.hasOwnProperty,db=Object.prototype.propertyIsEnumerable,gb=function(){try{if(!Object.assign)return!1;var t=new String("abc");if(t[5]="de","5"===Object.getOwnPropertyNames(t)[0])return!1;for(var e={},r=0;r<10;r++)e["_"+String.fromCharCode(r)]=r;if("0123456789"!==Object.getOwnPropertyNames(e).map(function(t){return e[t]}).join(""))return!1;var n={};return"abcdefghijklmnopqrst".split("").forEach(function(t){n[t]=t}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},n)).join("")}catch(t){return!1}}()?Object.assign:function(t,e){for(var r,n,o=function(t){if(null==t)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(t)}(t),i=1;i{"use strict";var t,n=e.i(271645),r=e.i(981140),o=e.i(248425),a=e.i(820783),i=e.i(30207),s=e.i(683986),u=e.i(843476),c="dismissableLayer.update",l=n.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set,dismissableSurfaces:new Set}),d=n.forwardRef((e,d)=>{let{disableOutsidePointerEvents:p=!1,deferPointerDownOutside:m=!1,onEscapeKeyDown:h,onPointerDownOutside:g,onFocusOutside:E,onInteractOutside:y,onDismiss:b,...w}=e,C=n.useContext(l),[R,D]=n.useState(null),S=R?.ownerDocument??globalThis?.document,[,P]=n.useState({}),L=(0,a.useComposedRefs)(d,D),x=Array.from(C.layers),[T]=[...C.layersWithOutsidePointerEventsDisabled].slice(-1),_=x.indexOf(T),k=R?x.indexOf(R):-1,N=C.layersWithOutsidePointerEventsDisabled.size>0,O=k>=_,F=n.useRef(!1),M=function(e,t){let{ownerDocument:r=globalThis?.document,deferPointerDownOutside:o=!1,isDeferredPointerDownOutsideRef:a,dismissableSurfaces:s}=t,u=(0,i.useCallbackRef)(e),c=n.useRef(!1),l=n.useRef(!1),d=n.useRef(new Map),f=n.useRef(()=>{});return n.useEffect(()=>{function e(){l.current=!1,a.current=!1,d.current.clear()}function t(e){if(!l.current)return;let t=e.target;t instanceof Node&&[...s].some(e=>e.contains(t))||d.current.set(e.type,!0),"click"===e.type&&window.setTimeout(()=>{l.current&&f.current()},0)}function n(e){l.current&&d.current.set(e.type,!1)}let i=t=>{if(t.target&&!c.current){let n=function(){r.removeEventListener("click",f.current);let t=Array.from(d.current.values()).some(Boolean);e(),t||v("dismissableLayer.pointerDownOutside",u,i,{discrete:!0})},i={originalEvent:t};l.current=!0,a.current=o&&0===t.button,d.current.clear(),o&&0===t.button?(r.removeEventListener("click",f.current),f.current=n,r.addEventListener("click",f.current,{once:!0})):n()}else r.removeEventListener("click",f.current),e();c.current=!1},p=["pointerup","mousedown","mouseup","touchstart","touchend","click"];for(let e of p)r.addEventListener(e,t,!0),r.addEventListener(e,n);let m=window.setTimeout(()=>{r.addEventListener("pointerdown",i)},0);return()=>{for(let e of(window.clearTimeout(m),r.removeEventListener("pointerdown",i),r.removeEventListener("click",f.current),p))r.removeEventListener(e,t,!0),r.removeEventListener(e,n)}},[r,u,o,a,s]),{onPointerDownCapture:()=>c.current=!0}}(e=>{let t=e.target;if(!(t instanceof Node))return;let n=[...C.branches].some(e=>e.contains(t));O&&!n&&(g?.(e),y?.(e),e.defaultPrevented||b?.())},{ownerDocument:S,deferPointerDownOutside:m,isDeferredPointerDownOutsideRef:F,dismissableSurfaces:C.dismissableSurfaces}),I=function(e,t=globalThis?.document){let r=(0,i.useCallbackRef)(e),o=n.useRef(!1);return n.useEffect(()=>{let e=e=>{e.target&&!o.current&&v("dismissableLayer.focusOutside",r,{originalEvent:e},{discrete:!1})};return t.addEventListener("focusin",e),()=>t.removeEventListener("focusin",e)},[t,r]),{onFocusCapture:()=>o.current=!0,onBlurCapture:()=>o.current=!1}}(e=>{if(m&&F.current)return;let t=e.target;![...C.branches].some(e=>e.contains(t))&&(E?.(e),y?.(e),e.defaultPrevented||b?.())},S),j=!!R&&k===x.length-1,A=(0,s.useEffectEvent)(e=>{"Escape"===e.key&&(h?.(e),!e.defaultPrevented&&b&&(e.preventDefault(),b()))});return n.useEffect(()=>{if(j)return S.addEventListener("keydown",A,{capture:!0}),()=>S.removeEventListener("keydown",A,{capture:!0})},[S,j]),n.useEffect(()=>{if(R)return p&&(0===C.layersWithOutsidePointerEventsDisabled.size&&(t=S.body.style.pointerEvents,S.body.style.pointerEvents="none"),C.layersWithOutsidePointerEventsDisabled.add(R)),C.layers.add(R),f(),()=>{p&&(C.layersWithOutsidePointerEventsDisabled.delete(R),0===C.layersWithOutsidePointerEventsDisabled.size&&(S.body.style.pointerEvents=t))}},[R,S,p,C]),n.useEffect(()=>()=>{R&&(C.layers.delete(R),C.layersWithOutsidePointerEventsDisabled.delete(R),f())},[R,C]),n.useEffect(()=>{let e=()=>P({});return document.addEventListener(c,e),()=>document.removeEventListener(c,e)},[]),(0,u.jsx)(o.Primitive.div,{...w,ref:L,style:{pointerEvents:N?O?"auto":"none":void 0,...e.style},onFocusCapture:(0,r.composeEventHandlers)(e.onFocusCapture,I.onFocusCapture),onBlurCapture:(0,r.composeEventHandlers)(e.onBlurCapture,I.onBlurCapture),onPointerDownCapture:(0,r.composeEventHandlers)(e.onPointerDownCapture,M.onPointerDownCapture)})});function f(){let e=new CustomEvent(c);document.dispatchEvent(e)}function v(e,t,n,{discrete:r}){let a=n.originalEvent.target,i=new CustomEvent(e,{bubbles:!1,cancelable:!0,detail:n});t&&a.addEventListener(e,t,{once:!0}),r?(0,o.dispatchDiscreteCustomEvent)(a,i):a.dispatchEvent(i)}d.displayName="DismissableLayer",n.forwardRef((e,t)=>{let r=n.useContext(l),i=n.useRef(null),s=(0,a.useComposedRefs)(t,i);return n.useEffect(()=>{let e=i.current;if(e)return r.branches.add(e),()=>{r.branches.delete(e)}},[r.branches]),(0,u.jsx)(o.Primitive.div,{...e,ref:s})}).displayName="DismissableLayerBranch",e.s(["DismissableLayer",0,d,"useDismissableLayerSurface",0,function(){let e=n.useContext(l),[t,r]=n.useState(null);return n.useEffect(()=>{if(t)return e.dismissableSurfaces.add(t),()=>{e.dismissableSurfaces.delete(t)}},[t,e.dismissableSurfaces]),r}])},765491,774606,e=>{"use strict";let t;var n=e.i(271645),r=e.i(820783),o=e.i(248425),a=e.i(30207),i=e.i(843476),s="focusScope.autoFocusOnMount",u="focusScope.autoFocusOnUnmount",c={bubbles:!1,cancelable:!0},l=n.forwardRef((e,t)=>{let{loop:l=!1,trapped:m=!1,onMountAutoFocus:h,onUnmountAutoFocus:g,...E}=e,[y,b]=n.useState(null),w=(0,a.useCallbackRef)(h),C=(0,a.useCallbackRef)(g),R=n.useRef(null),D=(0,r.useComposedRefs)(t,b),S=n.useRef({paused:!1,pause(){this.paused=!0},resume(){this.paused=!1}}).current;n.useEffect(()=>{if(m){let e=function(e){if(S.paused||!y)return;let t=e.target;y.contains(t)?R.current=t:v(R.current,{select:!0})},t=function(e){if(S.paused||!y)return;let t=e.relatedTarget;null!==t&&(y.contains(t)||v(R.current,{select:!0}))};document.addEventListener("focusin",e),document.addEventListener("focusout",t);let n=new MutationObserver(function(e){if(document.activeElement===document.body)for(let t of e)t.removedNodes.length>0&&v(y)});return y&&n.observe(y,{childList:!0,subtree:!0}),()=>{document.removeEventListener("focusin",e),document.removeEventListener("focusout",t),n.disconnect()}}},[m,y,S.paused]),n.useEffect(()=>{if(y){p.add(S);let e=document.activeElement;if(!y.contains(e)){let t=new CustomEvent(s,c);y.addEventListener(s,w),y.dispatchEvent(t),t.defaultPrevented||(function(e,{select:t=!1}={}){let n=document.activeElement;for(let r of e)if(v(r,{select:t}),document.activeElement!==n)return}(d(y).filter(e=>"A"!==e.tagName),{select:!0}),document.activeElement===e&&v(y))}return()=>{y.removeEventListener(s,w),setTimeout(()=>{let t=new CustomEvent(u,c);y.addEventListener(u,C),y.dispatchEvent(t),t.defaultPrevented||v(e??document.body,{select:!0}),y.removeEventListener(u,C),p.remove(S)},0)}}},[y,w,C,S]);let P=n.useCallback(e=>{if(!l&&!m||S.paused)return;let t="Tab"===e.key&&!e.altKey&&!e.ctrlKey&&!e.metaKey,n=document.activeElement;if(t&&n){var r;let t,o=e.currentTarget,[a,i]=[f(t=d(r=o),r),f(t.reverse(),r)];a&&i?e.shiftKey||n!==i?e.shiftKey&&n===a&&(e.preventDefault(),l&&v(i,{select:!0})):(e.preventDefault(),l&&v(a,{select:!0})):n===o&&e.preventDefault()}},[l,m,S.paused]);return(0,i.jsx)(o.Primitive.div,{tabIndex:-1,...E,ref:D,onKeyDown:P})});function d(e){let t=[],n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT,{acceptNode:e=>{let t="INPUT"===e.tagName&&"hidden"===e.type;return e.disabled||e.hidden||t?NodeFilter.FILTER_SKIP:e.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});for(;n.nextNode();)t.push(n.currentNode);return t}function f(e,t){for(let n of e)if(!function(e,{upTo:t}){if("hidden"===getComputedStyle(e).visibility)return!0;for(;e&&(void 0===t||e!==t);){if("none"===getComputedStyle(e).display)return!0;e=e.parentElement}return!1}(n,{upTo:t}))return n}function v(e,{select:t=!1}={}){if(e&&e.focus){var n;let r=document.activeElement;e.focus({preventScroll:!0}),e!==r&&(n=e)instanceof HTMLInputElement&&"select"in n&&t&&e.select()}}l.displayName="FocusScope";var p=(t=[],{add(e){let n=t[0];e!==n&&n?.pause(),(t=m(t,e)).unshift(e)},remove(e){t=m(t,e),t[0]?.resume()}});function m(e,t){let n=[...e],r=n.indexOf(t);return -1!==r&&n.splice(r,1),n}e.s(["FocusScope",0,l],765491);var h=e.i(174080),g=e.i(934620),E=n.forwardRef((e,t)=>{let{container:r,...a}=e,[s,u]=n.useState(!1);(0,g.useLayoutEffect)(()=>u(!0),[]);let c=r||s&&globalThis?.document?.body;return c?h.createPortal((0,i.jsx)(o.Primitive.div,{...a,ref:t}),c):null});E.displayName="Portal",e.s(["Portal",0,E],774606)},303536,e=>{"use strict";var t=e.i(271645),n=0,r=null;function o(){let e=document.createElement("span");return e.setAttribute("data-radix-focus-guard",""),e.tabIndex=0,e.style.outline="none",e.style.opacity="0",e.style.position="fixed",e.style.pointerEvents="none",e}e.s(["useFocusGuards",0,function(){t.useEffect(()=>{r||(r={start:o(),end:o()});let{start:e,end:t}=r;return document.body.firstElementChild!==e&&document.body.insertAdjacentElement("afterbegin",e),document.body.lastElementChild!==t&&document.body.insertAdjacentElement("beforeend",t),n++,()=>{1===n&&(r?.start.remove(),r?.end.remove(),r=null),n=Math.max(0,n-1)}},[])}])},326999,985369,e=>{"use strict";var t,n,r,o,a,i,s,u=e.i(271645),c=e.i(981140),l=e.i(820783),d=e.i(30030),f=e.i(610772),v=e.i(369340),p=e.i(726330),m=e.i(765491),h=e.i(774606),g=e.i(296626),E=e.i(248425),y=e.i(303536),b=e.i(290571),w="right-scroll-bar-position",C="width-before-scroll-bar";function R(e,t){return"function"==typeof e?e(t):e&&(e.current=t),e}var D="u">typeof window?u.useLayoutEffect:u.useEffect,S=new WeakMap,P=(void 0===t&&(t={}),(void 0===n&&(n=function(e){return e}),r=[],o=!1,a={read:function(){if(o)throw Error("Sidecar: could not `read` from an `assigned` medium. `read` could be used only with `useMedium`.");return r.length?r[r.length-1]:null},useMedium:function(e){var t=n(e,o);return r.push(t),function(){r=r.filter(function(e){return e!==t})}},assignSyncMedium:function(e){for(o=!0;r.length;){var t=r;r=[],t.forEach(e)}r={push:function(t){return e(t)},filter:function(){return r}}},assignMedium:function(e){o=!0;var t=[];if(r.length){var n=r;r=[],n.forEach(e),t=r}var a=function(){var n=t;t=[],n.forEach(e)},i=function(){return Promise.resolve().then(a)};i(),r={push:function(e){t.push(e),i()},filter:function(e){return t=t.filter(e),r}}}}).options=(0,b.__assign)({async:!0,ssr:!1},t),a),L=function(){},x=u.forwardRef(function(e,t){var n,r,o,a,i=u.useRef(null),s=u.useState({onScrollCapture:L,onWheelCapture:L,onTouchMoveCapture:L}),c=s[0],l=s[1],d=e.forwardProps,f=e.children,v=e.className,p=e.removeScrollBar,m=e.enabled,h=e.shards,g=e.sideCar,E=e.noRelative,y=e.noIsolation,w=e.inert,C=e.allowPinchZoom,x=e.as,T=e.gapMode,_=(0,b.__rest)(e,["forwardProps","children","className","removeScrollBar","enabled","shards","sideCar","noRelative","noIsolation","inert","allowPinchZoom","as","gapMode"]),k=(n=[i,t],r=function(e){return n.forEach(function(t){return R(t,e)})},(o=(0,u.useState)(function(){return{value:null,callback:r,facade:{get current(){return o.value},set current(value){var e=o.value;e!==value&&(o.value=value,o.callback(value,e))}}}})[0]).callback=r,a=o.facade,D(function(){var e=S.get(a);if(e){var t=new Set(e),r=new Set(n),o=a.current;t.forEach(function(e){r.has(e)||R(e,null)}),r.forEach(function(e){t.has(e)||R(e,o)})}S.set(a,n)},[n]),a),N=(0,b.__assign)((0,b.__assign)({},_),c);return u.createElement(u.Fragment,null,m&&u.createElement(g,{sideCar:P,removeScrollBar:p,shards:h,noRelative:E,noIsolation:y,inert:w,setCallbacks:l,allowPinchZoom:!!C,lockRef:i,gapMode:T}),d?u.cloneElement(u.Children.only(f),(0,b.__assign)((0,b.__assign)({},N),{ref:k})):u.createElement(void 0===x?"div":x,(0,b.__assign)({},N,{className:v,ref:k}),f))});x.defaultProps={enabled:!0,removeScrollBar:!0,inert:!1},x.classNames={fullWidth:C,zeroRight:w};var T=function(e){var t=e.sideCar,n=(0,b.__rest)(e,["sideCar"]);if(!t)throw Error("Sidecar: please provide `sideCar` property to import the right car");var r=t.read();if(!r)throw Error("Sidecar medium not found");return u.createElement(r,(0,b.__assign)({},n))};T.isSideCarExport=!0;var _=function(){var e=0,t=null;return{add:function(n){if(0==e&&(t=function(){if(!document)return null;var e=document.createElement("style");e.type="text/css";var t=s||("u">typeof __webpack_nonce__?__webpack_nonce__:void 0);return t&&e.setAttribute("nonce",t),e}())){var r,o;(r=t).styleSheet?r.styleSheet.cssText=n:r.appendChild(document.createTextNode(n)),o=t,(document.head||document.getElementsByTagName("head")[0]).appendChild(o)}e++},remove:function(){--e||!t||(t.parentNode&&t.parentNode.removeChild(t),t=null)}}},k=function(){var e=_();return function(t,n){u.useEffect(function(){return e.add(t),function(){e.remove()}},[t&&n])}},N=function(){var e=k();return function(t){return e(t.styles,t.dynamic),null}},O={left:0,top:0,right:0,gap:0},F=function(e){return parseInt(e||"",10)||0},M=function(e){var t=window.getComputedStyle(document.body),n=t["padding"===e?"paddingLeft":"marginLeft"],r=t["padding"===e?"paddingTop":"marginTop"],o=t["padding"===e?"paddingRight":"marginRight"];return[F(n),F(r),F(o)]},I=function(e){if(void 0===e&&(e="margin"),"u"` tag."),"__NEXT_ERROR_CODE",{value:"E863",enumerable:!1,configurable:!0});l=s.default.Children.only(n)}let V=B?l&&"object"==typeof l&&l.ref:z,G=s.default.useCallback(e=>(null!==U&&(w.current=(0,g.mountLinkInstance)(e,D,U,$,H,b)),()=>{w.current&&((0,g.unmountLinkForCurrentNavigation)(w.current),w.current=null),(0,g.unmountPrefetchableInstance)(e)}),[H,D,U,$,b]),K={ref:(0,d.useMergedRef)(G,V),onClick(t){B||"function"!=typeof T||T(t),B&&l.props&&"function"==typeof l.props.onClick&&l.props.onClick(t),!U||t.defaultPrevented||function(t,r,a,n,l,i,o){if("u">typeof window){let c,{nodeName:d}=t.currentTarget;if("A"===d.toUpperCase()&&((c=t.currentTarget.getAttribute("target"))&&"_self"!==c||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||t.nativeEvent&&2===t.nativeEvent.which)||t.currentTarget.hasAttribute("download"))return;if(!(0,p.isLocalURL)(r)){n&&(t.preventDefault(),location.replace(r));return}if(t.preventDefault(),i){let e=!1;if(i({preventDefault:()=>{e=!0}}),e)return}let{dispatchNavigateAction:u}=e.r(699781);s.default.startTransition(()=>{u(r,n?"replace":"push",!1===l?m.ScrollBehavior.NoScroll:m.ScrollBehavior.Default,a.current,o)})}}(t,D,w,N,E,I,A)},onMouseEnter(e){B||"function"!=typeof O||O(e),B&&l.props&&"function"==typeof l.props.onMouseEnter&&l.props.onMouseEnter(e),U&&H&&(0,g.onNavigationIntent)(e.currentTarget,!0===R)},onTouchStart:function(e){B||"function"!=typeof P||P(e),B&&l.props&&"function"==typeof l.props.onTouchStart&&l.props.onTouchStart(e),U&&H&&(0,g.onNavigationIntent)(e.currentTarget,!0===R)}};return(0,u.isAbsoluteUrl)(D)?K.href=D:B&&!C&&("a"!==l.type||"href"in l.props)||(K.href=(0,h.addBasePath)(D)),x=B?s.default.cloneElement(l,K):(0,i.jsx)("a",{...M,...K,children:n}),(0,i.jsx)(y.Provider,{value:v,children:x})}e.r(284508);let y=(0,s.createContext)(g.IDLE_LINK_STATUS),v=()=>(0,s.useContext)(y);("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},402874,143488,658140,e=>{"use strict";var t=e.i(843476),r=e.i(266027),a=e.i(602869);let n=(0,e.i(243652).createQueryKeys)("healthReadinessDetails"),l=async e=>{let t=(0,a.getProxyBaseUrl)(),r=await fetch(`${t}/health/readiness/details`,{method:"GET",headers:{[(0,a.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!r.ok)throw Error(`Failed to fetch health readiness details: ${r.statusText}`);return r.json()},i=e=>(0,r.useQuery)({queryKey:n.detail("readiness"),queryFn:()=>l(e),enabled:!!e,staleTime:3e5,retry:!1});e.s(["useHealthReadinessDetails",0,i],143488);var s=e.i(115571),o=e.i(271645);function c(e){let t=t=>{"disableBouncingIcon"===t.key&&e()},r=t=>{let{key:r}=t.detail;"disableBouncingIcon"===r&&e()};return window.addEventListener("storage",t),window.addEventListener(s.LOCAL_STORAGE_EVENT,r),()=>{window.removeEventListener("storage",t),window.removeEventListener(s.LOCAL_STORAGE_EVENT,r)}}function d(){return"true"===(0,s.getLocalStorageItem)("disableBouncingIcon")}function u(){return(0,o.useSyncExternalStore)(c,d)}function h(e){let t=t=>{"disableShowPrompts"===t.key&&e()},r=t=>{let{key:r}=t.detail;"disableShowPrompts"===r&&e()};return window.addEventListener("storage",t),window.addEventListener(s.LOCAL_STORAGE_EVENT,r),()=>{window.removeEventListener("storage",t),window.removeEventListener(s.LOCAL_STORAGE_EVENT,r)}}function m(){return"true"===(0,s.getLocalStorageItem)("disableShowPrompts")}function g(){return(0,o.useSyncExternalStore)(h,m)}var p=e.i(283713),f=e.i(275144),x=e.i(268004),y=e.i(321836),v=e.i(592392),b=e.i(755151);e.i(247167);var w=e.i(931067);let j={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 000 13.8z"}}]},name:"menu-fold",theme:"outlined"};var S=e.i(9583),L=o.forwardRef(function(e,t){return o.createElement(S.default,(0,w.default)({},e,{ref:t,icon:j}))});let k={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 000-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0014.4 7z"}}]},name:"menu-unfold",theme:"outlined"};var C=o.forwardRef(function(e,t){return o.createElement(S.default,(0,w.default)({},e,{ref:t,icon:k}))}),N=e.i(262218),_=e.i(522016);function E(e){let t=t=>{"disableBlogPosts"===t.key&&e()},r=t=>{let{key:r}=t.detail;"disableBlogPosts"===r&&e()};return window.addEventListener("storage",t),window.addEventListener(s.LOCAL_STORAGE_EVENT,r),()=>{window.removeEventListener("storage",t),window.removeEventListener(s.LOCAL_STORAGE_EVENT,r)}}function T(){return"true"===(0,s.getLocalStorageItem)("disableBlogPosts")}function O(){return(0,o.useSyncExternalStore)(E,T)}async function P(){let e=(0,a.getProxyBaseUrl)(),t=await fetch(`${e}/public/litellm_blog_posts`);if(!t.ok)throw Error(`Failed to fetch blog posts: ${t.statusText}`);return t.json()}let B="inline-flex h-9 shrink-0 items-center justify-center gap-1 rounded-md px-2 text-sm font-medium leading-none text-gray-800 transition-colors hover:bg-gray-100 hover:text-gray-950";var I=e.i(56456),A=e.i(464571),z=e.i(326373),R=e.i(770914),M=e.i(898586);let{Text:U,Title:H,Paragraph:$}=M.Typography,D=()=>{let e,a=O(),{data:n,isLoading:l,isError:i,refetch:s}=(0,r.useQuery)({queryKey:["blogPosts"],queryFn:P,staleTime:36e5,retry:1,retryDelay:0});return a?null:(e=l?[{key:"loading",label:(0,t.jsx)(I.LoadingOutlined,{}),disabled:!0}]:i?[{key:"error",label:(0,t.jsxs)(R.Space,{children:[(0,t.jsx)(U,{type:"danger",children:"Failed to load posts"}),(0,t.jsx)(A.Button,{size:"small",onClick:()=>s(),children:"Retry"})]}),disabled:!0}]:n&&0!==n.posts.length?[...n.posts.slice(0,5).map(e=>({key:e.url,label:(0,t.jsxs)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",style:{display:"block",width:380},children:[(0,t.jsx)(H,{level:5,style:{marginBottom:2},children:e.title}),(0,t.jsx)(U,{type:"secondary",style:{fontSize:11},children:new Date(e.date+"T00:00:00").toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}),(0,t.jsx)($,{ellipsis:{rows:2},children:e.description})]})})),{type:"divider"},{key:"view-all",label:(0,t.jsx)("a",{href:"https://docs.litellm.ai/blog",target:"_blank",rel:"noopener noreferrer",children:"View all posts"})}]:[{key:"empty",label:(0,t.jsx)(U,{type:"secondary",children:"No posts available"}),disabled:!0}],(0,t.jsx)(z.Dropdown,{menu:{items:e},trigger:["hover"],placement:"bottomRight",children:(0,t.jsxs)(A.Button,{type:"text",className:`${B} border-0! bg-transparent!`,children:["Blog",(0,t.jsx)(b.DownOutlined,{className:"text-[10px] text-gray-500","aria-hidden":!0})]})}))},V={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M511.6 76.3C264.3 76.2 64 276.4 64 523.5 64 718.9 189.3 885 363.8 946c23.5 5.9 19.9-10.8 19.9-22.2v-77.5c-135.7 15.9-141.2-73.9-150.3-88.9C215 726 171.5 718 184.5 703c30.9-15.9 62.4 4 98.9 57.9 26.4 39.1 77.9 32.5 104 26 5.7-23.5 17.9-44.5 34.7-60.8-140.6-25.2-199.2-111-199.2-213 0-49.5 16.3-95 48.3-131.7-20.4-60.5 1.9-112.3 4.9-120 58.1-5.2 118.5 41.6 123.2 45.3 33-8.9 70.7-13.6 112.9-13.6 42.4 0 80.2 4.9 113.5 13.9 11.3-8.6 67.3-48.8 121.3-43.9 2.9 7.7 24.7 58.3 5.5 118 32.4 36.8 48.9 82.7 48.9 132.3 0 102.2-59 188.1-200 212.9a127.5 127.5 0 0138.1 91v112.5c.8 9 0 17.9 15 17.9 177.1-59.7 304.6-227 304.6-424.1 0-247.2-200.4-447.3-447.5-447.3z"}}]},name:"github",theme:"outlined"};var G=o.forwardRef(function(e,t){return o.createElement(S.default,(0,w.default)({},e,{ref:t,icon:V}))});let K={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M409.4 128c-42.4 0-76.7 34.4-76.7 76.8 0 20.3 8.1 39.9 22.4 54.3a76.74 76.74 0 0054.3 22.5h76.7v-76.8c0-42.3-34.3-76.7-76.7-76.8zm0 204.8H204.7c-42.4 0-76.7 34.4-76.7 76.8s34.4 76.8 76.7 76.8h204.6c42.4 0 76.7-34.4 76.7-76.8.1-42.4-34.3-76.8-76.6-76.8zM614 486.4c42.4 0 76.8-34.4 76.7-76.8V204.8c0-42.4-34.3-76.8-76.7-76.8-42.4 0-76.7 34.4-76.7 76.8v204.8c0 42.5 34.3 76.8 76.7 76.8zm281.4-76.8c0-42.4-34.4-76.8-76.7-76.8S742 367.2 742 409.6v76.8h76.7c42.3 0 76.7-34.4 76.7-76.8zm-76.8 128H614c-42.4 0-76.7 34.4-76.7 76.8 0 20.3 8.1 39.9 22.4 54.3a76.74 76.74 0 0054.3 22.5h204.6c42.4 0 76.7-34.4 76.7-76.8.1-42.4-34.3-76.7-76.7-76.8zM614 742.4h-76.7v76.8c0 42.4 34.4 76.8 76.7 76.8 42.4 0 76.8-34.4 76.7-76.8.1-42.4-34.3-76.7-76.7-76.8zM409.4 537.6c-42.4 0-76.7 34.4-76.7 76.8v204.8c0 42.4 34.4 76.8 76.7 76.8 42.4 0 76.8-34.4 76.7-76.8V614.4c0-20.3-8.1-39.9-22.4-54.3a76.92 76.92 0 00-54.3-22.5zM128 614.4c0 20.3 8.1 39.9 22.4 54.3a76.74 76.74 0 0054.3 22.5c42.4 0 76.8-34.4 76.7-76.8v-76.8h-76.7c-42.3 0-76.7 34.4-76.7 76.8z"}}]},name:"slack",theme:"outlined"};var F=o.forwardRef(function(e,t){return o.createElement(S.default,(0,w.default)({},e,{ref:t,icon:K}))}),W=e.i(592968);let q="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-md border-0 bg-transparent text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700 cursor-pointer",Q=()=>g()?null:(0,t.jsxs)("div",{className:"flex items-center gap-0.5 rounded-md border border-gray-200/80 bg-gray-50 px-0.5 py-0","aria-label":"Community links",children:[(0,t.jsx)(W.Tooltip,{title:"LiteLLM Slack community",children:(0,t.jsx)("a",{href:"https://www.litellm.ai/support",target:"_blank",rel:"noopener noreferrer",className:q,"aria-label":"Join Slack",children:(0,t.jsx)(F,{className:"text-lg"})})}),(0,t.jsx)(W.Tooltip,{title:"LiteLLM on GitHub",children:(0,t.jsx)("a",{href:"https://github.com/BerriAI/litellm",target:"_blank",rel:"noopener noreferrer",className:q,"aria-label":"LiteLLM on GitHub",children:(0,t.jsx)(G,{className:"text-lg"})})})]}),X="litellmHideAgentPlatformBanner";function J(e){let t=t=>{t.key===X&&e()},r=t=>{let{key:r}=t.detail;r===X&&e()};return window.addEventListener("storage",t),window.addEventListener(s.LOCAL_STORAGE_EVENT,r),()=>{window.removeEventListener("storage",t),window.removeEventListener(s.LOCAL_STORAGE_EVENT,r)}}function Y(){return"true"===(0,s.getLocalStorageItem)(X)}let Z={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M816 768h-24V428c0-141.1-104.3-257.7-240-277.1V112c0-22.1-17.9-40-40-40s-40 17.9-40 40v38.9c-135.7 19.4-240 136-240 277.1v340h-24c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h216c0 61.8 50.2 112 112 112s112-50.2 112-112h216c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM512 888c-26.5 0-48-21.5-48-48h96c0 26.5-21.5 48-48 48zM304 768V428c0-55.6 21.6-107.8 60.9-147.1S456.4 220 512 220c55.6 0 107.8 21.6 147.1 60.9S720 372.4 720 428v340H304z"}}]},name:"bell",theme:"outlined"};var ee=o.forwardRef(function(e,t){return o.createElement(S.default,(0,w.default)({},e,{ref:t,icon:Z}))}),et=e.i(906579),er=e.i(282786);let ea=()=>{let e=!(0,o.useSyncExternalStore)(J,Y),[r,a]=(0,o.useState)(!1),n=(0,t.jsxs)("div",{className:"max-w-[280px]",children:[(0,t.jsx)(M.Typography.Title,{level:5,className:"mt-0! mb-2!",children:"LiteLLM Agent Platform"}),(0,t.jsx)(M.Typography.Paragraph,{type:"secondary",className:"mb-3! text-sm leading-snug",children:"Open-source agent infra — sandboxes, durable sessions, and workers on AWS Fargate."}),(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,t.jsx)(A.Button,{type:"primary",size:"small",href:"https://github.com/BerriAI/litellm-agent-platform",target:"_blank",rel:"noopener noreferrer",children:"GitHub"}),e?(0,t.jsx)(A.Button,{type:"link",size:"small",className:"px-1!",onClick:()=>{(0,s.setLocalStorageItem)(X,"true"),(0,s.emitLocalStorageChange)(X),a(!1)},children:"Mark as read"}):null]})]});return(0,t.jsx)(er.Popover,{content:n,trigger:"click",open:r,onOpenChange:a,placement:"bottomRight",children:(0,t.jsx)(A.Button,{type:"text",className:"flex! h-9! w-9! items-center justify-center rounded-md! text-gray-600 transition-colors hover:bg-gray-100! hover:text-gray-900!","aria-label":"Notifications",children:(0,t.jsx)(et.Badge,{dot:e,color:"#1677ff",size:"small",offset:[8,2],children:(0,t.jsx)(ee,{className:"text-base","aria-hidden":!0})})})})};var en=e.i(135214),el=e.i(371401),ei=e.i(100486);let es={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M868 732h-70.3c-4.8 0-9.3 2.1-12.3 5.8-7 8.5-14.5 16.7-22.4 24.5a353.84 353.84 0 01-112.7 75.9A352.8 352.8 0 01512.4 866c-47.9 0-94.3-9.4-137.9-27.8a353.84 353.84 0 01-112.7-75.9 353.28 353.28 0 01-76-112.5C167.3 606.2 158 559.9 158 512s9.4-94.2 27.8-137.8c17.8-42.1 43.4-80 76-112.5s70.5-58.1 112.7-75.9c43.6-18.4 90-27.8 137.9-27.8 47.9 0 94.3 9.3 137.9 27.8 42.2 17.8 80.1 43.4 112.7 75.9 7.9 7.9 15.3 16.1 22.4 24.5 3 3.7 7.6 5.8 12.3 5.8H868c6.3 0 10.2-7 6.7-12.3C798 160.5 663.8 81.6 511.3 82 271.7 82.6 79.6 277.1 82 516.4 84.4 751.9 276.2 942 512.4 942c152.1 0 285.7-78.8 362.3-197.7 3.4-5.3-.4-12.3-6.7-12.3zm88.9-226.3L815 393.7c-5.3-4.2-13-.4-13 6.3v76H488c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h314v76c0 6.7 7.8 10.5 13 6.3l141.9-112a8 8 0 000-12.6z"}}]},name:"logout",theme:"outlined"};var eo=o.forwardRef(function(e,t){return o.createElement(S.default,(0,w.default)({},e,{ref:t,icon:es}))});let ec={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M928 160H96c-17.7 0-32 14.3-32 32v640c0 17.7 14.3 32 32 32h832c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32zm-40 110.8V792H136V270.8l-27.6-21.5 39.3-50.5 42.8 33.3h643.1l42.8-33.3 39.3 50.5-27.7 21.5zM833.6 232L512 482 190.4 232l-42.8-33.3-39.3 50.5 27.6 21.5 341.6 265.6a55.99 55.99 0 0068.7 0L888 270.8l27.6-21.5-39.3-50.5-42.7 33.2z"}}]},name:"mail",theme:"outlined"};var ed=o.forwardRef(function(e,t){return o.createElement(S.default,(0,w.default)({},e,{ref:t,icon:ec}))}),eu=e.i(602073),eh=e.i(771674),em=e.i(312361),eg=e.i(790848);let{Text:ep}=M.Typography,ef=({onLogout:e})=>{let{userId:r,userEmail:a,userRole:n,premiumUser:l}=(0,en.default)(),i=g(),c=(0,el.useDisableUsageIndicator)(),d=O(),h=u(),[m,p]=(0,o.useState)(!1);(0,o.useEffect)(()=>{p("true"===(0,s.getLocalStorageItem)("disableShowNewBadge"))},[]);let f=[{key:"logout",label:(0,t.jsxs)(R.Space,{children:[(0,t.jsx)(eo,{}),"Logout"]}),onClick:e}],x=a||r||"user",y=function(e,t){let r=e?.split("@")[0]?.trim();if(r){let e=r.replace(/[^a-zA-Z0-9]+/g," ").trim().split(/\s+/).filter(Boolean);if(e.length>=2)return`${e[0].charAt(0)}${e[1].charAt(0)}`.toUpperCase();if(1===e.length){let t=e[0];return t.length>=2?t.slice(0,2).toUpperCase():`${t.charAt(0)}`.toUpperCase()}}return t&&t.length>=2?t.slice(0,2).toUpperCase():t&&1===t.length?`${t.toUpperCase()}•`:"?"}(a,r),v=function(e){let t=0;for(let r=0;r(0,t.jsxs)("div",{className:"rounded-lg bg-white shadow-lg","data-testid":"user-dropdown-panel",children:[(0,t.jsxs)(R.Space,{direction:"vertical",size:"small",style:{width:"100%",padding:"12px"},children:[(0,t.jsxs)(R.Space,{style:{width:"100%",justifyContent:"space-between"},children:[(0,t.jsxs)(R.Space,{children:[(0,t.jsx)(ed,{}),(0,t.jsx)(ep,{type:"secondary",children:a||"-"})]}),l?(0,t.jsx)(N.Tag,{icon:(0,t.jsx)(ei.CrownOutlined,{}),color:"gold",children:"Premium"}):(0,t.jsx)(W.Tooltip,{title:"Upgrade to Premium for advanced features",placement:"left",children:(0,t.jsx)(N.Tag,{icon:(0,t.jsx)(ei.CrownOutlined,{}),children:"Standard"})})]}),(0,t.jsx)(em.Divider,{style:{margin:"8px 0"}}),(0,t.jsxs)(R.Space,{style:{width:"100%",justifyContent:"space-between"},children:[(0,t.jsxs)(R.Space,{children:[(0,t.jsx)(eh.UserOutlined,{}),(0,t.jsx)(ep,{type:"secondary",children:"User ID"})]}),(0,t.jsx)(ep,{copyable:!0,ellipsis:!0,style:{maxWidth:"150px"},title:r||"-",children:r||"-"})]}),(0,t.jsxs)(R.Space,{style:{width:"100%",justifyContent:"space-between"},children:[(0,t.jsxs)(R.Space,{children:[(0,t.jsx)(eu.SafetyOutlined,{}),(0,t.jsx)(ep,{type:"secondary",children:"Role"})]}),(0,t.jsx)(ep,{children:n})]}),(0,t.jsx)(em.Divider,{style:{margin:"8px 0"}}),(0,t.jsxs)(R.Space,{style:{width:"100%",justifyContent:"space-between"},children:[(0,t.jsx)(ep,{type:"secondary",children:"Hide New Feature Indicators"}),(0,t.jsx)(eg.Switch,{size:"small",checked:m,onChange:e=>{p(e),e?(0,s.setLocalStorageItem)("disableShowNewBadge","true"):(0,s.removeLocalStorageItem)("disableShowNewBadge"),(0,s.emitLocalStorageChange)("disableShowNewBadge")},"aria-label":"Toggle hide new feature indicators"})]}),(0,t.jsxs)(R.Space,{style:{width:"100%",justifyContent:"space-between"},children:[(0,t.jsx)(ep,{type:"secondary",children:"Hide All Prompts"}),(0,t.jsx)(eg.Switch,{size:"small",checked:i,onChange:e=>{e?(0,s.setLocalStorageItem)("disableShowPrompts","true"):(0,s.removeLocalStorageItem)("disableShowPrompts"),(0,s.emitLocalStorageChange)("disableShowPrompts")},"aria-label":"Toggle hide all prompts"})]}),(0,t.jsxs)(R.Space,{style:{width:"100%",justifyContent:"space-between"},children:[(0,t.jsx)(ep,{type:"secondary",children:"Hide Usage Indicator"}),(0,t.jsx)(eg.Switch,{size:"small",checked:c,onChange:e=>{e?(0,s.setLocalStorageItem)("disableUsageIndicator","true"):(0,s.removeLocalStorageItem)("disableUsageIndicator"),(0,s.emitLocalStorageChange)("disableUsageIndicator")},"aria-label":"Toggle hide usage indicator"})]}),(0,t.jsxs)(R.Space,{style:{width:"100%",justifyContent:"space-between"},children:[(0,t.jsx)(ep,{type:"secondary",children:"Hide Blog Posts"}),(0,t.jsx)(eg.Switch,{size:"small",checked:d,onChange:e=>{e?(0,s.setLocalStorageItem)("disableBlogPosts","true"):(0,s.removeLocalStorageItem)("disableBlogPosts"),(0,s.emitLocalStorageChange)("disableBlogPosts")},"aria-label":"Toggle hide blog posts"})]}),(0,t.jsxs)(R.Space,{style:{width:"100%",justifyContent:"space-between"},children:[(0,t.jsx)(ep,{type:"secondary",children:"Hide Bouncing Icon"}),(0,t.jsx)(eg.Switch,{size:"small",checked:h,onChange:e=>{e?(0,s.setLocalStorageItem)("disableBouncingIcon","true"):(0,s.removeLocalStorageItem)("disableBouncingIcon"),(0,s.emitLocalStorageChange)("disableBouncingIcon")},"aria-label":"Toggle hide bouncing icon"})]})]}),(0,t.jsx)(em.Divider,{style:{margin:0}}),o.default.cloneElement(e,{style:{boxShadow:"none"}})]}),children:(0,t.jsxs)(A.Button,{type:"text",className:"flex! max-w-[min(200px,34vw)] items-center gap-2 rounded-md! py-0.5! pl-1! pr-2! transition-colors hover:bg-gray-100!","aria-label":`Account menu — ${n??"Unknown role"} — signed in as ${a||r||"unknown"}`,"aria-haspopup":"menu",children:[(0,t.jsx)("span",{className:"flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-xs font-semibold text-white shadow-inner ring-1 ring-black/5",style:{backgroundColor:`hsl(${v} 46% 38%)`},"aria-hidden":!0,children:y}),(0,t.jsx)("span",{className:"hidden min-w-0 truncate text-left text-sm font-medium leading-none text-gray-900 md:inline",children:w}),(0,t.jsx)(b.DownOutlined,{className:"hidden shrink-0 text-[10px] text-gray-400 md:inline","aria-hidden":!0})]})})};var ex=e.i(618566),ey=e.i(477189),ev=e.i(492030),eb=e.i(431703);let ew=(0,o.createContext)({mode:"ai-gateway",setMode:()=>{},plugins:[],activePlugin:null}),ej="litellm_plugin_mode",eS=(0,eb.createApiClient)({getBaseUrl:()=>(0,a.getProxyBaseUrl)()??""});function eL(){return localStorage.getItem(ej)??"ai-gateway"}function ek(){return(0,o.useContext)(ew)}e.s(["PluginModeProvider",0,function({children:e,accessToken:r}){let[a,n]=(0,o.useState)(eL),[l,i]=(0,o.useState)([]),[s,c]=(0,o.useState)(!1);(0,o.useEffect)(()=>{r&&eS.get("/api/plugins",{accessToken:r}).then(e=>{i(Array.isArray(e)?e:[])}).catch(()=>{}).finally(()=>c(!0))},[r]);let d="ai-gateway"!==a&&s&&!l.some(e=>e.name===a)?"ai-gateway":a,u=l.find(e=>e.name===d)??null;return(0,t.jsx)(ew.Provider,{value:{mode:d,setMode:e=>{n(e),localStorage.setItem(ej,e)},plugins:l,activePlugin:u},children:e})},"usePluginMode",0,ek],658140);var eC=e.i(292639),eN=e.i(571353);let e_="chat";function eE(){let{mode:e,setMode:r,plugins:a}=ek(),{data:n}=(0,eC.useUISettings)(),l=(0,ex.usePathname)(),i=!!n?.values?.enable_chat_ui;if(0===a.length&&!i)return null;let s=(0,eN.migratedHref)(e_),o=(l??"").replace(/\/+$/,""),c=i&&(o===s||o.startsWith(`${s}/`)),d=c?"Chat":a.find(t=>t.name===e)?.display_name??"AI Gateway",u=[...[{key:"ai-gateway",label:"AI Gateway"},...a.map(e=>({key:e.name,label:e.display_name}))].map(r=>({key:r.key,label:(0,t.jsxs)("div",{className:"flex items-center justify-between gap-6 py-0.5",children:[(0,t.jsx)("span",{className:"font-medium",children:r.label}),!c&&r.key===e&&(0,t.jsx)(ev.CheckOutlined,{className:"text-blue-600"})]})})),...i?[{key:e_,label:(0,t.jsxs)("div",{className:"flex items-center justify-between gap-6 py-0.5",children:[(0,t.jsx)("span",{className:"font-medium",children:"Chat"}),c&&(0,t.jsx)(ev.CheckOutlined,{className:"text-blue-600"})]})}]:[]];return(0,t.jsx)(z.Dropdown,{menu:{items:u,onClick:({key:e})=>{e===e_?window.location.assign((0,eN.migratedHref)(e_)):(r(e),c&&window.location.assign((0,eN.migratedHref)("")))},selectedKeys:[c?e_:e]},trigger:["click"],children:(0,t.jsxs)("button",{type:"button",className:"flex items-center gap-2 rounded-md border border-gray-200 px-2.5 py-1.5 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50",children:[(0,t.jsx)(ey.AppstoreOutlined,{className:"text-gray-500"}),(0,t.jsx)("span",{children:d}),(0,t.jsx)(b.DownOutlined,{className:"text-[10px] text-gray-400"})]})})}var eT=e.i(199133),eO=e.i(295320);let eP=({onWorkerSwitch:e})=>{let{isControlPlane:r,selectedWorker:a,workers:n}=(0,p.useWorker)();return r&&a?(0,t.jsx)(eT.Select,{showSearch:!0,filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase()),value:a.worker_id,style:{minWidth:180},suffixIcon:(0,t.jsx)(eO.CloudServerOutlined,{}),options:n.map(e=>({label:e.name,value:e.worker_id,disabled:e.worker_id===a.worker_id})),onChange:t=>{e(t)}}):null};e.s(["default",0,({accessToken:e,isPublicPage:r=!1,sidebarCollapsed:n=!1,onToggleSidebar:l})=>{let s=(0,a.getProxyBaseUrl)(),o=(0,v.default)(e),{logoUrl:c}=(0,f.useTheme)(),{data:d}=i(e),h=d?.litellm_version,m=u(),w=g(),{isControlPlane:j,selectedWorker:S}=(0,p.useWorker)(),k=j&&null!==S,E=c||`${s}/get_image`;return(0,t.jsx)("nav",{className:"sticky top-0 z-10 border-b border-gray-200 bg-white",children:(0,t.jsx)("div",{className:"w-full",children:(0,t.jsxs)("div",{className:"flex h-14 items-center px-4",children:[(0,t.jsxs)("div",{className:"flex shrink-0 items-center",children:[l&&(0,t.jsx)("button",{onClick:l,className:"mr-2 flex h-9 w-9 items-center justify-center rounded-md text-gray-600 transition-colors hover:bg-gray-100 hover:text-gray-900",title:n?"Expand sidebar":"Collapse sidebar",children:(0,t.jsx)("span",{className:"text-lg",children:n?(0,t.jsx)(C,{}):(0,t.jsx)(L,{})})}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(_.default,{href:s||"/",className:"flex items-center",children:(0,t.jsx)("div",{className:"relative",children:(0,t.jsx)("div",{className:"flex h-10 max-w-48 items-center justify-center overflow-hidden",children:(0,t.jsx)("img",{src:E,alt:"LiteLLM Brand",className:"h-auto max-h-full w-auto max-w-full object-contain"})})})}),h&&(0,t.jsxs)("div",{className:"relative",children:[!m&&(0,t.jsx)("span",{className:"absolute -left-2 -top-1 animate-bounce text-lg",style:{animationDuration:"2s"},title:"Thanks for using LiteLLM!",children:"🌑"}),(0,t.jsx)(N.Tag,{className:"relative z-10 cursor-pointer text-xs font-medium",children:(0,t.jsxs)("a",{href:"https://docs.litellm.ai/release_notes",target:"_blank",rel:"noopener noreferrer",className:"shrink-0",children:["v",h]})})]})]})]}),!r&&(0,t.jsx)("div",{className:"ml-4 flex shrink-0 items-center border-l border-gray-200 pl-4",children:(0,t.jsx)(eE,{})}),(0,t.jsxs)("div",{className:"ml-auto flex min-w-0 flex-1 items-center justify-end gap-4",children:[k&&(0,t.jsx)("div",{className:"flex shrink-0 items-center",children:(0,t.jsx)(eP,{onWorkerSwitch:e=>{(0,x.clearTokenCookies)(),(0,y.clearStoredReturnUrl)(),localStorage.removeItem("litellm_selected_worker_id"),localStorage.removeItem("litellm_worker_url"),window.location.href=`/ui/login?worker=${encodeURIComponent(e)}`}})}),(0,t.jsxs)("nav",{"aria-label":"Product documentation",className:`flex min-w-0 items-center gap-2 ${k?"border-l border-gray-200 pl-4":""}`,children:[(0,t.jsxs)("a",{href:"https://docs.litellm.ai/docs/",target:"_blank",rel:"noopener noreferrer",className:B,children:["Docs",(0,t.jsx)(b.DownOutlined,{className:"pointer-events-none text-[10px] opacity-0","aria-hidden":!0})]}),(0,t.jsx)(D,{})]}),!w&&(0,t.jsx)("div",{className:"flex shrink-0 items-center border-l border-gray-200 pl-4",children:(0,t.jsx)(Q,{})}),!r&&(0,t.jsx)("div",{className:"flex shrink-0 items-center border-l border-gray-200 pl-4",children:(0,t.jsxs)("div",{className:"flex items-center gap-0.5 rounded-lg bg-gray-50 px-1 py-0 transition-colors hover:bg-gray-100",children:[(0,t.jsx)(ea,{}),(0,t.jsx)("span",{className:"mx-0.5 h-6 w-px shrink-0 bg-gray-200","aria-hidden":!0}),(0,t.jsx)(ef,{onLogout:()=>{(0,x.clearTokenCookies)(),localStorage.removeItem("litellm_selected_worker_id"),localStorage.removeItem("litellm_worker_url"),window.location.href=o.PROXY_LOGOUT_URL||""}})]})})]})]})})})}],402874)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0p5z5ih0v4llb.js b/litellm/proxy/_experimental/out/_next/static/chunks/0p5z5ih0v4llb.js new file mode 100644 index 00000000000..25528ebcfa9 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/0p5z5ih0v4llb.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,728889,e=>{"use strict";var t=e.i(290571),r=e.i(271645),a=e.i(829087),l=e.i(480731),n=e.i(444755),s=e.i(673706),i=e.i(95779);let o={xs:{paddingX:"px-1.5",paddingY:"py-1.5"},sm:{paddingX:"px-1.5",paddingY:"py-1.5"},md:{paddingX:"px-2",paddingY:"py-2"},lg:{paddingX:"px-2",paddingY:"py-2"},xl:{paddingX:"px-2.5",paddingY:"py-2.5"}},d={xs:{height:"h-3",width:"w-3"},sm:{height:"h-5",width:"w-5"},md:{height:"h-5",width:"w-5"},lg:{height:"h-7",width:"w-7"},xl:{height:"h-9",width:"w-9"}},c={simple:{rounded:"",border:"",ring:"",shadow:""},light:{rounded:"rounded-tremor-default",border:"",ring:"",shadow:""},shadow:{rounded:"rounded-tremor-default",border:"border",ring:"",shadow:"shadow-tremor-card dark:shadow-dark-tremor-card"},solid:{rounded:"rounded-tremor-default",border:"border-2",ring:"ring-1",shadow:""},outlined:{rounded:"rounded-tremor-default",border:"border",ring:"ring-2",shadow:""}},u=(0,s.makeClassName)("Icon"),m=r.default.forwardRef((e,m)=>{let{icon:h,variant:f="simple",tooltip:p,size:g=l.Sizes.SM,color:b,className:v}=e,x=(0,t.__rest)(e,["icon","variant","tooltip","size","color","className"]),y=((e,t)=>{switch(e){case"simple":return{textColor:t?(0,s.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:"",borderColor:"",ringColor:""};case"light":return{textColor:t?(0,s.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,n.tremorTwMerge)((0,s.getColorClassNames)(t,i.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-brand-muted dark:bg-dark-tremor-brand-muted",borderColor:"",ringColor:""};case"shadow":return{textColor:t?(0,s.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,n.tremorTwMerge)((0,s.getColorClassNames)(t,i.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:"border-tremor-border dark:border-dark-tremor-border",ringColor:""};case"solid":return{textColor:t?(0,s.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand-inverted dark:text-dark-tremor-brand-inverted",bgColor:t?(0,n.tremorTwMerge)((0,s.getColorClassNames)(t,i.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-brand dark:bg-dark-tremor-brand",borderColor:"border-tremor-brand-inverted dark:border-dark-tremor-brand-inverted",ringColor:"ring-tremor-ring dark:ring-dark-tremor-ring"};case"outlined":return{textColor:t?(0,s.getColorClassNames)(t,i.colorPalette.text).textColor:"text-tremor-brand dark:text-dark-tremor-brand",bgColor:t?(0,n.tremorTwMerge)((0,s.getColorClassNames)(t,i.colorPalette.background).bgColor,"bg-opacity-20"):"bg-tremor-background dark:bg-dark-tremor-background",borderColor:t?(0,s.getColorClassNames)(t,i.colorPalette.ring).borderColor:"border-tremor-brand-subtle dark:border-dark-tremor-brand-subtle",ringColor:t?(0,n.tremorTwMerge)((0,s.getColorClassNames)(t,i.colorPalette.ring).ringColor,"ring-opacity-40"):"ring-tremor-brand-muted dark:ring-dark-tremor-brand-muted"}}})(f,b),{tooltipProps:w,getReferenceProps:C}=(0,a.useTooltip)();return r.default.createElement("span",Object.assign({ref:(0,s.mergeRefs)([m,w.refs.setReference]),className:(0,n.tremorTwMerge)(u("root"),"inline-flex shrink-0 items-center justify-center",y.bgColor,y.textColor,y.borderColor,y.ringColor,c[f].rounded,c[f].border,c[f].shadow,c[f].ring,o[g].paddingX,o[g].paddingY,v)},C,x),r.default.createElement(a.default,Object.assign({text:p},w)),r.default.createElement(h,{className:(0,n.tremorTwMerge)(u("icon"),"shrink-0",d[g].height,d[g].width)}))});m.displayName="Icon",e.s(["default",0,m],728889)},752978,e=>{"use strict";var t=e.i(728889);e.s(["Icon",()=>t.default])},591935,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"}))});e.s(["PencilAltIcon",0,r],591935)},434626,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"}))});e.s(["ExternalLinkIcon",0,r],434626)},551332,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"}))});e.s(["ClipboardCopyIcon",0,r],551332)},122577,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"}),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M21 12a9 9 0 11-18 0 9 9 0 0118 0z"}))});e.s(["PlayIcon",0,r],122577)},902555,e=>{"use strict";var t=e.i(843476),r=e.i(591935),a=e.i(122577),l=e.i(278587),n=e.i(68155),s=e.i(360820),i=e.i(871943),o=e.i(434626),d=e.i(551332),c=e.i(592968),u=e.i(115504),m=e.i(752978);function h({icon:e,onClick:r,className:a,disabled:l,dataTestId:n}){return l?(0,t.jsx)(m.Icon,{icon:e,size:"sm",className:"opacity-50 cursor-not-allowed","data-testid":n}):(0,t.jsx)(m.Icon,{icon:e,size:"sm",onClick:r,className:(0,u.cx)("cursor-pointer",a),"data-testid":n})}let f={Edit:{icon:r.PencilAltIcon,className:"hover:text-blue-600"},Delete:{icon:n.TrashIcon,className:"hover:text-red-600"},Test:{icon:a.PlayIcon,className:"hover:text-blue-600"},Regenerate:{icon:l.RefreshIcon,className:"hover:text-green-600"},Up:{icon:s.ChevronUpIcon,className:"hover:text-blue-600"},Down:{icon:i.ChevronDownIcon,className:"hover:text-blue-600"},Open:{icon:o.ExternalLinkIcon,className:"hover:text-green-600"},Copy:{icon:d.ClipboardCopyIcon,className:"hover:text-blue-600"}};e.s(["default",0,function({onClick:e,tooltipText:r,disabled:a=!1,disabledTooltipText:l,dataTestId:n,variant:s}){let{icon:i,className:o}=f[s];return(0,t.jsx)(c.Tooltip,{title:a?l:r,children:(0,t.jsx)("span",{children:(0,t.jsx)(h,{icon:i,onClick:e,className:o,disabled:a,dataTestId:n})})})}],902555)},991124,e=>{"use strict";let t=(0,e.i(475254).default)("copy",[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]]);e.s(["default",0,t])},678745,e=>{"use strict";let t=(0,e.i(475254).default)("check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]]);e.s(["default",0,t])},678784,e=>{"use strict";var t=e.i(678745);e.s(["CheckIcon",()=>t.default])},118366,e=>{"use strict";var t=e.i(991124);e.s(["CopyIcon",()=>t.default])},564897,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M696 480H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8z"}},{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"}}]},name:"minus-circle",theme:"outlined"};var l=e.i(9583),n=r.forwardRef(function(e,n){return r.createElement(l.default,(0,t.default)({},e,{ref:n,icon:a}))});e.s(["MinusCircleOutlined",0,n],564897)},91979,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M909.1 209.3l-56.4 44.1C775.8 155.1 656.2 92 521.9 92 290 92 102.3 279.5 102 511.5 101.7 743.7 289.8 932 521.9 932c181.3 0 335.8-115 394.6-276.1 1.5-4.2-.7-8.9-4.9-10.3l-56.7-19.5a8 8 0 00-10.1 4.8c-1.8 5-3.8 10-5.9 14.9-17.3 41-42.1 77.8-73.7 109.4A344.77 344.77 0 01655.9 829c-42.3 17.9-87.4 27-133.8 27-46.5 0-91.5-9.1-133.8-27A341.5 341.5 0 01279 755.2a342.16 342.16 0 01-73.7-109.4c-17.9-42.4-27-87.4-27-133.9s9.1-91.5 27-133.9c17.3-41 42.1-77.8 73.7-109.4 31.6-31.6 68.4-56.4 109.3-73.8 42.3-17.9 87.4-27 133.8-27 46.5 0 91.5 9.1 133.8 27a341.5 341.5 0 01109.3 73.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 003 14.1l175.6 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c-.1-6.6-7.8-10.3-13-6.2z"}}]},name:"reload",theme:"outlined"};var l=e.i(9583),n=r.forwardRef(function(e,n){return r.createElement(l.default,(0,t.default)({},e,{ref:n,icon:a}))});e.s(["ReloadOutlined",0,n],91979)},751904,e=>{"use strict";var t=e.i(401361);e.s(["EditOutlined",()=>t.default])},987432,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M893.3 293.3L730.7 130.7c-7.5-7.5-16.7-13-26.7-16V112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V338.5c0-17-6.7-33.2-18.7-45.2zM384 184h256v104H384V184zm456 656H184V184h136v136c0 17.7 14.3 32 32 32h320c17.7 0 32-14.3 32-32V205.8l136 136V840zM512 442c-79.5 0-144 64.5-144 144s64.5 144 144 144 144-64.5 144-144-64.5-144-144-144zm0 224c-44.2 0-80-35.8-80-80s35.8-80 80-80 80 35.8 80 80-35.8 80-80 80z"}}]},name:"save",theme:"outlined"};var l=e.i(9583),n=r.forwardRef(function(e,n){return r.createElement(l.default,(0,t.default)({},e,{ref:n,icon:a}))});e.s(["SaveOutlined",0,n],987432)},21548,e=>{"use strict";var t=e.i(616303);e.s(["Empty",()=>t.default])},54943,e=>{"use strict";let t=(0,e.i(475254).default)("search",[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]]);e.s(["default",0,t])},438100,e=>{"use strict";let t=(0,e.i(475254).default)("key",[["path",{d:"m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4",key:"g0fldk"}],["path",{d:"m21 2-9.6 9.6",key:"1j0ho8"}],["circle",{cx:"7.5",cy:"15.5",r:"5.5",key:"yqb3hr"}]]);e.s(["KeyIcon",0,t],438100)},988846,e=>{"use strict";var t=e.i(54943);e.s(["SearchIcon",()=>t.default])},822315,(e,t,r)=>{e.e,t.exports=function(){"use strict";var e="millisecond",t="second",r="minute",a="hour",l="week",n="month",s="quarter",i="year",o="date",d="Invalid Date",c=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,u=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,m=function(e,t,r){var a=String(e);return!a||a.length>=t?e:""+Array(t+1-a.length).join(r)+e},h="en",f={};f[h]={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(e){var t=["th","st","nd","rd"],r=e%100;return"["+e+(t[(r-20)%10]||t[r]||t[0])+"]"}};var p="$isDayjsObject",g=function(e){return e instanceof y||!(!e||!e[p])},b=function e(t,r,a){var l;if(!t)return h;if("string"==typeof t){var n=t.toLowerCase();f[n]&&(l=n),r&&(f[n]=r,l=n);var s=t.split("-");if(!l&&s.length>1)return e(s[0])}else{var i=t.name;f[i]=t,l=i}return!a&&l&&(h=l),l||!a&&h},v=function(e,t){if(g(e))return e.clone();var r="object"==typeof t?t:{};return r.date=e,r.args=arguments,new y(r)},x={s:m,z:function(e){var t=-e.utcOffset(),r=Math.abs(t);return(t<=0?"+":"-")+m(Math.floor(r/60),2,"0")+":"+m(r%60,2,"0")},m:function e(t,r){if(t.date(){"use strict";var t=e.i(309821);e.s(["Progress",()=>t.default])},95684,e=>{"use strict";var t=e.i(165370);e.s(["Pagination",()=>t.default])},897565,166452,e=>{"use strict";let t=(0,e.i(475254).default)("layers",[["path",{d:"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z",key:"zw3jo"}],["path",{d:"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12",key:"1wduqc"}],["path",{d:"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17",key:"kqbvx6"}]]);e.s(["LayersIcon",0,t],897565);var r=e.i(98740);e.s(["UsersIcon",()=>r.default],166452)},160818,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M854.4 800.9c.2-.3.5-.6.7-.9C920.6 722.1 960 621.7 960 512s-39.4-210.1-104.8-288c-.2-.3-.5-.5-.7-.8-1.1-1.3-2.1-2.5-3.2-3.7-.4-.5-.8-.9-1.2-1.4l-4.1-4.7-.1-.1c-1.5-1.7-3.1-3.4-4.6-5.1l-.1-.1c-3.2-3.4-6.4-6.8-9.7-10.1l-.1-.1-4.8-4.8-.3-.3c-1.5-1.5-3-2.9-4.5-4.3-.5-.5-1-1-1.6-1.5-1-1-2-1.9-3-2.8-.3-.3-.7-.6-1-1C736.4 109.2 629.5 64 512 64s-224.4 45.2-304.3 119.2c-.3.3-.7.6-1 1-1 .9-2 1.9-3 2.9-.5.5-1 1-1.6 1.5-1.5 1.4-3 2.9-4.5 4.3l-.3.3-4.8 4.8-.1.1c-3.3 3.3-6.5 6.7-9.7 10.1l-.1.1c-1.6 1.7-3.1 3.4-4.6 5.1l-.1.1c-1.4 1.5-2.8 3.1-4.1 4.7-.4.5-.8.9-1.2 1.4-1.1 1.2-2.1 2.5-3.2 3.7-.2.3-.5.5-.7.8C103.4 301.9 64 402.3 64 512s39.4 210.1 104.8 288c.2.3.5.6.7.9l3.1 3.7c.4.5.8.9 1.2 1.4l4.1 4.7c0 .1.1.1.1.2 1.5 1.7 3 3.4 4.6 5l.1.1c3.2 3.4 6.4 6.8 9.6 10.1l.1.1c1.6 1.6 3.1 3.2 4.7 4.7l.3.3c3.3 3.3 6.7 6.5 10.1 9.6 80.1 74 187 119.2 304.5 119.2s224.4-45.2 304.3-119.2a300 300 0 0010-9.6l.3-.3c1.6-1.6 3.2-3.1 4.7-4.7l.1-.1c3.3-3.3 6.5-6.7 9.6-10.1l.1-.1c1.5-1.7 3.1-3.3 4.6-5 0-.1.1-.1.1-.2 1.4-1.5 2.8-3.1 4.1-4.7.4-.5.8-.9 1.2-1.4a99 99 0 003.3-3.7zm4.1-142.6c-13.8 32.6-32 62.8-54.2 90.2a444.07 444.07 0 00-81.5-55.9c11.6-46.9 18.8-98.4 20.7-152.6H887c-3 40.9-12.6 80.6-28.5 118.3zM887 484H743.5c-1.9-54.2-9.1-105.7-20.7-152.6 29.3-15.6 56.6-34.4 81.5-55.9A373.86 373.86 0 01887 484zM658.3 165.5c39.7 16.8 75.8 40 107.6 69.2a394.72 394.72 0 01-59.4 41.8c-15.7-45-35.8-84.1-59.2-115.4 3.7 1.4 7.4 2.9 11 4.4zm-90.6 700.6c-9.2 7.2-18.4 12.7-27.7 16.4V697a389.1 389.1 0 01115.7 26.2c-8.3 24.6-17.9 47.3-29 67.8-17.4 32.4-37.8 58.3-59 75.1zm59-633.1c11 20.6 20.7 43.3 29 67.8A389.1 389.1 0 01540 327V141.6c9.2 3.7 18.5 9.1 27.7 16.4 21.2 16.7 41.6 42.6 59 75zM540 640.9V540h147.5c-1.6 44.2-7.1 87.1-16.3 127.8l-.3 1.2A445.02 445.02 0 00540 640.9zm0-156.9V383.1c45.8-2.8 89.8-12.5 130.9-28.1l.3 1.2c9.2 40.7 14.7 83.5 16.3 127.8H540zm-56 56v100.9c-45.8 2.8-89.8 12.5-130.9 28.1l-.3-1.2c-9.2-40.7-14.7-83.5-16.3-127.8H484zm-147.5-56c1.6-44.2 7.1-87.1 16.3-127.8l.3-1.2c41.1 15.6 85 25.3 130.9 28.1V484H336.5zM484 697v185.4c-9.2-3.7-18.5-9.1-27.7-16.4-21.2-16.7-41.7-42.7-59.1-75.1-11-20.6-20.7-43.3-29-67.8 37.2-14.6 75.9-23.3 115.8-26.1zm0-370a389.1 389.1 0 01-115.7-26.2c8.3-24.6 17.9-47.3 29-67.8 17.4-32.4 37.8-58.4 59.1-75.1 9.2-7.2 18.4-12.7 27.7-16.4V327zM365.7 165.5c3.7-1.5 7.3-3 11-4.4-23.4 31.3-43.5 70.4-59.2 115.4-21-12-40.9-26-59.4-41.8 31.8-29.2 67.9-52.4 107.6-69.2zM165.5 365.7c13.8-32.6 32-62.8 54.2-90.2 24.9 21.5 52.2 40.3 81.5 55.9-11.6 46.9-18.8 98.4-20.7 152.6H137c3-40.9 12.6-80.6 28.5-118.3zM137 540h143.5c1.9 54.2 9.1 105.7 20.7 152.6a444.07 444.07 0 00-81.5 55.9A373.86 373.86 0 01137 540zm228.7 318.5c-39.7-16.8-75.8-40-107.6-69.2 18.5-15.8 38.4-29.7 59.4-41.8 15.7 45 35.8 84.1 59.2 115.4-3.7-1.4-7.4-2.9-11-4.4zm292.6 0c-3.7 1.5-7.3 3-11 4.4 23.4-31.3 43.5-70.4 59.2-115.4 21 12 40.9 26 59.4 41.8a373.81 373.81 0 01-107.6 69.2z"}}]},name:"global",theme:"outlined"};var l=e.i(9583),n=r.forwardRef(function(e,n){return r.createElement(l.default,(0,t.default)({},e,{ref:n,icon:a}))});e.s(["GlobalOutlined",0,n],160818)},625901,e=>{"use strict";var t=e.i(266027),r=e.i(621482),a=e.i(243652),l=e.i(602869),n=e.i(135214);let s=(0,a.createQueryKeys)("models"),i=(0,a.createQueryKeys)("modelHub"),o=(0,a.createQueryKeys)("allProxyModels");(0,a.createQueryKeys)("selectedTeamModels");let d=(0,a.createQueryKeys)("infiniteModels"),c=(0,a.createQueryKeys)("userModels");e.s(["useAllProxyModels",0,()=>{let{accessToken:e,userId:r,userRole:a}=(0,n.default)();return(0,t.useQuery)({queryKey:o.list({}),queryFn:async()=>await (0,l.modelAvailableCall)(e,r,a,!0,null,!0,!1,"expand"),enabled:!!(e&&r&&a)})},"useInfiniteModelInfo",0,(e=50,t)=>{let{accessToken:a,userId:s,userRole:i}=(0,n.default)();return(0,r.useInfiniteQuery)({queryKey:d.list({filters:{...s&&{userId:s},...i&&{userRole:i},size:e,...t&&{search:t}}}),queryFn:async({pageParam:r})=>await (0,l.modelInfoCall)(a,s,i,r,e,t),initialPageParam:1,getNextPageParam:e=>{if(e.current_page{let{accessToken:e}=(0,n.default)();return(0,t.useQuery)({queryKey:i.list({}),queryFn:async()=>await (0,l.modelHubCall)(e),enabled:!!e})},"useModelsInfo",0,(e=1,r=50,a,i,o,d,c)=>{let{accessToken:u,userId:m,userRole:h}=(0,n.default)();return(0,t.useQuery)({queryKey:s.list({filters:{...m&&{userId:m},...h&&{userRole:h},page:e,size:r,...a&&{search:a},...i&&{modelId:i},...o&&{teamId:o},...d&&{sortBy:d},...c&&{sortOrder:c}}}),queryFn:async()=>await (0,l.modelInfoCall)(u,m,h,e,r,a,i,o,d,c),enabled:!!(u&&m&&h)})},"useUserModels",0,()=>{let{accessToken:e,userId:r,userRole:a}=(0,n.default)();return(0,t.useQuery)({queryKey:c.list({}),queryFn:async()=>(await (0,l.modelAvailableCall)(e,r,a)).data.map(e=>e.id),enabled:!!(e&&r&&a)})}])},738014,e=>{"use strict";var t=e.i(135214),r=e.i(602869),a=e.i(266027);let l=(0,e.i(243652).createQueryKeys)("users");e.s(["useCurrentUser",0,()=>{let{accessToken:e,userId:n}=(0,t.default)();return(0,a.useQuery)({queryKey:l.detail(n),queryFn:async()=>await (0,r.userGetInfoV2)(e),enabled:!!(e&&n)})}])},162386,e=>{"use strict";var t=e.i(843476),r=e.i(625901),a=e.i(109799),l=e.i(785242),n=e.i(738014),s=e.i(199133),i=e.i(981339),o=e.i(592968);let d={label:"All Proxy Models",value:"all-proxy-models"},c={label:"No Default Models",value:"no-default-models"},u=[d,c],m={user:({allProxyModels:e,userModels:t,options:r})=>t&&r?.includeUserModels?t:[],team:({allProxyModels:e,selectedOrganization:t,userModels:r})=>t?t.models.includes(d.value)||0===t.models.length?e:e.filter(e=>t.models.includes(e)):e??[],organization:({allProxyModels:e})=>e,global:({allProxyModels:e})=>e};e.s(["ModelSelect",0,e=>{let{teamID:h,organizationID:f,options:p,context:g,dataTestId:b,value:v=[],onChange:x,style:y}=e,{includeUserModels:w,showAllTeamModelsOption:C,showAllProxyModelsOverride:k,includeSpecialOptions:j}=p||{},{data:M,isLoading:S}=(0,r.useAllProxyModels)(),{data:$,isLoading:_}=(0,l.useTeam)(h),{data:O,isLoading:I}=(0,a.useOrganization)(f),{data:N,isLoading:A}=(0,n.useCurrentUser)(),z=e=>u.some(t=>t.value===e),T=v.some(z),D=O?.models.includes(d.value)||O?.models.length===0;if(S||_||I||A)return(0,t.jsx)(i.Skeleton.Input,{active:!0,block:!0});let{wildcard:L,regular:E}=(e=>{let t=[],r=[];for(let a of e)a.endsWith("/*")?t.push(a):r.push(a);return{wildcard:t,regular:r}})(((e,t,r)=>{let a=Array.from(new Map(e.map(e=>[e.id,e])).values()).map(e=>e.id);if(t.options?.showAllProxyModelsOverride)return a;let l=m[t.context];return l?l({allProxyModels:a,...r,options:t.options}):[]})(M?.data??[],e,{selectedTeam:$,selectedOrganization:O,userModels:N?.models}));return(0,t.jsx)(s.Select,{"data-testid":b,value:v,onChange:e=>{let t=e.filter(z);x(t.length>0?[t[t.length-1]]:e)},style:y,options:[...j?[{label:(0,t.jsx)("span",{children:"Special Options"}),title:"Special Options",options:[...k||D&&j||"global"===g?[{label:(0,t.jsx)("span",{children:"All Proxy Models"}),value:d.value,disabled:v.length>0&&v.some(e=>z(e)&&e!==d.value),key:d.value}]:[],{label:(0,t.jsx)("span",{children:"No Default Models"}),value:c.value,disabled:v.length>0&&v.some(e=>z(e)&&e!==c.value),key:c.value}]}]:[],...L.length>0?[{label:(0,t.jsx)("span",{children:"Wildcard Options"}),title:"Wildcard Options",options:L.map(e=>{let r=e.replace("/*",""),a=r.charAt(0).toUpperCase()+r.slice(1);return{label:(0,t.jsx)("span",{children:`All ${a} models`}),value:e,disabled:T}})}]:[],{label:(0,t.jsx)("span",{children:"Models"}),title:"Models",options:E.map(e=>({label:(0,t.jsx)("span",{children:e}),value:e,disabled:T}))}],mode:"multiple",placeholder:"Select Models",allowClear:!0,maxTagCount:"responsive",maxTagPlaceholder:e=>(0,t.jsx)(o.Tooltip,{styles:{root:{pointerEvents:"none"}},title:e.map(({value:e})=>e).join(", "),children:(0,t.jsxs)("span",{children:["+",e.length," more"]})})})}],162386)},907308,276173,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(212931),l=e.i(808613),n=e.i(464571),s=e.i(199133),i=e.i(592968),o=e.i(213205),d=e.i(374009),c=e.i(602869);e.s(["default",0,({isVisible:e,onCancel:u,onSubmit:m,accessToken:h,title:f="Add Team Member",roles:p=[{label:"admin",value:"admin",description:"Admin role. Can create team keys, add members, and manage settings."},{label:"user",value:"user",description:"User role. Can view team info, but not manage it."}],defaultRole:g="user",teamId:b})=>{let[v]=l.Form.useForm(),[x,y]=(0,r.useState)([]),[w,C]=(0,r.useState)(!1),[k,j]=(0,r.useState)("user_email"),[M,S]=(0,r.useState)(!1),$=async(e,t)=>{if(!e)return void y([]);C(!0);try{let r=new URLSearchParams;if(r.append(t,e),b&&r.append("team_id",b),null==h)return;let a=(await (0,c.userFilterUICall)(h,r)).map(e=>({label:"user_email"===t?`${e.user_email}`:`${e.user_id}`,value:"user_email"===t?e.user_email:e.user_id,user:e}));y(a)}catch(e){console.error("Error fetching users:",e)}finally{C(!1)}},_=(0,r.useCallback)((0,d.default)((e,t)=>$(e,t),300),[]),O=(e,t)=>{j(t),_(e,t)},I=(e,t)=>{let r=t.user;v.setFieldsValue({user_email:r.user_email,user_id:r.user_id,role:v.getFieldValue("role")})},N=async e=>{S(!0);try{await m(e)}finally{S(!1)}};return(0,t.jsx)(a.Modal,{title:f,open:e,onCancel:()=>{v.resetFields(),y([]),u()},footer:null,width:800,maskClosable:!M,children:(0,t.jsxs)(l.Form,{form:v,onFinish:N,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",initialValues:{role:g},children:[(0,t.jsx)(l.Form.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,t.jsx)(s.Select,{showSearch:!0,className:"w-full",placeholder:"Search by email",filterOption:!1,onSearch:e=>O(e,"user_email"),onSelect:(e,t)=>I(e,t),options:"user_email"===k?x:[],loading:w,allowClear:!0,"data-testid":"member-email-search"})}),(0,t.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,t.jsx)(l.Form.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,t.jsx)(s.Select,{showSearch:!0,className:"w-full",placeholder:"Search by user ID",filterOption:!1,onSearch:e=>O(e,"user_id"),onSelect:(e,t)=>I(e,t),options:"user_id"===k?x:[],loading:w,allowClear:!0})}),(0,t.jsx)(l.Form.Item,{label:"Member Role",name:"role",className:"mb-4",children:(0,t.jsx)(s.Select,{defaultValue:g,children:p.map(e=>(0,t.jsx)(s.Select.Option,{value:e.value,children:(0,t.jsxs)(i.Tooltip,{title:e.description,children:[(0,t.jsx)("span",{className:"font-medium",children:e.label}),(0,t.jsxs)("span",{className:"ml-2 text-gray-500 text-sm",children:["- ",e.description]})]})},e.value))})}),(0,t.jsx)("div",{className:"text-right mt-4",children:(0,t.jsx)(n.Button,{type:"primary",htmlType:"submit",icon:(0,t.jsx)(o.UserAddOutlined,{}),loading:M,children:M?"Adding...":"Add Member"})})]})})}],907308);var u=e.i(599724),m=e.i(779241),h=e.i(435451),f=e.i(860585);e.s(["default",0,({visible:e,onCancel:i,onSubmit:o,initialData:d,mode:c,config:p})=>{let g,[b]=l.Form.useForm(),[v,x]=(0,r.useState)(!1);(0,r.useEffect)(()=>{if(e)if("edit"===c&&d){let e={...d,role:d.role||p.defaultRole,max_budget_in_team:d.max_budget_in_team||null,tpm_limit:d.tpm_limit||null,rpm_limit:d.rpm_limit||null,budget_duration:d.budget_duration||null,allowed_models:d.allowed_models||[]};b.setFieldsValue(e)}else b.resetFields(),b.setFieldsValue({role:p.defaultRole||p.roleOptions[0]?.value})},[e,d,c,b,p.defaultRole,p.roleOptions]);let y=async e=>{try{x(!0);let t=Object.entries(e).reduce((e,[t,r])=>{if("string"==typeof r){let a=r.trim();return""===a&&("max_budget_in_team"===t||"tpm_limit"===t||"rpm_limit"===t)?{...e,[t]:null}:{...e,[t]:a}}return{...e,[t]:r}},{});await Promise.resolve(o(t)),b.resetFields()}catch(e){console.error("Form submission error:",e)}finally{x(!1)}};return(0,t.jsx)(a.Modal,{title:p.title||("add"===c?"Add Member":"Edit Member"),open:e,width:1e3,footer:null,onCancel:i,children:(0,t.jsxs)(l.Form,{form:b,onFinish:y,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[p.showEmail&&(0,t.jsx)(l.Form.Item,{label:"Email",name:"user_email",className:"mb-4",rules:[{type:"email",message:"Please enter a valid email!"}],children:(0,t.jsx)(m.TextInput,{placeholder:"user@example.com"})}),p.showEmail&&p.showUserId&&(0,t.jsx)("div",{className:"text-center mb-4",children:(0,t.jsx)(u.Text,{children:"OR"})}),p.showUserId&&(0,t.jsx)(l.Form.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,t.jsx)(m.TextInput,{placeholder:"user_123"})}),(0,t.jsx)(l.Form.Item,{label:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("span",{children:"Role"}),"edit"===c&&d&&(0,t.jsxs)("span",{className:"text-gray-500 text-sm",children:["(Current: ",(g=d.role,p.roleOptions.find(e=>e.value===g)?.label||g),")"]})]}),name:"role",className:"mb-4",rules:[{required:!0,message:"Please select a role!"}],children:(0,t.jsx)(s.Select,{children:"edit"===c&&d?[...p.roleOptions.filter(e=>e.value===d.role),...p.roleOptions.filter(e=>e.value!==d.role)].map(e=>(0,t.jsx)(s.Select.Option,{value:e.value,children:e.label},e.value)):p.roleOptions.map(e=>(0,t.jsx)(s.Select.Option,{value:e.value,children:e.label},e.value))})}),p.additionalFields?.map(e=>(0,t.jsx)(l.Form.Item,{label:e.label,name:e.name,className:"mb-4",rules:e.rules,children:(e=>{switch(e.type){case"input":return(0,t.jsx)(m.TextInput,{placeholder:e.placeholder});case"numerical":return(0,t.jsx)(h.default,{step:e.step||1,min:e.min||0,style:{width:"100%"},placeholder:e.placeholder||"Enter a numerical value"});case"select":return(0,t.jsx)(s.Select,{children:e.options?.map(e=>(0,t.jsx)(s.Select.Option,{value:e.value,children:e.label},e.value))});case"multi-select":return(0,t.jsx)(s.Select,{mode:"multiple",placeholder:e.placeholder||"Select options",options:e.options,allowClear:!0});case"budget-duration":return(0,t.jsx)(f.default,{});default:return null}})(e)},e.name)),(0,t.jsxs)("div",{className:"text-right mt-6",children:[(0,t.jsx)(n.Button,{onClick:i,className:"mr-2",disabled:v,children:"Cancel"}),(0,t.jsx)(n.Button,{type:"default",htmlType:"submit",loading:v,children:"add"===c?v?"Adding...":"Add Member":v?"Saving...":"Save Changes"})]})]})})}],276173)},294612,e=>{"use strict";var t=e.i(843476),r=e.i(100486),a=e.i(827252),l=e.i(213205),n=e.i(771674),s=e.i(464571),i=e.i(770914),o=e.i(291542),d=e.i(262218),c=e.i(592968),u=e.i(898586),m=e.i(902555);let{Text:h}=u.Typography;e.s(["default",0,function({members:e,canEdit:u,onEdit:f,onDelete:p,onAddMember:g,roleColumnTitle:b="Role",roleTooltip:v,extraColumns:x=[],showDeleteForMember:y,emptyText:w}){let C=[{title:"User Email",dataIndex:"user_email",key:"user_email",render:e=>(0,t.jsx)(h,{children:e||"-"})},{title:"User ID",dataIndex:"user_id",key:"user_id",render:e=>"default_user_id"===e?(0,t.jsx)(d.Tag,{color:"blue",children:"Default Proxy Admin"}):(0,t.jsx)(h,{children:e||"-"})},{title:v?(0,t.jsxs)(i.Space,{direction:"horizontal",children:[b,(0,t.jsx)(c.Tooltip,{title:v,children:(0,t.jsx)(a.InfoCircleOutlined,{})})]}):b,dataIndex:"role",key:"role",render:e=>(0,t.jsxs)(i.Space,{children:[e?.toLowerCase()==="admin"||e?.toLowerCase()==="org_admin"?(0,t.jsx)(r.CrownOutlined,{}):(0,t.jsx)(n.UserOutlined,{}),(0,t.jsx)(h,{style:{textTransform:"capitalize"},children:e||"-"})]})},...x,{title:"Actions",key:"actions",fixed:"right",width:120,render:(e,r)=>u?(0,t.jsxs)(i.Space,{children:[(0,t.jsx)(m.default,{variant:"Edit",tooltipText:"Edit member",dataTestId:"edit-member",onClick:()=>f(r)}),(!y||y(r))&&(0,t.jsx)(m.default,{variant:"Delete",tooltipText:"Delete member",dataTestId:"delete-member",onClick:()=>p(r)})]}):null}];return(0,t.jsxs)(i.Space,{direction:"vertical",style:{width:"100%"},children:[(0,t.jsxs)("span",{className:"inline-flex text-sm text-gray-700",children:[e.length," Member",1!==e.length?"s":""]}),(0,t.jsx)(o.Table,{columns:C,dataSource:e,rowKey:e=>e.user_id??e.user_email??JSON.stringify(e),pagination:!1,size:"small",scroll:{x:"max-content"},locale:w?{emptyText:w}:void 0}),g&&u&&(0,t.jsx)(s.Button,{icon:(0,t.jsx)(l.UserAddOutlined,{}),type:"primary",onClick:g,children:"Add Member"})]})}])},94629,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"}))});e.s(["SwitchVerticalIcon",0,r],94629)},166406,e=>{"use strict";var t=e.i(190144);e.s(["CopyOutlined",()=>t.default])},447566,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let a={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 000 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"}}]},name:"arrow-left",theme:"outlined"};var l=e.i(9583),n=r.forwardRef(function(e,n){return r.createElement(l.default,(0,t.default)({},e,{ref:n,icon:a}))});e.s(["ArrowLeftOutlined",0,n],447566)},969550,e=>{"use strict";var t=e.i(843476),r=e.i(271645);let a=r.forwardRef(function(e,t){return r.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),r.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"}))});var l=e.i(464571),n=e.i(311451),s=e.i(199133),i=e.i(374009);e.s(["default",0,({options:e,onApplyFilters:o,onResetFilters:d,initialValues:c={},buttonLabel:u="Filters"})=>{let[m,h]=(0,r.useState)(!1),[f,p]=(0,r.useState)(c),[g,b]=(0,r.useState)({}),[v,x]=(0,r.useState)({}),[y,w]=(0,r.useState)({}),[C,k]=(0,r.useState)({}),j=(0,r.useCallback)((0,i.default)(async(e,t)=>{if(t.isSearchable&&t.searchFn){x(e=>({...e,[t.name]:!0}));try{let r=await t.searchFn(e);b(e=>({...e,[t.name]:r}))}catch(e){console.error("Error searching:",e),b(e=>({...e,[t.name]:[]}))}finally{x(e=>({...e,[t.name]:!1}))}}},300),[]),M=(0,r.useCallback)(async e=>{if(e.isSearchable&&e.searchFn&&!e.loading&&!C[e.name]){x(t=>({...t,[e.name]:!0})),k(t=>({...t,[e.name]:!0}));try{let t=await e.searchFn("");b(r=>({...r,[e.name]:t}))}catch(t){console.error("Error loading initial options:",t),b(t=>({...t,[e.name]:[]}))}finally{x(t=>({...t,[e.name]:!1}))}}},[C]);(0,r.useEffect)(()=>{m&&e.forEach(e=>{e.isSearchable&&!C[e.name]&&M(e)})},[m,e,M,C]);let S=(e,t)=>{let r={...f,[e]:t};p(r),o(r)};return(0,t.jsxs)("div",{className:"w-full",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 mb-6",children:[(0,t.jsx)(l.Button,{icon:(0,t.jsx)(a,{className:"h-4 w-4"}),onClick:()=>h(!m),className:"flex items-center gap-2",children:u}),(0,t.jsx)(l.Button,{onClick:()=>{let t={};e.forEach(e=>{t[e.name]=""}),p(t),d()},children:"Reset Filters"})]}),m&&(0,t.jsx)("div",{className:"grid grid-cols-3 gap-x-6 gap-y-4 mb-6",children:e.map(e=>{let r,a=v[e.name]||e.loading;return(0,t.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,t.jsx)("label",{className:"text-sm text-gray-600",children:e.label||e.name}),e.isSearchable?(0,t.jsx)(s.Select,{showSearch:!0,className:"w-full",placeholder:`Search ${e.label||e.name}...`,value:f[e.name]||void 0,onChange:t=>S(e.name,t),onOpenChange:t=>{t&&e.isSearchable&&!C[e.name]&&M(e)},onSearch:t=>{w(r=>({...r,[e.name]:t})),e.searchFn&&j(t,e)},filterOption:!1,loading:a,options:g[e.name]||[],allowClear:!0,notFoundContent:a?"Loading...":"No results found"}):e.options?(0,t.jsx)(s.Select,{className:"w-full",placeholder:`Select ${e.label||e.name}...`,value:f[e.name]||void 0,onChange:t=>S(e.name,t),allowClear:!0,children:e.options.map(e=>(0,t.jsx)(s.Select.Option,{value:e.value,children:e.label},e.value))}):e.customComponent?(r=e.customComponent,(0,t.jsx)(r,{value:f[e.name]||void 0,onChange:t=>S(e.name,t??""),placeholder:`Select ${e.label||e.name}...`,allFilters:f})):(0,t.jsx)(n.Input,{className:"w-full",placeholder:`Enter ${e.label||e.name}...`,value:f[e.name]||"",onChange:t=>S(e.name,t.target.value),allowClear:!0})]},e.name)})})]})}],969550)},633627,e=>{"use strict";var t=e.i(602869);let r=(e,t,r,a)=>{for(let l of e){let e=l?.key_alias;e&&"string"==typeof e&&t.add(e.trim());let n=l?.organization_id??l?.org_id;n&&"string"==typeof n&&r.add(n.trim());let s=l?.user_id;if(s&&"string"==typeof s){let e=l?.user?.user_email||s;a.set(s,e)}}},a=async(e,a)=>{if(!e||!a)return{keyAliases:[],organizationIds:[],userIds:[]};try{let l=new Set,n=new Set,s=new Map,i=await (0,t.keyListCall)(e,null,a,null,null,null,1,100,null,null,"user",null),o=i?.keys||[],d=i?.total_pages??1;r(o,l,n,s);let c=Math.min(d,10)-1;if(c>0){let i=Array.from({length:c},(r,l)=>(0,t.keyListCall)(e,null,a,null,null,null,l+2,100,null,null,"user",null));for(let e of(await Promise.allSettled(i)))"fulfilled"===e.status&&r(e.value?.keys||[],l,n,s)}return{keyAliases:Array.from(l).sort(),organizationIds:Array.from(n).sort(),userIds:Array.from(s.entries()).map(([e,t])=>({id:e,email:t}))}}catch(e){return console.error("Error fetching team filter options:",e),{keyAliases:[],organizationIds:[],userIds:[]}}},l=async(e,r)=>{if(!e)return[];try{let a=[],l=1,n=!0;for(;n;){let s=await (0,t.teamListCall)(e,r||null,null);a=[...a,...s],l{"use strict";var t=e.i(843476),r=e.i(482725),a=e.i(56456);e.s(["AntDLoadingSpinner",0,function({size:e,fontSize:l}){let n=(0,t.jsx)(a.LoadingOutlined,{style:l?{fontSize:l}:void 0,spin:!0});return(0,t.jsx)(r.Spin,{indicator:n,size:e})}])}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0pidya1qvuvx8.js b/litellm/proxy/_experimental/out/_next/static/chunks/0pidya1qvuvx8.js new file mode 100644 index 00000000000..b547129cba4 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/0pidya1qvuvx8.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,491915,(e,t,r)=>{"use strict";function n(e,t={}){if(t.onlyHashChange)return void e();let r=document.documentElement;if("smooth"!==r.dataset.scrollBehavior)return void e();let a=r.style.scrollBehavior;r.style.scrollBehavior="auto",t.dontForceLayout||r.getClientRects(),e(),r.style.scrollBehavior=a}Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"disableSmoothScrollDuringRouteTransition",{enumerable:!0,get:function(){return n}}),e.r(233525)},768017,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"HTTPAccessFallbackBoundary",{enumerable:!0,get:function(){return u}});let n=e.r(151836),a=e.r(843476),o=n._(e.r(271645)),i=e.r(590373),s=e.r(754394);e.r(233525);let l=e.r(8372);class c extends o.default.Component{constructor(e){super(e),this.state={triggeredStatus:void 0,previousPathname:e.pathname}}componentDidCatch(){}static getDerivedStateFromError(e){if((0,s.isHTTPAccessFallbackError)(e))return{triggeredStatus:(0,s.getAccessFallbackHTTPStatus)(e)};throw e}static getDerivedStateFromProps(e,t){return e.pathname!==t.previousPathname&&t.triggeredStatus?{triggeredStatus:void 0,previousPathname:e.pathname}:{triggeredStatus:t.triggeredStatus,previousPathname:e.pathname}}render(){let{notFound:e,forbidden:t,unauthorized:r,children:n}=this.props,{triggeredStatus:o}=this.state,i={[s.HTTPAccessErrorStatus.NOT_FOUND]:e,[s.HTTPAccessErrorStatus.FORBIDDEN]:t,[s.HTTPAccessErrorStatus.UNAUTHORIZED]:r};if(o){let l=o===s.HTTPAccessErrorStatus.NOT_FOUND&&e,c=o===s.HTTPAccessErrorStatus.FORBIDDEN&&t,u=o===s.HTTPAccessErrorStatus.UNAUTHORIZED&&r;return l||c||u?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("meta",{name:"robots",content:"noindex"}),!1,i[o]]}):n}return n}}function u({notFound:e,forbidden:t,unauthorized:r,children:n}){let s=(0,i.useUntrackedPathname)(),d=(0,o.useContext)(l.MissingSlotContext);return e||t||r?(0,a.jsx)(c,{pathname:s,notFound:e,forbidden:t,unauthorized:r,missingSlots:d,children:n}):(0,a.jsx)(a.Fragment,{children:n})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},728298,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"useRouterBFCache",{enumerable:!0,get:function(){return a}});let n=e.r(271645);function a(e,t,r){let[a,o]=(0,n.useState)(()=>({tree:e,cacheNode:t,stateKey:r,next:null}));if(a.tree===e)return a;let i={tree:e,cacheNode:t,stateKey:r,next:null},s=1,l=a,c=i;for(;null!==l&&s<1;){if(l.stateKey===r){c.next=l.next;break}{s++;let e={tree:l.tree,cacheNode:l.cacheNode,stateKey:l.stateKey,next:null};c.next=e,c=e}l=l.next}return o(i),i}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},339756,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={LoadingBoundaryProvider:function(){return j},default:function(){return A}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=e.r(563141),i=e.r(151836),s=e.r(843476),l=i._(e.r(271645)),c=o._(e.r(174080)),u=e.r(8372),d=e.r(201244),f=e.r(972383),p=e.r(491915),m=e.r(358442),h=e.r(768017),g=e.r(270725),y=e.r(728298);e.r(174180);let b=e.r(261994),P=e.r(33906),_=e.r(595871),v=c.default.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,E=["bottom","height","left","right","top","width","x","y"];function R(e,t){let r=e.getClientRects();if(0===r.length)return!1;let n=1/0;for(let e=0;e=0&&n<=t}class O extends l.default.Component{componentDidMount(){this.handlePotentialScroll()}componentDidUpdate(){this.handlePotentialScroll()}render(){return this.props.children}constructor(...e){super(...e),this.handlePotentialScroll=()=>{let{focusAndScrollRef:e,cacheNode:t}=this.props,r=e.forceScroll?e.scrollRef:t.scrollRef;if(null===r||!r.current)return;let n=null,a=e.hashFragment;if(a&&(n="top"===a?document.body:document.getElementById(a)??document.getElementsByName(a)[0]),n||(n="u"0===t[e])}(n);){if(null===n.nextElementSibling)return;n=n.nextElementSibling}r.current=!1,(0,p.disableSmoothScrollDuringRouteTransition)(()=>{if(a)return void n.scrollIntoView();let e=document.documentElement,t=e.clientHeight;!R(n,t)&&(e.scrollTop=0,R(n,t)||n.scrollIntoView())},{dontForceLayout:!0,onlyHashChange:e.onlyHashChange}),e.onlyHashChange=!1,e.hashFragment=null,n.focus()}}}}function w({children:e,cacheNode:t}){let r=(0,l.useContext)(u.GlobalLayoutRouterContext);if(!r)throw Object.defineProperty(Error("invariant global layout router not mounted"),"__NEXT_ERROR_CODE",{value:"E473",enumerable:!1,configurable:!0});return(0,s.jsx)(O,{focusAndScrollRef:r.focusAndScrollRef,cacheNode:t,children:e})}function S({tree:e,segmentPath:t,debugNameContext:r,cacheNode:n,params:a,url:o,isActive:i}){let c,f=(0,l.useContext)(u.GlobalLayoutRouterContext);if((0,l.useContext)(b.NavigationPromisesContext),!f)throw Object.defineProperty(Error("invariant global layout router not mounted"),"__NEXT_ERROR_CODE",{value:"E473",enumerable:!1,configurable:!0});let p=null!==n?n:(0,l.use)(d.unresolvedThenable),m=null!==p.prefetchRsc?p.prefetchRsc:p.rsc,h=(0,l.useDeferredValue)(p.rsc,m);if((0,_.isDeferredRsc)(h)){let e=(0,l.use)(h);null===e&&(0,l.use)(d.unresolvedThenable),c=e}else null===h&&(0,l.use)(d.unresolvedThenable),c=h;let g=c;return(0,s.jsx)(u.LayoutRouterContext.Provider,{value:{parentTree:e,parentCacheNode:p,parentSegmentPath:t,parentParams:a,parentLoadingData:null,debugNameContext:r,url:o,isActive:i},children:g})}function j({loading:e,children:t}){let r=(0,l.use)(u.LayoutRouterContext);return null===r?t:(0,s.jsx)(u.LayoutRouterContext.Provider,{value:{parentTree:r.parentTree,parentCacheNode:r.parentCacheNode,parentSegmentPath:r.parentSegmentPath,parentParams:r.parentParams,parentLoadingData:e,debugNameContext:r.debugNameContext,url:r.url,isActive:r.isActive},children:t})}function C({name:e,loading:t,children:r}){if(null!==t){let n=t[0],a=t[1],o=t[2];return(0,s.jsx)(l.Suspense,{name:e,fallback:(0,s.jsxs)(s.Fragment,{children:[a,o,n]}),children:r})}return(0,s.jsx)(s.Fragment,{children:r})}function A({parallelRouterKey:e,error:t,errorStyles:r,errorScripts:n,templateStyles:a,templateScripts:o,template:i,notFound:c,forbidden:p,unauthorized:b,segmentViewBoundaries:_}){let v=(0,l.useContext)(u.LayoutRouterContext);if(!v)throw Object.defineProperty(Error("invariant expected layout router to be mounted"),"__NEXT_ERROR_CODE",{value:"E56",enumerable:!1,configurable:!0});let{parentTree:E,parentCacheNode:R,parentSegmentPath:O,parentParams:j,parentLoadingData:x,url:k,isActive:T,debugNameContext:N}=v,D=E[0],M=null===O?[e]:O.concat([D,e]),I=E[1][e],F=R.slots;(void 0===I||null===F)&&(0,l.use)(d.unresolvedThenable);let $=I[0],L=F[e]??null,U=(0,g.createRouterCacheKey)($,!0),X=(0,y.useRouterBFCache)(I,L,U),H=[];do{let e=X.tree,l=X.cacheNode,d=X.stateKey,g=e[0],y=j;if(Array.isArray(g)){let e=g[0],t=g[1],r=g[2],n=(0,P.getParamValueFromCacheKey)(t,r);null!==n&&(y={...j,[e]:n})}let _=function(e){if("/"===e)return"/";if("string"==typeof e)if("(__SLOT__)"===e)return;else return e+"/";return e[1]+"/"}(g),v=_??N,E=void 0===_?void 0:N,R=(0,s.jsxs)(w,{cacheNode:l,children:[(0,s.jsx)(f.ErrorBoundary,{errorComponent:t,errorStyles:r,errorScripts:n,children:(0,s.jsx)(C,{name:E,loading:x,children:(0,s.jsx)(h.HTTPAccessFallbackBoundary,{notFound:c,forbidden:p,unauthorized:b,children:(0,s.jsxs)(m.RedirectBoundary,{children:[(0,s.jsx)(S,{url:k,tree:e,params:y,cacheNode:l,segmentPath:M,debugNameContext:v,isActive:T&&d===U}),null]})})})}),null]}),O=(0,s.jsxs)(u.TemplateContext.Provider,{value:R,children:[a,o,i]},d);H.push(O),X=X.next}while(null!==X)return H}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},837457,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"default",{enumerable:!0,get:function(){return s}});let n=e.r(151836),a=e.r(843476),o=n._(e.r(271645)),i=e.r(8372);function s(){let e=(0,o.useContext)(i.TemplateContext);return(0,a.jsx)(a.Fragment,{children:e})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},793504,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderSearchParamsFromClient",{enumerable:!0,get:function(){return a}});let n=new WeakMap;function a(e){let t=n.get(e);if(t)return t;let r=Promise.resolve(e);return n.set(e,r),r}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},266996,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderSearchParamsFromClient",{enumerable:!0,get:function(){return n}});let n=e.r(793504).createRenderSearchParamsFromClient;("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},806831,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderParamsFromClient",{enumerable:!0,get:function(){return a}});let n=new WeakMap;function a(e){let t=n.get(e);if(t)return t;let r=Promise.resolve(e);return n.set(e,r),r}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},797689,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderParamsFromClient",{enumerable:!0,get:function(){return n}});let n=e.r(806831).createRenderParamsFromClient;("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},66373,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={accumulateRootVaryParam:function(){return y},accumulateVaryParam:function(){return g},createResponseVaryParamsAccumulator:function(){return c},createVaryParamsAccumulator:function(){return u},createVaryingParams:function(){return b},createVaryingSearchParams:function(){return P},emptyVaryParamsAccumulator:function(){return l},finishAccumulatingVaryParams:function(){return _},getMetadataVaryParamsAccumulator:function(){return d},getMetadataVaryParamsThenable:function(){return p},getRootParamsVaryParamsAccumulator:function(){return h},getVaryParamsThenable:function(){return f},getViewportVaryParamsAccumulator:function(){return m}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=e.r(662141);function i(){let e={varyParams:new Set,status:"pending",value:new Set,then(t){t&&("pending"===e.status?e.resolvers.push(t):t(e.value))},resolvers:[]};return e}let s=new Set,l={varyParams:s,status:"fulfilled",value:s,then(e){e&&e(s)},resolvers:[]};function c(){let e=i();return{head:e,rootParams:i(),segments:new Set}}function u(){let e=o.workUnitAsyncStorage.getStore();if(e)switch(e.type){case"prerender":case"prerender-runtime":{let t=e.varyParamsAccumulator;if(null!==t){let e=i();return t.segments.add(e),e}}}return null}function d(){let e=o.workUnitAsyncStorage.getStore();if(e)switch(e.type){case"prerender":case"prerender-runtime":{let t=e.varyParamsAccumulator;if(null!==t)return t.head}}return null}function f(e){return e}function p(){let e=d();return null!==e?e:null}let m=d;function h(){let e=o.workUnitAsyncStorage.getStore();if(e)switch(e.type){case"prerender":case"prerender-runtime":{let t=e.varyParamsAccumulator;if(null!==t)return t.rootParams}}return null}function g(e,t){e.varyParams.add(t)}function y(e){let t=h();null!==t&&g(t,e)}function b(e,t,r){if(null!==r)return new Proxy(t,{get:(t,n,a)=>("string"==typeof n&&(n===r||Object.prototype.hasOwnProperty.call(t,n))&&g(e,n),Reflect.get(t,n,a)),has:(t,n)=>(n===r&&g(e,r),Reflect.has(t,n)),ownKeys:t=>(g(e,r),Reflect.ownKeys(t))});let n={};for(let r in t)Object.defineProperty(n,r,{get:()=>(g(e,r),t[r]),enumerable:!0});return n}function P(e,t){let r={};for(let n in t)Object.defineProperty(r,n,{get:()=>(g(e,"?"),t[n]),enumerable:!0});return r}async function _(e){let t=e.rootParams.varyParams;for(let r of(v(e.head,t),e.segments))v(r,t);await Promise.resolve(),await Promise.resolve(),await Promise.resolve()}function v(e,t){if("pending"!==e.status)return;let r=new Set(e.varyParams);for(let e of t)r.add(e);for(let t of(e.value=r,e.status="fulfilled",e.resolvers))t(r);e.resolvers=[]}},242715,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"ReflectAdapter",{enumerable:!0,get:function(){return n}});class n{static get(e,t,r){let n=Reflect.get(e,t,r);return"function"==typeof n?n.bind(e):n}static set(e,t,r,n){return Reflect.set(e,t,r,n)}static has(e,t){return Reflect.has(e,t)}static deleteProperty(e,t){return Reflect.deleteProperty(e,t)}}},364146,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createDedupedByCallsiteServerErrorLoggerDev",{enumerable:!0,get:function(){return l}});let n=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var t=a(void 0);if(t&&t.has(e))return t.get(e);var r={__proto__:null},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if("default"!==o&&Object.prototype.hasOwnProperty.call(e,o)){var i=n?Object.getOwnPropertyDescriptor(e,o):null;i&&(i.get||i.set)?Object.defineProperty(r,o,i):r[o]=e[o]}return r.default=e,t&&t.set(e,r),r}(e.r(271645));function a(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(a=function(e){return e?r:t})(e)}let o={current:null},i="function"==typeof n.cache?n.cache:e=>e,s=console.warn;function l(e){return function(...t){s(e(...t))}}i(e=>{try{s(o.current)}finally{o.current=null}})},565932,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={describeHasCheckingStringProperty:function(){return s},describeStringPropertyAccess:function(){return i},wellKnownProperties:function(){return l}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=/^[A-Za-z_$][A-Za-z0-9_$]*$/;function i(e,t){return o.test(t)?`\`${e}.${t}\``:`\`${e}[${JSON.stringify(t)}]\``}function s(e,t){let r=JSON.stringify(t);return`\`Reflect.has(${e}, ${r})\`, \`${r} in ${e}\`, or similar`}let l=new Set(["hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toString","valueOf","toLocaleString","then","catch","finally","status","displayName","_debugInfo","toJSON","$$typeof","__esModule","@@iterator"])},783066,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"afterTaskAsyncStorageInstance",{enumerable:!0,get:function(){return n}});let n=(0,e.r(90317).createAsyncLocalStorage)()},341643,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"afterTaskAsyncStorage",{enumerable:!0,get:function(){return n.afterTaskAsyncStorageInstance}});let n=e.r(783066)},850999,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={isRequestAPICallableInsideAfter:function(){return c},throwForSearchParamsAccessInUseCache:function(){return l},throwWithStaticGenerationBailoutErrorWithDynamicError:function(){return s}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=e.r(643248),i=e.r(341643);function s(e,t){throw Object.defineProperty(new o.StaticGenBailoutError(`Route ${e} with \`dynamic = "error"\` couldn't be rendered statically because it used ${t}. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`),"__NEXT_ERROR_CODE",{value:"E543",enumerable:!1,configurable:!0})}function l(e,t){let r=Object.defineProperty(Error(`Route ${e.route} used \`searchParams\` inside "use cache". Accessing dynamic request data inside a cache scope is not supported. If you need some search params inside a cached function await \`searchParams\` outside of the cached function and pass only the required search params as arguments to the cached function. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache`),"__NEXT_ERROR_CODE",{value:"E842",enumerable:!1,configurable:!0});throw Error.captureStackTrace(r,t),e.invalidDynamicUsageError??=r,r}function c(){let e=i.afterTaskAsyncStorage.getStore();return(null==e?void 0:e.rootTaskSpawnPhase)==="action"}},928649,(e,t,r)=>{"use strict";var n=Object.defineProperty,a=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,s={},l={RequestCookies:()=>h,ResponseCookies:()=>g,parseCookie:()=>d,parseSetCookie:()=>f,stringifyCookie:()=>u};for(var c in l)n(s,c,{get:l[c],enumerable:!0});function u(e){var t;let r=["path"in e&&e.path&&`Path=${e.path}`,"expires"in e&&(e.expires||0===e.expires)&&`Expires=${("number"==typeof e.expires?new Date(e.expires):e.expires).toUTCString()}`,"maxAge"in e&&"number"==typeof e.maxAge&&`Max-Age=${e.maxAge}`,"domain"in e&&e.domain&&`Domain=${e.domain}`,"secure"in e&&e.secure&&"Secure","httpOnly"in e&&e.httpOnly&&"HttpOnly","sameSite"in e&&e.sameSite&&`SameSite=${e.sameSite}`,"partitioned"in e&&e.partitioned&&"Partitioned","priority"in e&&e.priority&&`Priority=${e.priority}`].filter(Boolean),n=`${e.name}=${encodeURIComponent(null!=(t=e.value)?t:"")}`;return 0===r.length?n:`${n}; ${r.join("; ")}`}function d(e){let t=new Map;for(let r of e.split(/; */)){if(!r)continue;let e=r.indexOf("=");if(-1===e){t.set(r,"true");continue}let[n,a]=[r.slice(0,e),r.slice(e+1)];try{t.set(n,decodeURIComponent(null!=a?a:"true"))}catch{}}return t}function f(e){if(!e)return;let[[t,r],...n]=d(e),{domain:a,expires:o,httponly:i,maxage:s,path:l,samesite:c,secure:u,partitioned:f,priority:h}=Object.fromEntries(n.map(([e,t])=>[e.toLowerCase().replace(/-/g,""),t]));{var g,y,b={name:t,value:decodeURIComponent(r),domain:a,...o&&{expires:new Date(o)},...i&&{httpOnly:!0},..."string"==typeof s&&{maxAge:Number(s)},path:l,...c&&{sameSite:p.includes(g=(g=c).toLowerCase())?g:void 0},...u&&{secure:!0},...h&&{priority:m.includes(y=(y=h).toLowerCase())?y:void 0},...f&&{partitioned:!0}};let e={};for(let t in b)b[t]&&(e[t]=b[t]);return e}}t.exports=((e,t,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let s of o(t))i.call(e,s)||void 0===s||n(e,s,{get:()=>t[s],enumerable:!(r=a(t,s))||r.enumerable});return e})(n({},"__esModule",{value:!0}),s);var p=["strict","lax","none"],m=["low","medium","high"],h=class{constructor(e){this._parsed=new Map,this._headers=e;const t=e.get("cookie");if(t)for(const[e,r]of d(t))this._parsed.set(e,{name:e,value:r})}[Symbol.iterator](){return this._parsed[Symbol.iterator]()}get size(){return this._parsed.size}get(...e){let t="string"==typeof e[0]?e[0]:e[0].name;return this._parsed.get(t)}getAll(...e){var t;let r=Array.from(this._parsed);if(!e.length)return r.map(([e,t])=>t);let n="string"==typeof e[0]?e[0]:null==(t=e[0])?void 0:t.name;return r.filter(([e])=>e===n).map(([e,t])=>t)}has(e){return this._parsed.has(e)}set(...e){let[t,r]=1===e.length?[e[0].name,e[0].value]:e,n=this._parsed;return n.set(t,{name:t,value:r}),this._headers.set("cookie",Array.from(n).map(([e,t])=>u(t)).join("; ")),this}delete(e){let t=this._parsed,r=Array.isArray(e)?e.map(e=>t.delete(e)):t.delete(e);return this._headers.set("cookie",Array.from(t).map(([e,t])=>u(t)).join("; ")),r}clear(){return this.delete(Array.from(this._parsed.keys())),this}[Symbol.for("edge-runtime.inspect.custom")](){return`RequestCookies ${JSON.stringify(Object.fromEntries(this._parsed))}`}toString(){return[...this._parsed.values()].map(e=>`${e.name}=${encodeURIComponent(e.value)}`).join("; ")}},g=class{constructor(e){var t,r,n;this._parsed=new Map,this._headers=e;const a=null!=(n=null!=(r=null==(t=e.getSetCookie)?void 0:t.call(e))?r:e.get("set-cookie"))?n:[];for(const e of Array.isArray(a)?a:function(e){if(!e)return[];var t,r,n,a,o,i=[],s=0;function l(){for(;s=e.length)&&i.push(e.substring(t,e.length))}return i}(a)){const t=f(e);t&&this._parsed.set(t.name,t)}}get(...e){let t="string"==typeof e[0]?e[0]:e[0].name;return this._parsed.get(t)}getAll(...e){var t;let r=Array.from(this._parsed.values());if(!e.length)return r;let n="string"==typeof e[0]?e[0]:null==(t=e[0])?void 0:t.name;return r.filter(e=>e.name===n)}has(e){return this._parsed.has(e)}set(...e){let[t,r,n]=1===e.length?[e[0].name,e[0].value,e[0]]:e,a=this._parsed;return a.set(t,function(e={name:"",value:""}){return"number"==typeof e.expires&&(e.expires=new Date(e.expires)),e.maxAge&&(e.expires=new Date(Date.now()+1e3*e.maxAge)),(null===e.path||void 0===e.path)&&(e.path="/"),e}({name:t,value:r,...n})),function(e,t){for(let[,r]of(t.delete("set-cookie"),e)){let e=u(r);t.append("set-cookie",e)}}(a,this._headers),this}delete(...e){let[t,r]="string"==typeof e[0]?[e[0]]:[e[0].name,e[0]];return this.set({...r,name:t,value:"",expires:new Date(0)})}[Symbol.for("edge-runtime.inspect.custom")](){return`ResponseCookies ${JSON.stringify(Object.fromEntries(this._parsed))}`}toString(){return[...this._parsed.values()].map(u).join("; ")}}},196883,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={RequestCookies:function(){return o.RequestCookies},ResponseCookies:function(){return o.ResponseCookies},stringifyCookie:function(){return o.stringifyCookie}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=e.r(928649)},397270,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={MutableRequestCookiesAdapter:function(){return m},ReadonlyRequestCookiesError:function(){return c},RequestCookiesAdapter:function(){return u},appendMutableCookies:function(){return p},areCookiesMutableInCurrentPhase:function(){return g},createCookiesWithMutableAccessCheck:function(){return h},getModifiedCookieValues:function(){return f},responseCookiesToRequestCookies:function(){return b}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=e.r(196883),i=e.r(242715),s=e.r(563599),l=e.r(339146);class c extends Error{constructor(){super("Cookies can only be modified in a Server Action or Route Handler. Read more: https://nextjs.org/docs/app/api-reference/functions/cookies#options")}static callable(){throw new c}}class u{static seal(e){return new Proxy(e,{get(e,t,r){switch(t){case"clear":case"delete":case"set":return c.callable;default:return i.ReflectAdapter.get(e,t,r)}}})}}let d=Symbol.for("next.mutated.cookies");function f(e){let t=e[d];return t&&Array.isArray(t)&&0!==t.length?t:[]}function p(e,t){let r=f(t);if(0===r.length)return!1;let n=new o.ResponseCookies(e),a=n.getAll();for(let e of r)n.set(e);for(let e of a)n.set(e);return!0}class m{static wrap(e,t){let r=new o.ResponseCookies(new Headers);for(let t of e.getAll())r.set(t);let n=[],a=new Set,c=()=>{let e=s.workAsyncStorage.getStore();if(e&&(e.pathWasRevalidated=l.ActionDidRevalidateStaticAndDynamic),n=r.getAll().filter(e=>a.has(e.name)),t){let e=[];for(let t of n){let r=new o.ResponseCookies(new Headers);r.set(t),e.push(r.toString())}t(e)}},u=new Proxy(r,{get(e,t,r){switch(t){case d:return n;case"delete":return function(...t){a.add("string"==typeof t[0]?t[0]:t[0].name);try{return e.delete(...t),u}finally{c()}};case"set":return function(...t){a.add("string"==typeof t[0]?t[0]:t[0].name);try{return e.set(...t),u}finally{c()}};default:return i.ReflectAdapter.get(e,t,r)}}});return u}}function h(e){let t=new Proxy(e.mutableCookies,{get(r,n,a){switch(n){case"delete":return function(...n){return y(e,"cookies().delete"),r.delete(...n),t};case"set":return function(...n){return y(e,"cookies().set"),r.set(...n),t};default:return i.ReflectAdapter.get(r,n,a)}}});return t}function g(e){return"action"===e.phase}function y(e,t){if(!g(e))throw new c}function b(e){let t=new o.RequestCookies(new Headers);for(let r of e.getAll())t.set(r);return t}},687720,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={HeadersAdapter:function(){return s},ReadonlyHeadersError:function(){return i}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=e.r(242715);class i extends Error{constructor(){super("Headers cannot be modified. Read more: https://nextjs.org/docs/app/api-reference/functions/headers")}static callable(){throw new i}}class s extends Headers{constructor(e){super(),this.headers=new Proxy(e,{get(t,r,n){if("symbol"==typeof r)return o.ReflectAdapter.get(t,r,n);let a=r.toLowerCase(),i=Object.keys(e).find(e=>e.toLowerCase()===a);if(void 0!==i)return o.ReflectAdapter.get(t,i,n)},set(t,r,n,a){if("symbol"==typeof r)return o.ReflectAdapter.set(t,r,n,a);let i=r.toLowerCase(),s=Object.keys(e).find(e=>e.toLowerCase()===i);return o.ReflectAdapter.set(t,s??r,n,a)},has(t,r){if("symbol"==typeof r)return o.ReflectAdapter.has(t,r);let n=r.toLowerCase(),a=Object.keys(e).find(e=>e.toLowerCase()===n);return void 0!==a&&o.ReflectAdapter.has(t,a)},deleteProperty(t,r){if("symbol"==typeof r)return o.ReflectAdapter.deleteProperty(t,r);let n=r.toLowerCase(),a=Object.keys(e).find(e=>e.toLowerCase()===n);return void 0===a||o.ReflectAdapter.deleteProperty(t,a)}})}static seal(e){return new Proxy(e,{get(e,t,r){switch(t){case"append":case"delete":case"set":return i.callable;default:return o.ReflectAdapter.get(e,t,r)}}})}merge(e){return Array.isArray(e)?e.join(", "):e}static from(e){return e instanceof Headers?e:new s(e)}append(e,t){let r=this.headers[e];"string"==typeof r?this.headers[e]=[r,t]:Array.isArray(r)?r.push(t):this.headers[e]=t}delete(e){delete this.headers[e]}get(e){let t=this.headers[e];return void 0!==t?this.merge(t):null}has(e){return void 0!==this.headers[e]}set(e,t){this.headers[e]=t}forEach(e,t){for(let[r,n]of this.entries())e.call(t,n,r,this)}*entries(){for(let e of Object.keys(this.headers)){let t=e.toLowerCase(),r=this.get(t);yield[t,r]}}*keys(){for(let e of Object.keys(this.headers)){let t=e.toLowerCase();yield t}}*values(){for(let e of Object.keys(this.headers)){let t=this.get(e);yield t}}[Symbol.iterator](){return this.entries()}}},401643,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={getParamProperties:function(){return l},getSegmentParam:function(){return i},isCatchAll:function(){return s}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=e.r(591463);function i(e){let t=o.INTERCEPTION_ROUTE_MARKERS.find(t=>e.startsWith(t));return(t&&(e=e.slice(t.length)),e.startsWith("[[...")&&e.endsWith("]]"))?{paramType:"optional-catchall",paramName:e.slice(5,-2)}:e.startsWith("[...")&&e.endsWith("]")?{paramType:t?`catchall-intercepted-${t}`:"catchall",paramName:e.slice(4,-1)}:e.startsWith("[")&&e.endsWith("]")?{paramType:t?`dynamic-intercepted-${t}`:"dynamic",paramName:e.slice(1,-1)}:null}function s(e){return"catchall"===e||"catchall-intercepted-(..)(..)"===e||"catchall-intercepted-(.)"===e||"catchall-intercepted-(..)"===e||"catchall-intercepted-(...)"===e||"optional-catchall"===e}function l(e){let t=!1,r=!1;switch(e){case"catchall":case"catchall-intercepted-(..)(..)":case"catchall-intercepted-(.)":case"catchall-intercepted-(..)":case"catchall-intercepted-(...)":t=!0;break;case"optional-catchall":t=!0,r=!0}return{repeat:t,optional:r}}},722783,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"parseRelativeUrl",{enumerable:!0,get:function(){return o}});let n=e.r(718967),a=e.r(998183);function o(e,t,r=!0){let i=new URL("u"{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={InstantValidationError:function(){return s},isInstantValidationError:function(){return i}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o="INSTANT_VALIDATION_ERROR";function i(e){return!!(e&&"object"==typeof e&&e instanceof Error&&e.digest===o)}class s extends Error{constructor(...e){super(...e),this.digest=o}}},918450,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={assertRootParamInSamples:function(){return S},createCookiesFromSample:function(){return y},createDraftModeForValidation:function(){return _},createExhaustiveParamsProxy:function(){return v},createExhaustiveSearchParamsProxy:function(){return E},createExhaustiveURLSearchParamsProxy:function(){return R},createHeadersFromSample:function(){return P},createRelativeURLFromSamples:function(){return w},createValidationSampleTracking:function(){return m},trackMissingSampleError:function(){return h},trackMissingSampleErrorAndThrow:function(){return g}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=e.r(196883),i=e.r(397270),s=e.r(687720),l=e.r(401643),c=e.r(722783),u=e.r(312718),d=e.r(513770),f=e.r(662141),p=e.r(565932);function m(){return{missingSampleErrors:[]}}function h(e){(function(){let e=null,t=f.workUnitAsyncStorage.getStore();if(t)switch(t.type){case"request":case"validation-client":e=t.validationSampleTracking??null}if(!e)throw Object.defineProperty(new u.InvariantError("Expected to have a workUnitStore that provides validationSampleTracking"),"__NEXT_ERROR_CODE",{value:"E1110",enumerable:!1,configurable:!0});return e})().missingSampleErrors.push(e)}function g(e){throw h(e),e}function y(e,t){let r=new Set,n=new o.RequestCookies(new Headers);if(e)for(let t of e)r.add(t.name),null!==t.value&&n.set(t.name,t.value);return new Proxy(i.RequestCookiesAdapter.seal(n),{get(e,n,a){if("has"===n){let o=Reflect.get(e,n,a);return function(n){return r.has(n)||g(b(t,n)),o.call(e,n)}}if("get"===n){let o=Reflect.get(e,n,a);return function(n){let a;if("string"==typeof n)a=n;else{if(!n||"object"!=typeof n||"string"!=typeof n.name)return o.call(e,n);a=n.name}return r.has(a)||g(b(t,a)),o.call(e,a)}}return Reflect.get(e,n,a)}})}function b(e,t){return Object.defineProperty(new d.InstantValidationError(`Route "${e}" accessed cookie "${t}" which is not defined in the \`samples\` of \`unstable_instant\`. Add it to the sample's \`cookies\` array, or \`{ name: "${t}", value: null }\` if it should be absent.`),"__NEXT_ERROR_CODE",{value:"E1115",enumerable:!1,configurable:!0})}function P(e,t,r){let n=e?[...e]:[];if(n.find(([e])=>"cookie"===e.toLowerCase()))throw Object.defineProperty(new d.InstantValidationError('Invalid sample: Defining cookies via a "cookie" header is not supported. Use `cookies: [{ name: ..., value: ... }]` instead.'),"__NEXT_ERROR_CODE",{value:"E1111",enumerable:!1,configurable:!0});if(t){let e=t.toString();n.push(["cookie",""!==e?e:null])}let a=new Set,o={};for(let[e,t]of n)a.add(e.toLowerCase()),null!==t&&(o[e.toLowerCase()]=t);return new Proxy(s.HeadersAdapter.seal(s.HeadersAdapter.from(o)),{get(e,t,n){if("get"===t||"has"===t){let o=Reflect.get(e,t,n);return function(t){let n=t.toLowerCase();return a.has(n)||g(Object.defineProperty(new d.InstantValidationError(`Route "${r}" accessed header "${n}" which is not defined in the \`samples\` of \`unstable_instant\`. Add it to the sample's \`headers\` array, or \`["${n}", null]\` if it should be absent.`),"__NEXT_ERROR_CODE",{value:"E1116",enumerable:!1,configurable:!0})),o.call(e,n)}}return Reflect.get(e,t,n)}})}function _(){return{get isEnabled(){return!1},enable(){throw Object.defineProperty(Error("Draft mode cannot be enabled during build-time instant validation."),"__NEXT_ERROR_CODE",{value:"E1092",enumerable:!1,configurable:!0})},disable(){throw Object.defineProperty(Error("Draft mode cannot be disabled during build-time instant validation."),"__NEXT_ERROR_CODE",{value:"E1094",enumerable:!1,configurable:!0})}}}function v(e,t,r){return new Proxy(e,{get:(n,a,o)=>("string"==typeof a&&!p.wellKnownProperties.has(a)&&a in e&&!t.has(a)&&g(Object.defineProperty(new d.InstantValidationError(`Route "${r}" accessed param "${a}" which is not defined in the \`samples\` of \`unstable_instant\`. Add it to the sample's \`params\` object.`),"__NEXT_ERROR_CODE",{value:"E1095",enumerable:!1,configurable:!0})),Reflect.get(n,a,o))})}function E(e,t,r){return new Proxy(e,{get:(e,n,a)=>("string"!=typeof n||p.wellKnownProperties.has(n)||t.has(n)||g(O(r,n)),Reflect.get(e,n,a)),has:(e,n)=>("string"!=typeof n||p.wellKnownProperties.has(n)||t.has(n)||g(O(r,n)),Reflect.has(e,n))})}function R(e,t,r){return new Proxy(e,{get(e,n,a){if("get"===n||"getAll"===n||"has"===n){let o=Reflect.get(e,n,a);return n=>("string"!=typeof n||t.has(n)||g(O(r,n)),o.call(e,n))}let o=Reflect.get(e,n,a);return"function"!=typeof o||Object.hasOwn(e,n)?o:o.bind(e)}})}function O(e,t){return Object.defineProperty(new d.InstantValidationError(`Route "${e}" accessed searchParam "${t}" which is not defined in the \`samples\` of \`unstable_instant\`. Add it to the sample's \`searchParams\` object, or \`{ "${t}": null }\` if it should be absent.`),"__NEXT_ERROR_CODE",{value:"E1098",enumerable:!1,configurable:!0})}function w(e,t,r){let n=function(e,t){let r=[];for(let n of e.split("/")){let e=(0,l.getSegmentParam)(n);if(e)switch(e.paramType){case"catchall":case"optional-catchall":{let a=t[e.paramName];if(void 0===a)a=[n];else if(!Array.isArray(a))throw Object.defineProperty(new d.InstantValidationError(`Expected sample param value for segment '${n}' to be an array of strings, got ${typeof a}`),"__NEXT_ERROR_CODE",{value:"E1104",enumerable:!1,configurable:!0});r.push(...a.map(e=>encodeURIComponent(e)));break}case"dynamic":{let a=t[e.paramName];if(void 0===a)a=n;else if("string"!=typeof a)throw Object.defineProperty(new d.InstantValidationError(`Expected sample param value for segment '${n}' to be a string, got ${typeof a}`),"__NEXT_ERROR_CODE",{value:"E1108",enumerable:!1,configurable:!0});r.push(encodeURIComponent(a));break}case"catchall-intercepted-(..)(..)":case"catchall-intercepted-(.)":case"catchall-intercepted-(..)":case"catchall-intercepted-(...)":case"dynamic-intercepted-(..)(..)":case"dynamic-intercepted-(.)":case"dynamic-intercepted-(..)":case"dynamic-intercepted-(...)":throw Object.defineProperty(new u.InvariantError("Not implemented: Validation of interception routes"),"__NEXT_ERROR_CODE",{value:"E1106",enumerable:!1,configurable:!0});default:e.paramType}else r.push(n)}return r.join("/")}(e,t??{}),a="";if(r){let e=(function(e){let t=new URLSearchParams;if(e){for(let[r,n]of Object.entries(e))if(null!=n)if(Array.isArray(n))for(let e of n)t.append(r,e);else t.set(r,n)}return t})(r).toString();e&&(a="?"+e)}return(0,c.parseRelativeUrl)(n+a,void 0,!0)}function S(e,t,r){if(t&&r in t);else{let t=e.route;g(Object.defineProperty(new d.InstantValidationError(`Route "${t}" accessed root param "${r}" which is not defined in the \`samples\` of \`unstable_instant\`. Add it to the sample's \`params\` object.`),"__NEXT_ERROR_CODE",{value:"E1114",enumerable:!1,configurable:!0}))}}},269882,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={createPrerenderSearchParamsForClientPage:function(){return P},createSearchParamsFromClient:function(){return g},createServerSearchParamsForMetadata:function(){return y},createServerSearchParamsForServerPage:function(){return b},makeErroringSearchParamsForUseCache:function(){return O}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=e.r(563599),i=e.r(66373),s=e.r(242715),l=e.r(67673),c=e.r(662141),u=e.r(312718),d=e.r(963138),f=e.r(364146),p=e.r(565932),m=e.r(850999),h=e.r(142852);function g(t){let r=o.workAsyncStorage.getStore();if(!r)throw Object.defineProperty(new u.InvariantError("Expected workStore to be initialized"),"__NEXT_ERROR_CODE",{value:"E1068",enumerable:!1,configurable:!0});let n=c.workUnitAsyncStorage.getStore();if(n)switch(n.type){case"prerender":case"prerender-client":case"prerender-ppr":case"prerender-legacy":return _(r,n);case"validation-client":return function(t,r,n){var a;let{createExhaustiveSearchParamsProxy:o}=e.r(918450);return Promise.resolve(t=o(t,new Set(Object.keys((null==(a=n.validationSamples)?void 0:a.searchParams)??{})),r.route))}(t,r,n);case"prerender-runtime":throw Object.defineProperty(new u.InvariantError("createSearchParamsFromClient should not be called in a runtime prerender."),"__NEXT_ERROR_CODE",{value:"E769",enumerable:!1,configurable:!0});case"cache":case"private-cache":case"unstable-cache":throw Object.defineProperty(new u.InvariantError("createSearchParamsFromClient should not be called in cache contexts."),"__NEXT_ERROR_CODE",{value:"E739",enumerable:!1,configurable:!0});case"generate-static-params":throw Object.defineProperty(new u.InvariantError("createSearchParamsFromClient should not be called inside generateStaticParams."),"__NEXT_ERROR_CODE",{value:"E1133",enumerable:!1,configurable:!0});case"request":return v(t,r,n,!1)}(0,c.throwInvariantForMissingStore)()}function y(e,t){return b(e,(0,i.getMetadataVaryParamsAccumulator)(),t)}function b(e,t,r){let n=o.workAsyncStorage.getStore();if(!n)throw Object.defineProperty(new u.InvariantError("Expected workStore to be initialized"),"__NEXT_ERROR_CODE",{value:"E1068",enumerable:!1,configurable:!0});let a=c.workUnitAsyncStorage.getStore();if(a)switch(a.type){case"prerender":case"prerender-client":case"prerender-ppr":case"prerender-legacy":return _(n,a);case"validation-client":throw Object.defineProperty(new u.InvariantError("createServerSearchParamsForServerPage should not be called in a client validation."),"__NEXT_ERROR_CODE",{value:"E1066",enumerable:!1,configurable:!0});case"cache":case"private-cache":case"unstable-cache":throw Object.defineProperty(new u.InvariantError("createServerSearchParamsForServerPage should not be called in cache contexts."),"__NEXT_ERROR_CODE",{value:"E747",enumerable:!1,configurable:!0});case"generate-static-params":throw Object.defineProperty(new u.InvariantError("createServerSearchParamsForServerPage should not be called inside generateStaticParams."),"__NEXT_ERROR_CODE",{value:"E1128",enumerable:!1,configurable:!0});case"prerender-runtime":return function(e,t,r,n){let a=w(null!==r?(0,i.createVaryingSearchParams)(r,e):e),{stagedRendering:o}=t;if(!o)return a;let s=n?h.RenderStage.EarlyRuntime:h.RenderStage.Runtime;return o.waitForStage(s).then(()=>a)}(e,a,t,r);case"request":return v(e,n,a,r)}(0,c.throwInvariantForMissingStore)()}function P(){let e=o.workAsyncStorage.getStore();if(!e)throw Object.defineProperty(new u.InvariantError("Expected workStore to be initialized"),"__NEXT_ERROR_CODE",{value:"E1068",enumerable:!1,configurable:!0});if(e.forceStatic)return Promise.resolve({});let t=c.workUnitAsyncStorage.getStore();if(t)switch(t.type){case"prerender":case"prerender-client":return(0,d.makeHangingPromise)(t.renderSignal,e.route,"`searchParams`");case"validation-client":throw Object.defineProperty(new u.InvariantError("createPrerenderSearchParamsForClientPage should not be called in a client validation."),"__NEXT_ERROR_CODE",{value:"E1061",enumerable:!1,configurable:!0});case"prerender-runtime":throw Object.defineProperty(new u.InvariantError("createPrerenderSearchParamsForClientPage should not be called in a runtime prerender."),"__NEXT_ERROR_CODE",{value:"E768",enumerable:!1,configurable:!0});case"cache":case"private-cache":case"unstable-cache":throw Object.defineProperty(new u.InvariantError("createPrerenderSearchParamsForClientPage should not be called in cache contexts."),"__NEXT_ERROR_CODE",{value:"E746",enumerable:!1,configurable:!0});case"generate-static-params":throw Object.defineProperty(new u.InvariantError("createPrerenderSearchParamsForClientPage should not be called inside generateStaticParams."),"__NEXT_ERROR_CODE",{value:"E1124",enumerable:!1,configurable:!0});case"prerender-ppr":case"prerender-legacy":case"request":return Promise.resolve({})}(0,c.throwInvariantForMissingStore)()}function _(e,t){if(e.forceStatic)return Promise.resolve({});switch(t.type){case"prerender":case"prerender-client":var r=e,n=t;let a=E.get(n);if(a)return a;let o=(0,d.makeHangingPromise)(n.renderSignal,r.route,"`searchParams`"),i=new Proxy(o,{get(e,t,r){if(Object.hasOwn(o,t))return s.ReflectAdapter.get(e,t,r);switch(t){case"then":return(0,l.annotateDynamicAccess)("`await searchParams`, `searchParams.then`, or similar",n),s.ReflectAdapter.get(e,t,r);case"status":return(0,l.annotateDynamicAccess)("`use(searchParams)`, `searchParams.status`, or similar",n),s.ReflectAdapter.get(e,t,r);default:return s.ReflectAdapter.get(e,t,r)}}});return E.set(n,i),i;case"prerender-ppr":case"prerender-legacy":var c=e,u=t;let f=E.get(c);if(f)return f;let p=Promise.resolve({}),h=new Proxy(p,{get(e,t,r){if(Object.hasOwn(p,t))return s.ReflectAdapter.get(e,t,r);if("string"==typeof t&&"then"===t){let e="`await searchParams`, `searchParams.then`, or similar";c.dynamicShouldError?(0,m.throwWithStaticGenerationBailoutErrorWithDynamicError)(c.route,e):"prerender-ppr"===u.type?(0,l.postponeWithTracking)(c.route,e,u.dynamicTracking):(0,l.throwToInterruptStaticGeneration)(e,c,u)}return s.ReflectAdapter.get(e,t,r)}});return E.set(c,h),h;default:return t}}function v(t,r,n,a){if(r.forceStatic)return Promise.resolve({});if(!n.asyncApiPromises)return w(t);if(n.validationSamples){let{createExhaustiveSearchParamsProxy:a}=e.r(918450),o=new Set(Object.keys(n.validationSamples.searchParams??{}));t=a(t,o,r.route)}return(a?n.asyncApiPromises.earlySharedSearchParamsParent:n.asyncApiPromises.sharedSearchParamsParent).then(()=>t)}let E=new WeakMap,R=new WeakMap;function O(){let e=o.workAsyncStorage.getStore();if(!e)throw Object.defineProperty(new u.InvariantError("Expected workStore to be initialized"),"__NEXT_ERROR_CODE",{value:"E1068",enumerable:!1,configurable:!0});let t=R.get(e);if(t)return t;let r=Promise.resolve({}),n=new Proxy(r,{get:function t(n,a,o){return Object.hasOwn(r,a)||"string"!=typeof a||"then"!==a&&p.wellKnownProperties.has(a)||(0,m.throwForSearchParamsAccessInUseCache)(e,t),s.ReflectAdapter.get(n,a,o)}});return R.set(e,n),n}function w(e){let t=E.get(e);if(t)return t;let r=Promise.resolve(e);return E.set(e,r),r}(0,f.createDedupedByCallsiteServerErrorLoggerDev)(function(e,t){let r=e?`Route "${e}" `:"This route ";return Object.defineProperty(Error(`${r}used ${t}. \`searchParams\` is a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis`),"__NEXT_ERROR_CODE",{value:"E848",enumerable:!1,configurable:!0})})},74804,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"dynamicAccessAsyncStorageInstance",{enumerable:!0,get:function(){return n}});let n=(0,e.r(90317).createAsyncLocalStorage)()},288276,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"dynamicAccessAsyncStorage",{enumerable:!0,get:function(){return n.dynamicAccessAsyncStorageInstance}});let n=e.r(74804)},541489,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={createParamsFromClient:function(){return g},createPrerenderParamsForClientSegment:function(){return _},createServerParamsForMetadata:function(){return y},createServerParamsForRoute:function(){return b},createServerParamsForServerSegment:function(){return P}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=e.r(563599),i=e.r(66373),s=e.r(242715),l=e.r(67673),c=e.r(662141),u=e.r(312718),d=e.r(565932),f=e.r(963138),p=e.r(364146),m=e.r(288276),h=e.r(142852);function g(e){let t=o.workAsyncStorage.getStore();if(!t)throw Object.defineProperty(new u.InvariantError("Expected workStore to be initialized"),"__NEXT_ERROR_CODE",{value:"E1068",enumerable:!1,configurable:!0});let r=c.workUnitAsyncStorage.getStore();if(r)switch(r.type){case"prerender":case"prerender-client":case"prerender-ppr":case"prerender-legacy":return v(e,null,t,r,null);case"validation-client":return R(e,t,r.validationSamples);case"cache":case"private-cache":case"unstable-cache":throw Object.defineProperty(new u.InvariantError("createParamsFromClient should not be called in cache contexts."),"__NEXT_ERROR_CODE",{value:"E736",enumerable:!1,configurable:!0});case"prerender-runtime":throw Object.defineProperty(new u.InvariantError("createParamsFromClient should not be called in a runtime prerender."),"__NEXT_ERROR_CODE",{value:"E770",enumerable:!1,configurable:!0});case"generate-static-params":throw Object.defineProperty(new u.InvariantError("createParamsFromClient should not be called inside generateStaticParams."),"__NEXT_ERROR_CODE",{value:"E1122",enumerable:!1,configurable:!0});case"request":if(r.validationSamples)return R(e,t,r.validationSamples);return S(e)}(0,c.throwInvariantForMissingStore)()}function y(e,t,r){return P(e,t,(0,i.getMetadataVaryParamsAccumulator)(),r)}function b(e,t=null){let r=o.workAsyncStorage.getStore();if(!r)throw Object.defineProperty(new u.InvariantError("Expected workStore to be initialized"),"__NEXT_ERROR_CODE",{value:"E1068",enumerable:!1,configurable:!0});let n=c.workUnitAsyncStorage.getStore();if(n)switch(n.type){case"prerender":case"prerender-ppr":case"prerender-legacy":return v(e,null,r,n,t);case"prerender-client":case"validation-client":throw Object.defineProperty(new u.InvariantError("createServerParamsForRoute should not be called in client contexts."),"__NEXT_ERROR_CODE",{value:"E1064",enumerable:!1,configurable:!0});case"cache":case"private-cache":case"unstable-cache":throw Object.defineProperty(new u.InvariantError("createServerParamsForRoute should not be called in cache contexts."),"__NEXT_ERROR_CODE",{value:"E738",enumerable:!1,configurable:!0});case"generate-static-params":throw Object.defineProperty(new u.InvariantError("createServerParamsForRoute should not be called inside generateStaticParams."),"__NEXT_ERROR_CODE",{value:"E1131",enumerable:!1,configurable:!0});case"prerender-runtime":return E(e,null,n,t,!1);case"request":return S(e)}(0,c.throwInvariantForMissingStore)()}function P(t,r,n,a){let i=o.workAsyncStorage.getStore();if(!i)throw Object.defineProperty(new u.InvariantError("Expected workStore to be initialized"),"__NEXT_ERROR_CODE",{value:"E1068",enumerable:!1,configurable:!0});let s=c.workUnitAsyncStorage.getStore();if(s)switch(s.type){case"prerender":case"prerender-client":case"prerender-ppr":case"prerender-legacy":return v(t,r,i,s,n);case"validation-client":throw Object.defineProperty(new u.InvariantError("createServerParamsForServerSegment should not be called in client contexts."),"__NEXT_ERROR_CODE",{value:"E1101",enumerable:!1,configurable:!0});case"cache":case"private-cache":case"unstable-cache":throw Object.defineProperty(new u.InvariantError("createServerParamsForServerSegment should not be called in cache contexts."),"__NEXT_ERROR_CODE",{value:"E743",enumerable:!1,configurable:!0});case"generate-static-params":throw Object.defineProperty(new u.InvariantError("createServerParamsForServerSegment should not be called inside generateStaticParams."),"__NEXT_ERROR_CODE",{value:"E1120",enumerable:!1,configurable:!0});case"prerender-runtime":return E(t,r,s,n,a);case"request":if(s.asyncApiPromises&&s.validationSamples)return function(t,r,n,a,o){let{createExhaustiveParamsProxy:i}=e.r(918450),s=i(t,new Set(Object.keys(n.params??{})),r.route);return(o?a.earlySharedParamsParent:a.sharedParamsParent).then(()=>s)}(t,i,s.validationSamples,s.asyncApiPromises,a);if(s.asyncApiPromises&&function(e,t){if(t){for(let r in e)if(t.has(r))return!0}return!1}(t,s.fallbackParams))return(a?s.asyncApiPromises.earlySharedParamsParent:s.asyncApiPromises.sharedParamsParent).then(()=>t);return S(t)}(0,c.throwInvariantForMissingStore)()}function _(e){let t=o.workAsyncStorage.getStore();if(!t)throw Object.defineProperty(new u.InvariantError("Missing workStore in createPrerenderParamsForClientSegment"),"__NEXT_ERROR_CODE",{value:"E773",enumerable:!1,configurable:!0});let r=c.workUnitAsyncStorage.getStore();if(r)switch(r.type){case"prerender":case"prerender-client":let n=r.fallbackRouteParams;if(n){for(let a in e)if(n.has(a))return(0,f.makeHangingPromise)(r.renderSignal,t.route,"`params`")}break;case"validation-client":throw Object.defineProperty(new u.InvariantError("createPrerenderParamsForClientSegment should not be called in validation contexts."),"__NEXT_ERROR_CODE",{value:"E1099",enumerable:!1,configurable:!0});case"cache":case"private-cache":case"unstable-cache":throw Object.defineProperty(new u.InvariantError("createPrerenderParamsForClientSegment should not be called in cache contexts."),"__NEXT_ERROR_CODE",{value:"E734",enumerable:!1,configurable:!0});case"generate-static-params":throw Object.defineProperty(new u.InvariantError("createPrerenderParamsForClientSegment should not be called inside generateStaticParams."),"__NEXT_ERROR_CODE",{value:"E1126",enumerable:!1,configurable:!0})}return Promise.resolve(e)}function v(e,t,r,n,a){let o=null!==a?(0,i.createVaryingParams)(a,e,t):e;switch(n.type){case"prerender":case"prerender-client":{let t=n.fallbackRouteParams;if(t){for(let a in e)if(t.has(a))return function(e,t,r){let n=O.get(e);if(n)return n;let a=new Proxy((0,f.makeHangingPromise)(r.renderSignal,t.route,"`params`"),w);return O.set(e,a),a}(o,r,n)}break}case"prerender-ppr":{let t=n.fallbackRouteParams;if(t){for(let a in e)if(t.has(a))return function(e,t,r,n){let a=O.get(e);if(a)return a;let o={...e},i=Promise.resolve(o);return O.set(e,i),Object.keys(e).forEach(e=>{d.wellKnownProperties.has(e)||t.has(e)&&Object.defineProperty(o,e,{get(){let t=(0,d.describeStringPropertyAccess)("params",e);"prerender-ppr"===n.type?(0,l.postponeWithTracking)(r.route,t,n.dynamicTracking):(0,l.throwToInterruptStaticGeneration)(t,r,n)},enumerable:!0})}),i}(o,t,r,n)}}}return S(o)}function E(e,t,r,n,a){let o=S(null!==n?(0,i.createVaryingParams)(n,e,t):e),{stagedRendering:s}=r;if(!s)return o;let l=a?h.RenderStage.EarlyRuntime:h.RenderStage.Runtime;return s.waitForStage(l).then(()=>o)}function R(t,r,n){let{createExhaustiveParamsProxy:a}=e.r(918450);return Promise.resolve(a(t,new Set(Object.keys((null==n?void 0:n.params)??{})),r.route))}let O=new WeakMap,w={get:function(e,t,r){if("then"===t||"catch"===t||"finally"===t){let n=s.ReflectAdapter.get(e,t,r);return({[t]:(...t)=>{let r=m.dynamicAccessAsyncStorage.getStore();return r&&r.abortController.abort(Object.defineProperty(Error("Accessed fallback `params` during prerendering."),"__NEXT_ERROR_CODE",{value:"E691",enumerable:!1,configurable:!0})),new Proxy(n.apply(e,t),w)}})[t]}return s.ReflectAdapter.get(e,t,r)}};function S(e){let t=O.get(e);if(t)return t;let r=Promise.resolve(e);return O.set(e,r),r}(0,p.createDedupedByCallsiteServerErrorLoggerDev)(function(e,t){let r=e?`Route "${e}" `:"This route ";return Object.defineProperty(Error(`${r}used ${t}. \`params\` is a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis`),"__NEXT_ERROR_CODE",{value:"E834",enumerable:!1,configurable:!0})})},347257,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"ClientPageRoot",{enumerable:!0,get:function(){return l}});let n=e.r(843476),a=e.r(8372),o=e.r(271645),i=e.r(33906),s=e.r(261994);function l({Component:t,serverProvidedParams:r}){let c,u;if(null!==r)c=r.searchParams,u=r.params;else{let e=(0,o.use)(a.LayoutRouterContext);u=null!==e?e.parentParams:{},c=(0,i.urlSearchParamsToParsedUrlQuery)((0,o.use)(s.SearchParamsContext))}if("u"{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"ClientSegmentRoot",{enumerable:!0,get:function(){return i}});let n=e.r(843476),a=e.r(8372),o=e.r(271645);function i({Component:t,slots:r,serverProvidedParams:s}){let l;if(null!==s)l=s.params;else{let e=(0,o.use)(a.LayoutRouterContext);l=null!==e?e.parentParams:{}}if("u"{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"IconMark",{enumerable:!0,get:function(){return a}});let n=e.r(843476),a=()=>"u">typeof window?null:(0,n.jsx)("meta",{name:"«nxt-icon»"})}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0piozaeodiue..js b/litellm/proxy/_experimental/out/_next/static/chunks/0piozaeodiue..js new file mode 100644 index 00000000000..8d4e485ff65 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/0piozaeodiue..js @@ -0,0 +1,56 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,488143,(e,t,s)=>{"use strict";function r({widthInt:e,heightInt:t,blurWidth:s,blurHeight:a,blurDataURL:n,objectFit:i}){let l=s?40*s:e,o=a?40*a:t,c=l&&o?`viewBox='0 0 ${l} ${o}'`:"";return`%3Csvg xmlns='http://www.w3.org/2000/svg' ${c}%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='20'/%3E%3CfeColorMatrix values='1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 100 -1' result='s'/%3E%3CfeFlood x='0' y='0' width='100%25' height='100%25'/%3E%3CfeComposite operator='out' in='s'/%3E%3CfeComposite in2='SourceGraphic'/%3E%3CfeGaussianBlur stdDeviation='20'/%3E%3C/filter%3E%3Cimage width='100%25' height='100%25' x='0' y='0' preserveAspectRatio='${c?"none":"contain"===i?"xMidYMid":"cover"===i?"xMidYMid slice":"none"}' style='filter: url(%23b);' href='${n}'/%3E%3C/svg%3E`}Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"getImageBlurSvg",{enumerable:!0,get:function(){return r}})},987690,(e,t,s)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0});var r={VALID_LOADERS:function(){return n},imageConfigDefault:function(){return i}};for(var a in r)Object.defineProperty(s,a,{enumerable:!0,get:r[a]});let n=["default","imgix","cloudinary","akamai","custom"],i={deviceSizes:[640,750,828,1080,1200,1920,2048,3840],imageSizes:[32,48,64,96,128,256,384],path:"/_next/image",loader:"default",loaderFile:"",domains:[],disableStaticImages:!1,minimumCacheTTL:14400,formats:["image/webp"],maximumDiskCacheSize:void 0,maximumRedirects:3,maximumResponseBody:5e7,dangerouslyAllowLocalIP:!1,dangerouslyAllowSVG:!1,contentSecurityPolicy:"script-src 'none'; frame-src 'none'; sandbox;",contentDispositionType:"attachment",localPatterns:void 0,remotePatterns:[],qualities:[75],unoptimized:!1,customCacheHandler:!1}},908927,(e,t,s)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"getImgProps",{enumerable:!0,get:function(){return c}}),e.r(233525);let r=e.r(543369),a=e.r(488143),n=e.r(987690),i=["-moz-initial","fill","none","scale-down",void 0];function l(e){return void 0!==e.default}function o(e){return void 0===e?e:"number"==typeof e?Number.isFinite(e)?e:NaN:"string"==typeof e&&/^[0-9]+$/.test(e)?parseInt(e,10):NaN}function c({src:e,sizes:t,unoptimized:s=!1,priority:d=!1,preload:u=!1,loading:m,className:h,quality:p,width:g,height:f,fill:x=!1,style:y,overrideSrc:b,onLoad:v,onLoadingComplete:w,placeholder:j="empty",blurDataURL:_,fetchPriority:N,decoding:S="async",layout:k,objectFit:C,objectPosition:T,lazyBoundary:E,lazyRoot:A,...P},R){var O;let I,M,$,{imgConf:L,showAltText:U,blurComplete:B,defaultLoader:D}=R,q=L||n.imageConfigDefault;if("allSizes"in q)I=q;else{let e=[...q.deviceSizes,...q.imageSizes].sort((e,t)=>e-t),t=q.deviceSizes.sort((e,t)=>e-t),s=q.qualities?.sort((e,t)=>e-t);I={...q,allSizes:e,deviceSizes:t,qualities:s}}if(void 0===D)throw Object.defineProperty(Error("images.loaderFile detected but the file is missing default export.\nRead more: https://nextjs.org/docs/messages/invalid-images-config"),"__NEXT_ERROR_CODE",{value:"E163",enumerable:!1,configurable:!0});let W=P.loader||D;delete P.loader,delete P.srcSet;let z="__next_img_default"in W;if(z){if("custom"===I.loader)throw Object.defineProperty(Error(`Image with src "${e}" is missing "loader" prop. +Read more: https://nextjs.org/docs/messages/next-image-missing-loader`),"__NEXT_ERROR_CODE",{value:"E252",enumerable:!1,configurable:!0})}else{let e=W;W=t=>{let{config:s,...r}=t;return e(r)}}if(k){"fill"===k&&(x=!0);let e={intrinsic:{maxWidth:"100%",height:"auto"},responsive:{width:"100%",height:"auto"}}[k];e&&(y={...y,...e});let s={responsive:"100vw",fill:"100vw"}[k];s&&!t&&(t=s)}let F="",H=o(g),V=o(f);if((O=e)&&"object"==typeof O&&(l(O)||void 0!==O.src)){let t=l(e)?e.default:e;if(!t.src)throw Object.defineProperty(Error(`An object should only be passed to the image component src parameter if it comes from a static image import. It must include src. Received ${JSON.stringify(t)}`),"__NEXT_ERROR_CODE",{value:"E460",enumerable:!1,configurable:!0});if(!t.height||!t.width)throw Object.defineProperty(Error(`An object should only be passed to the image component src parameter if it comes from a static image import. It must include height and width. Received ${JSON.stringify(t)}`),"__NEXT_ERROR_CODE",{value:"E48",enumerable:!1,configurable:!0});if(M=t.blurWidth,$=t.blurHeight,_=_||t.blurDataURL,F=t.src,!x)if(H||V){if(H&&!V){let e=H/t.width;V=Math.round(t.height*e)}else if(!H&&V){let e=V/t.height;H=Math.round(t.width*e)}}else H=t.width,V=t.height}let J=!d&&!u&&("lazy"===m||void 0===m);(!(e="string"==typeof e?e:F)||e.startsWith("data:")||e.startsWith("blob:"))&&(s=!0,J=!1),I.unoptimized&&(s=!0),z&&!I.dangerouslyAllowSVG&&e.split("?",1)[0].endsWith(".svg")&&(s=!0);let G=o(p),K=Object.assign(x?{position:"absolute",height:"100%",width:"100%",left:0,top:0,right:0,bottom:0,objectFit:C,objectPosition:T}:{},U?{}:{color:"transparent"},y),X=B||"empty"===j?null:"blur"===j?`url("data:image/svg+xml;charset=utf-8,${(0,a.getImageBlurSvg)({widthInt:H,heightInt:V,blurWidth:M,blurHeight:$,blurDataURL:_||"",objectFit:K.objectFit})}")`:`url("${j}")`,Y=i.includes(K.objectFit)?"fill"===K.objectFit?"100% 100%":"cover":K.objectFit,Q=X?{backgroundSize:Y,backgroundPosition:K.objectPosition||"50% 50%",backgroundRepeat:"no-repeat",backgroundImage:X}:{},Z=function({config:e,src:t,unoptimized:s,width:a,quality:n,sizes:i,loader:l}){if(s){if(t.startsWith("/")&&!t.startsWith("//")){let e=(0,r.getDeploymentId)();if(e){let s=t.indexOf("?");if(-1!==s){let r=new URLSearchParams(t.slice(s+1));r.get("dpl")||(r.append("dpl",e),t=t.slice(0,s)+"?"+r.toString())}else t+=`?dpl=${e}`}}return{src:t,srcSet:void 0,sizes:void 0}}let{widths:o,kind:c}=function({deviceSizes:e,allSizes:t},s,r){if(r){let s=/(^|\s)(1?\d?\d)vw/g,a=[];for(let e;e=s.exec(r);)a.push(parseInt(e[2]));if(a.length){let s=.01*Math.min(...a);return{widths:t.filter(t=>t>=e[0]*s),kind:"w"}}return{widths:t,kind:"w"}}return"number"!=typeof s?{widths:e,kind:"w"}:{widths:[...new Set([s,2*s].map(e=>t.find(t=>t>=e)||t[t.length-1]))],kind:"x"}}(e,a,i),d=o.length-1;return{sizes:i||"w"!==c?i:"100vw",srcSet:o.map((s,r)=>`${l({config:e,src:t,quality:n,width:s})} ${"w"===c?s:r+1}${c}`).join(", "),src:l({config:e,src:t,quality:n,width:o[d]})}}({config:I,src:e,unoptimized:s,width:H,quality:G,sizes:t,loader:W}),ee=J?"lazy":m;return{props:{...P,loading:ee,fetchPriority:N,width:H,height:V,decoding:S,className:h,style:{...K,...Q},sizes:Z.sizes,srcSet:Z.srcSet,src:b||Z.src},meta:{unoptimized:s,preload:u||d,placeholder:j,fill:x}}}},898879,(e,t,s)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"default",{enumerable:!0,get:function(){return l}});let r=e.r(271645),a="u"{}:r.useLayoutEffect,i=a?()=>{}:r.useEffect;function l(e){let{headManager:t,reduceComponentsToState:s}=e;function l(){if(t&&t.mountedInstances){let e=r.Children.toArray(Array.from(t.mountedInstances).filter(Boolean));t.updateHead(s(e))}}return a&&(t?.mountedInstances?.add(e.children),l()),n(()=>(t?.mountedInstances?.add(e.children),()=>{t?.mountedInstances?.delete(e.children)})),n(()=>(t&&(t._pendingUpdate=l),()=>{t&&(t._pendingUpdate=l)})),i(()=>(t&&t._pendingUpdate&&(t._pendingUpdate(),t._pendingUpdate=null),()=>{t&&t._pendingUpdate&&(t._pendingUpdate(),t._pendingUpdate=null)})),null}},325633,(e,t,s)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0});var r={default:function(){return g},defaultHead:function(){return u}};for(var a in r)Object.defineProperty(s,a,{enumerable:!0,get:r[a]});let n=e.r(563141),i=e.r(151836),l=e.r(843476),o=i._(e.r(271645)),c=n._(e.r(898879)),d=e.r(742732);function u(){return[(0,l.jsx)("meta",{charSet:"utf-8"},"charset"),(0,l.jsx)("meta",{name:"viewport",content:"width=device-width"},"viewport")]}function m(e,t){return"string"==typeof t||"number"==typeof t?e:t.type===o.default.Fragment?e.concat(o.default.Children.toArray(t.props.children).reduce((e,t)=>"string"==typeof t||"number"==typeof t?e:e.concat(t),[])):e.concat(t)}e.r(233525);let h=["name","httpEquiv","charSet","itemProp"];function p(e){let t,s,r,a;return e.reduce(m,[]).reverse().concat(u().reverse()).filter((t=new Set,s=new Set,r=new Set,a={},e=>{let n=!0,i=!1;if(e.key&&"number"!=typeof e.key&&e.key.indexOf("$")>0){i=!0;let s=e.key.slice(e.key.indexOf("$")+1);t.has(s)?n=!1:t.add(s)}switch(e.type){case"title":case"base":s.has(e.type)?n=!1:s.add(e.type);break;case"meta":for(let t=0,s=h.length;t{let s=e.key||t;return o.default.cloneElement(e,{key:s})})}let g=function({children:e}){let t=(0,o.useContext)(d.HeadManagerContext);return(0,l.jsx)(c.default,{reduceComponentsToState:p,headManager:t,children:e})};("function"==typeof s.default||"object"==typeof s.default&&null!==s.default)&&void 0===s.default.__esModule&&(Object.defineProperty(s.default,"__esModule",{value:!0}),Object.assign(s.default,s),t.exports=s.default)},918556,(e,t,s)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"ImageConfigContext",{enumerable:!0,get:function(){return n}});let r=e.r(563141)._(e.r(271645)),a=e.r(987690),n=r.default.createContext(a.imageConfigDefault)},65856,(e,t,s)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"RouterContext",{enumerable:!0,get:function(){return r}});let r=e.r(563141)._(e.r(271645)).default.createContext(null)},670965,(e,t,s)=>{"use strict";function r(e,t){let s=e||75;return t?.qualities?.length?t.qualities.reduce((e,t)=>Math.abs(t-s){"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"default",{enumerable:!0,get:function(){return i}});let r=e.r(670965),a=e.r(543369);function n({config:e,src:t,width:s,quality:i}){let l=(0,a.getDeploymentId)();if(t.startsWith("/")&&!t.startsWith("//")){let e=t.indexOf("?");if(-1!==e){let s=new URLSearchParams(t.slice(e+1)),r=s.get("dpl");if(r){l=r,s.delete("dpl");let a=s.toString();t=t.slice(0,e)+(a?"?"+a:"")}}}if(t.startsWith("/")&&t.includes("?")&&e.localPatterns?.length===1&&"**"===e.localPatterns[0].pathname&&""===e.localPatterns[0].search)throw Object.defineProperty(Error(`Image with src "${t}" is using a query string which is not configured in images.localPatterns. +Read more: https://nextjs.org/docs/messages/next-image-unconfigured-localpatterns`),"__NEXT_ERROR_CODE",{value:"E871",enumerable:!1,configurable:!0});let o=(0,r.findClosestQuality)(i,e);return`${e.path}?url=${encodeURIComponent(t)}&w=${s}&q=${o}${t.startsWith("/")&&l?`&dpl=${l}`:""}`}n.__next_img_default=!0;let i=n},605500,(e,t,s)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0}),Object.defineProperty(s,"Image",{enumerable:!0,get:function(){return v}});let r=e.r(563141),a=e.r(151836),n=e.r(843476),i=a._(e.r(271645)),l=r._(e.r(174080)),o=r._(e.r(325633)),c=e.r(908927),d=e.r(987690),u=e.r(918556);e.r(233525);let m=e.r(65856),h=r._(e.r(1948)),p=e.r(818581),g={deviceSizes:[640,750,828,1080,1200,1920,2048,3840],imageSizes:[32,48,64,96,128,256,384],qualities:[75],path:"/_next/image/",loader:"default",dangerouslyAllowSVG:!1,unoptimized:!0};function f(e,t,s,r,a,n,i){let l=e?.src;e&&e["data-loaded-src"]!==l&&(e["data-loaded-src"]=l,("decode"in e?e.decode():Promise.resolve()).catch(()=>{}).then(()=>{if(e.parentElement&&e.isConnected){if("empty"!==t&&a(!0),s?.current){let t=new Event("load");Object.defineProperty(t,"target",{writable:!1,value:e});let r=!1,a=!1;s.current({...t,nativeEvent:t,currentTarget:e,target:e,isDefaultPrevented:()=>r,isPropagationStopped:()=>a,persist:()=>{},preventDefault:()=>{r=!0,t.preventDefault()},stopPropagation:()=>{a=!0,t.stopPropagation()}})}r?.current&&r.current(e)}}))}function x(e){return i.use?{fetchPriority:e}:{fetchpriority:e}}"u"{let C=(0,i.useCallback)(e=>{e&&(N&&(e.src=e.src),e.complete&&f(e,u,y,b,v,h,j))},[e,u,y,b,v,N,h,j]),T=(0,p.useMergedRef)(k,C);return(0,n.jsx)("img",{...S,...x(d),loading:m,width:a,height:r,decoding:l,"data-nimg":g?"fill":"1",className:o,style:c,sizes:s,srcSet:t,src:e,ref:T,onLoad:e=>{f(e.currentTarget,u,y,b,v,h,j)},onError:e=>{w(!0),"empty"!==u&&v(!0),N&&N(e)}})});function b({isAppRouter:e,imgAttributes:t}){let s={as:"image",imageSrcSet:t.srcSet,imageSizes:t.sizes,crossOrigin:t.crossOrigin,referrerPolicy:t.referrerPolicy,...x(t.fetchPriority)};return e&&l.default.preload?(l.default.preload(t.src,s),null):(0,n.jsx)(o.default,{children:(0,n.jsx)("link",{rel:"preload",href:t.srcSet?void 0:t.src,...s},"__nimg-"+t.src+t.srcSet+t.sizes)})}let v=(0,i.forwardRef)((e,t)=>{let s=(0,i.useContext)(m.RouterContext),r=(0,i.useContext)(u.ImageConfigContext),a=(0,i.useMemo)(()=>{let e=g||r||d.imageConfigDefault,t=[...e.deviceSizes,...e.imageSizes].sort((e,t)=>e-t),s=e.deviceSizes.sort((e,t)=>e-t),a=e.qualities?.sort((e,t)=>e-t);return{...e,allSizes:t,deviceSizes:s,qualities:a,localPatterns:"u"{p.current=l},[l]);let f=(0,i.useRef)(o);(0,i.useEffect)(()=>{f.current=o},[o]);let[x,v]=(0,i.useState)(!1),[w,j]=(0,i.useState)(!1),{props:_,meta:N}=(0,c.getImgProps)(e,{defaultLoader:h.default,imgConf:a,blurComplete:x,showAltText:w});return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(y,{..._,unoptimized:N.unoptimized,placeholder:N.placeholder,fill:N.fill,onLoadRef:p,onLoadingCompleteRef:f,setBlurComplete:v,setShowAltText:j,sizesInput:e.sizes,ref:t}),N.preload?(0,n.jsx)(b,{isAppRouter:!s,imgAttributes:_}):null]})});("function"==typeof s.default||"object"==typeof s.default&&null!==s.default)&&void 0===s.default.__esModule&&(Object.defineProperty(s.default,"__esModule",{value:!0}),Object.assign(s.default,s),t.exports=s.default)},794909,(e,t,s)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0});var r={default:function(){return d},getImageProps:function(){return c}};for(var a in r)Object.defineProperty(s,a,{enumerable:!0,get:r[a]});let n=e.r(563141),i=e.r(908927),l=e.r(605500),o=n._(e.r(1948));function c(e){let{props:t}=(0,i.getImgProps)(e,{defaultLoader:o.default,imgConf:{deviceSizes:[640,750,828,1080,1200,1920,2048,3840],imageSizes:[32,48,64,96,128,256,384],qualities:[75],path:"/_next/image/",loader:"default",dangerouslyAllowSVG:!1,unoptimized:!0}});for(let[e,s]of Object.entries(t))void 0===s&&delete t[e];return{props:t}}let d=l.Image},657688,(e,t,s)=>{t.exports=e.r(794909)},213970,e=>{"use strict";let t,s,r;var a,n,i,l,o,c,d,u,m,h,p,g,f,x,y,b,v,w,j,_,N,S,k,C,T,E,A,P,R,O,I,M,$,L,U,B,D,q,W,z,F,H,V,J,G,K,X,Y,Q,Z,ee,et,es,er,ea,en,ei,el,eo,ec,ed,eu,em,eh,ep,eg,ef,ex,ey=e.i(843476),eb=e.i(271645),ev=e.i(800374),ew=e.i(955135),ej=e.i(19732),e_=e.i(596239),eN=e.i(646563),eS=e.i(983561),ek=e.i(987432),eC=e.i(464571),eT=e.i(311451),eE=e.i(212931),eA=e.i(199133),eP=e.i(482725),eR=e.i(653496),eO=e.i(673709),eI=e.i(727749),eM=e.i(602869);let e$=async(e,t)=>{try{let s=t||(0,eM.getProxyBaseUrl)(),r=s?`${s}/v1/agents`:"/v1/agents",a=await fetch(r,{method:"GET",headers:{[(0,eM.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!a.ok){let e=await a.json();throw Error(e.detail||"Failed to fetch agents")}let n=await a.json();return n.sort((e,t)=>{let s=e.agent_name||e.agent_id,r=t.agent_name||t.agent_id;return s.localeCompare(r)}),n}catch(e){throw console.error("Error fetching agents:",e),e}},eL=async(e,t,s,r)=>{try{let r=await (0,eM.modelInfoCall)(e,t,s,1,200),a=r?.data??[],n=(Array.isArray(a)?a:[]).filter(e=>"string"==typeof e?.litellm_params?.model&&e.litellm_params.model.startsWith("litellm_agent/")).map(e=>({model_name:e.model_name??e.model_group??"",litellm_params:{...e.litellm_params,model:e.litellm_params.model,litellm_system_prompt:e.litellm_params?.litellm_system_prompt,tools:Array.isArray(e.litellm_params?.tools)?e.litellm_params.tools:void 0},model_info:e.model_info??null}));return n.sort((e,t)=>e.model_name.localeCompare(t.model_name)),n}catch(e){throw console.error("Error fetching agent models:",e),e}};var eU=e.i(695411),eB=e.i(166068),eD=e.i(921511);e.i(247167);var eq=e.i(356449);async function eW(e,t,s,r,a,n,i,l,o,c,d,u,m,h,p,g,f,x,y,b,v,w,j,_,N){console.log=function(){};let S=b||(0,eM.getProxyBaseUrl)(),k={};a&&a.length>0&&(k["x-litellm-tags"]=a.join(","));let C=new eq.default.OpenAI({apiKey:r,baseURL:S,dangerouslyAllowBrowser:!0,defaultHeaders:k});try{let r,a=Date.now(),b=!1,S={},k=!1,T=[];for await(let y of(h&&h.length>0&&(h.includes("__all__")?T.push({type:"mcp",server_label:"litellm",server_url:"litellm_proxy/mcp",require_approval:"never"}):h.forEach(e=>{if(e.startsWith("toolset:")){let t=e.slice(8),s=N?.find(e=>e.toolset_id===t),r=s?.toolset_name||t;T.push({type:"mcp",server_label:r,server_url:`litellm_proxy/mcp/${encodeURIComponent(r)}`,require_approval:"never"})}else{let t=v?.find(t=>t.server_id===e),s=t?.alias||t?.server_name||e,r=w?.[e]||[];T.push({type:"mcp",server_label:"litellm",server_url:`litellm_proxy/mcp/${s}`,require_approval:"never",...r.length>0?{allowed_tools:r}:{}})}})),await C.chat.completions.create({model:s,stream:!0,stream_options:{include_usage:!0},litellm_trace_id:c,messages:e,...d?{vector_store_ids:d}:{},...u?{guardrails:u}:{},...m?{policies:m}:{},...T.length>0?{tools:T,tool_choice:"auto"}:{},...void 0!==f?{temperature:f}:{},...void 0!==x?{max_tokens:x}:{},..._?{mock_testing_fallbacks:!0}:{}},{signal:n}))){let e=y.choices[0]?.delta;if(!b&&(y.choices[0]?.delta?.content||e&&e.reasoning_content)&&(b=!0,r=Date.now()-a,l&&l(r)),y.choices[0]?.delta?.content){let e=y.choices[0].delta.content;t(e,y.model)}if(e&&e.image&&p&&p(e.image.url,y.model),e&&e.reasoning_content){let t=e.reasoning_content;i&&i(t)}if(e&&e.provider_specific_fields?.search_results&&g&&g(e.provider_specific_fields.search_results),e&&e.provider_specific_fields){let t=e.provider_specific_fields;if(t.mcp_list_tools&&!S.mcp_list_tools&&(S.mcp_list_tools=t.mcp_list_tools,j&&!k)){k=!0;let e={type:"response.output_item.done",item_id:"mcp_list_tools",item:{type:"mcp_list_tools",tools:t.mcp_list_tools.map(e=>({name:e.function?.name||e.name||"",description:e.function?.description||e.description||"",input_schema:e.function?.parameters||e.input_schema||{}}))},timestamp:Date.now()};j(e)}t.mcp_tool_calls&&(S.mcp_tool_calls=t.mcp_tool_calls),t.mcp_call_results&&(S.mcp_call_results=t.mcp_call_results)}if(y.usage&&o){let e={completionTokens:y.usage.completion_tokens,promptTokens:y.usage.prompt_tokens,totalTokens:y.usage.total_tokens};y.usage.completion_tokens_details?.reasoning_tokens&&(e.reasoningTokens=y.usage.completion_tokens_details.reasoning_tokens),void 0!==y.usage.cost&&null!==y.usage.cost&&(e.cost=parseFloat(y.usage.cost)),o(e)}}j&&(S.mcp_tool_calls||S.mcp_call_results)&&S.mcp_tool_calls&&S.mcp_tool_calls.length>0&&S.mcp_tool_calls.forEach((e,t)=>{let s=e.function?.name||e.name||"",r=e.function?.arguments||e.arguments||"{}",a=S.mcp_call_results?.find(t=>t.tool_call_id===e.id||t.tool_call_id===e.call_id)||S.mcp_call_results?.[t],n={type:"response.output_item.done",item:{type:"mcp_call",name:s,arguments:"string"==typeof r?r:JSON.stringify(r),output:a?.result?"string"==typeof a.result?a.result:JSON.stringify(a.result):void 0},item_id:e.id||e.call_id,timestamp:Date.now()};j(n)});let E=Date.now();y&&y(E-a)}catch(e){throw e}}var ez=e.i(878894),eF=e.i(217923),eH=e.i(531245),eV=e.i(475254);let eJ=(0,eV.default)("brain",[["path",{d:"M12 5a3 3 0 1 0-5.997.125 4 4 0 0 0-2.526 5.77 4 4 0 0 0 .556 6.588A4 4 0 1 0 12 18Z",key:"l5xja"}],["path",{d:"M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.526 5.77 4 4 0 0 1-.556 6.588A4 4 0 1 1 12 18Z",key:"ep3f8r"}],["path",{d:"M15 13a4.5 4.5 0 0 1-3-4 4.5 4.5 0 0 1-3 4",key:"1p4c4q"}],["path",{d:"M17.599 6.5a3 3 0 0 0 .399-1.375",key:"tmeiqw"}],["path",{d:"M6.003 5.125A3 3 0 0 0 6.401 6.5",key:"105sqy"}],["path",{d:"M3.477 10.896a4 4 0 0 1 .585-.396",key:"ql3yin"}],["path",{d:"M19.938 10.5a4 4 0 0 1 .585.396",key:"1qfode"}],["path",{d:"M6 18a4 4 0 0 1-1.967-.516",key:"2e4loj"}],["path",{d:"M19.967 17.484A4 4 0 0 1 18 18",key:"159ez6"}]]),eG=(0,eV.default)("circle-check",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]);var eK=e.i(643531),eX=e.i(664659),eY=e.i(463059);let eQ=(0,eV.default)("clipboard-list",[["rect",{width:"8",height:"4",x:"8",y:"2",rx:"1",ry:"1",key:"tgr4d6"}],["path",{d:"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2",key:"116196"}],["path",{d:"M12 11h4",key:"1jrz19"}],["path",{d:"M12 16h4",key:"n85exb"}],["path",{d:"M8 11h.01",key:"1dfujw"}],["path",{d:"M8 16h.01",key:"18s6g9"}]]),eZ=(0,eV.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"}]]),e0=(0,eV.default)("file-text",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M10 9H8",key:"b1mrlr"}],["path",{d:"M16 13H8",key:"t4e002"}],["path",{d:"M16 17H8",key:"z1uh3a"}]]),e1=(0,eV.default)("fingerprint",[["path",{d:"M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4",key:"1nerag"}],["path",{d:"M14 13.12c0 2.38 0 6.38-1 8.88",key:"o46ks0"}],["path",{d:"M17.29 21.02c.12-.6.43-2.3.5-3.02",key:"ptglia"}],["path",{d:"M2 12a10 10 0 0 1 18-6",key:"ydlgp0"}],["path",{d:"M2 16h.01",key:"1gqxmh"}],["path",{d:"M21.8 16c.2-2 .131-5.354 0-6",key:"drycrb"}],["path",{d:"M5 19.5C5.5 18 6 15 6 12a6 6 0 0 1 .34-2",key:"1tidbn"}],["path",{d:"M8.65 22c.21-.66.45-1.32.57-2",key:"13wd9y"}],["path",{d:"M9 6.8a6 6 0 0 1 9 5.2v2",key:"1fr1j5"}]]),e2=(0,eV.default)("flask-conical",[["path",{d:"M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2",key:"18mbvz"}],["path",{d:"M6.453 15h11.094",key:"3shlmq"}],["path",{d:"M8.5 2h7",key:"csnxdl"}]]),e5=(0,eV.default)("list-checks",[["path",{d:"m3 17 2 2 4-4",key:"1jhpwq"}],["path",{d:"m3 7 2 2 4-4",key:"1obspn"}],["path",{d:"M13 6h8",key:"15sg57"}],["path",{d:"M13 12h8",key:"h98zly"}],["path",{d:"M13 18h8",key:"oe0vm4"}]]);var e4=e.i(531278),e3=e.i(319023),e6=e.i(686311),e8=e.i(788699),e7=e.i(431343),e9=e.i(107233),te=e.i(367240);let tt=(0,eV.default)("scale",[["path",{d:"m16 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z",key:"7g6ntu"}],["path",{d:"m2 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z",key:"ijws7r"}],["path",{d:"M7 21h10",key:"1b0cd5"}],["path",{d:"M12 3v18",key:"108xh3"}],["path",{d:"M3 7h2c2 0 5-1 7-2 2 1 5 2 7 2h2",key:"3gwbw2"}]]);var ts=e.i(555436);let tr=(0,eV.default)("send",[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",key:"1ffxy3"}],["path",{d:"m21.854 2.147-10.94 10.939",key:"12cjpa"}]]);var ta=e.i(98919);let tn=(0,eV.default)("smile",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M8 14s1.5 2 4 2 4-2 4-2",key:"1y1vjs"}],["line",{x1:"9",x2:"9.01",y1:"9",y2:"9",key:"yxxnd0"}],["line",{x1:"15",x2:"15.01",y1:"9",y2:"9",key:"1p4y9e"}]]),ti=(0,eV.default)("square",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}]]);var tl=e.i(727612);let to=(0,eV.default)("trending-down",[["path",{d:"M16 17h6v-6",key:"t6n2it"}],["path",{d:"m22 17-8.5-8.5-5 5L2 7",key:"x473p"}]]);var tc=e.i(569074),td=e.i(37727),tu=e.i(59935);let tm={lock:e3.Lock,brain:eJ,"bar-chart":eF.BarChart3,scale:tt,search:ts.Search,smile:tn,fingerprint:e1,"trash-2":tl.Trash2,"check-circle":eG,"trending-down":to,bot:eH.Bot,pencil:e8.Pencil,shield:ta.Shield,"file-text":e0};function th({iconKey:e,className:t="w-4 h-4 text-gray-500"}){let s=tm[e]??eQ;return(0,ey.jsx)(s,{className:t})}function tp({accessToken:e,disabledPersonalKeyCreation:t,backendMode:s="policies",fixedModel:r,proxySettings:a}){let n,i=(0,eB.getFrameworks)(),[l,o]=(0,eb.useState)(new Map),[c,d]=(0,eb.useState)([]),[u,m]=(0,eb.useState)([]),[h,p]=(0,eb.useState)([]),[g,f]=(0,eb.useState)(!1),[x,y]=(0,eb.useState)(new Set),[b,v]=(0,eb.useState)(new Set([i[0]?.name??""])),[w,j]=(0,eb.useState)(new Set),[_,N]=(0,eb.useState)(""),[S,k]=(0,eb.useState)([]),[C,T]=(0,eb.useState)(!1),[E,A]=(0,eb.useState)(""),[P,R]=(0,eb.useState)("fail"),[O,I]=(0,eb.useState)("quick-test"),[M,$]=(0,eb.useState)(""),[L,U]=(0,eb.useState)([]),[B,D]=(0,eb.useState)(!1),q=(0,eb.useRef)(null),W=(0,eb.useRef)(null),[z,F]=(0,eb.useState)([]),[H,V]=(0,eb.useState)(!1),[J,G]=(0,eb.useState)("all"),[K,X]=(0,eb.useState)(new Set),Y=(0,eb.useRef)(null),Q=(0,eb.useCallback)(e=>{o(new Map((0,eD.getPolicyOptionEntries)(e).map(e=>[e.value,e.label])))},[]);(0,eb.useEffect)(()=>{e&&(async()=>{try{let t=await (0,eM.getGuardrailsList)(e).catch(()=>({guardrails:[]}));d((t.guardrails||[]).map(e=>({id:e.guardrail_name,name:e.guardrail_name,type:"litellm_content_filter"})))}catch{d([])}})()},[e]),(0,eb.useEffect)(()=>{q.current?.scrollIntoView({behavior:"smooth"})},[L]);let Z=(()=>{if(0===S.length)return i;let e=new Map;for(let t of S){e.has(t.framework)||e.set(t.framework,new Map);let s=e.get(t.framework);s.has(t.category)||s.set(t.category,[]),s.get(t.category).push(t)}return[...Array.from(e.entries()).map(([e,t])=>({name:e,icon:S.find(t=>t.framework===e)?.categoryIcon??"file-text",description:`Custom prompts — ${e}.`,categories:Array.from(t.entries()).map(([e,t])=>({name:e,icon:t[0]?.categoryIcon??"file-text",description:t[0]?.categoryDescription??"",prompts:t}))})),...i]})(),ee=Z.reduce((e,t)=>e+t.categories.reduce((e,t)=>e+t.prompts.length,0),0),et=e=>{p(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e])},[es,er]=(0,eb.useState)(!1),[ea,en]=(0,eb.useState)(null),ei=(0,eb.useRef)(null),el=["prompt","expected_result"],eo=a?.LITELLM_UI_API_DOC_BASE_URL??a?.PROXY_BASE_URL??void 0,ec=(0,eb.useCallback)(async()=>{if(!M.trim()||!e)return;let t=M.trim(),a={id:`msg-${Date.now()}`,type:"user",text:t,timestamp:new Date};U(e=>[...e,a]),$(""),D(!0);try{if("chat_completions"===s&&r){let s="";await eW([{role:"user",content:t}],e=>{s+=e},r,e,void 0,void 0,void 0,void 0,void 0,void 0,void 0,h.length>0?h:void 0,u.length>0?u:void 0,void 0,void 0,void 0,void 0,void 0,void 0,eo,void 0);let a={id:`msg-${Date.now()}-sys`,type:"system",text:"Allowed — model response received.",result:"allowed",returnedText:s,timestamp:new Date};U(e=>[...e,a])}else{let{inputs:s,guardrail_errors:r=[]}=await (0,eM.testPoliciesAndGuardrails)(e,{policy_names:u.length>0?u:void 0,guardrail_names:h.length>0?h:void 0,inputs:{texts:[t]},request_data:{},input_type:"request"}),a=r.length>0?"blocked":"allowed",n=r.length>0?r.map(e=>`${e.guardrail_name}: ${e.message}`).join("; "):void 0,i=Array.isArray(s?.texts)&&s.texts.length>0?s.texts[0]:void 0,l="blocked"===a?`Blocked — ${n??"content filter"}`:"Allowed — no policy or guardrail violations detected.",o={id:`msg-${Date.now()}-sys`,type:"system",text:l,result:a,triggeredBy:n,returnedText:i,timestamp:new Date};U(e=>[...e,o])}}catch(s){let e=s instanceof Error?s.message:String(s),t={id:`msg-${Date.now()}-sys`,type:"system",text:`Error: ${e}`,result:"blocked",triggeredBy:e,timestamp:new Date};U(e=>[...e,t])}finally{D(!1)}},[e,M,u,h,s,r,eo]),ed=(0,eb.useCallback)(async()=>{if(0===x.size||!e)return;let t=new AbortController;Y.current=t;let a=t.signal;V(!0),G("all"),I("batch-results");let n=Z.flatMap(e=>e.categories.flatMap(e=>e.prompts)).filter(e=>x.has(e.id)),i=n.map(e=>e.prompt),l=n.map(e=>({promptId:e.id,prompt:e.prompt,category:e.category,categoryIcon:e.categoryIcon,expectedResult:e.expectedResult,actualResult:"allowed",isMatch:!1,status:"pending"}));F(l);try{let t="chat_completions"===s&&r,n=(await (0,eM.testPoliciesAndGuardrails)(e,{policy_names:u.length>0?u:void 0,guardrail_names:h.length>0?h:void 0,inputs_list:i.map(e=>({texts:[e]})),request_data:{},input_type:"request",...t?{agent_id:r}:{}},a)).results??[];F(l.map((e,t)=>{let s,r=n[t],a=r?.guardrail_errors??[],i=a.length>0?"blocked":"allowed",l=a.length>0?a.map(e=>`${e.guardrail_name}: ${e.message}`).join("; "):void 0;if(r?.agent_response!=null){let e=r.agent_response.choices;s=Array.isArray(e)&&e[0]?.message?.content!=null?String(e[0].message.content):void 0}return void 0===s&&Array.isArray(r?.inputs?.texts)&&r.inputs.texts.length>0&&(s=r.inputs.texts[0]),{...e,actualResult:i,isMatch:"fail"===e.expectedResult&&"blocked"===i||"pass"===e.expectedResult&&"allowed"===i,triggeredBy:l,returnedText:s,status:"complete"}}))}catch(t){if(t instanceof Error&&"AbortError"===t.name)return;let e=t instanceof Error?t.message:String(t);F(l.map(t=>({...t,actualResult:"blocked",isMatch:!1,triggeredBy:`Error: ${e}`,status:"complete"})))}finally{V(!1),Y.current=null}},[e,x,u,h,Z,s,r,eo]),eu=z.filter(e=>"complete"===e.status),em=eu.filter(e=>e.isMatch).length,eh=eu.filter(e=>!e.isMatch).length,ep=eu.filter(e=>"pass"===e.expectedResult&&"blocked"===e.actualResult).length,eg=eu.filter(e=>"fail"===e.expectedResult&&"allowed"===e.actualResult).length,ef=z.filter(e=>"complete"!==e.status).length,ex=z.filter(e=>"matches"===J?"complete"===e.status&&e.isMatch:"mismatches"===J?"complete"===e.status&&!e.isMatch:"pending"!==J||"complete"!==e.status),ev=Z.map(e=>({...e,categories:e.categories.map(e=>({...e,prompts:e.prompts.filter(e=>""===_||e.prompt.toLowerCase().includes(_.toLowerCase()))})).filter(e=>e.prompts.length>0)})).filter(e=>e.categories.length>0),ew=u.length>0||h.length>0,ej=(n=[],(u.length>0&&n.push(`${u.length} ${1===u.length?"policy":"policies"}`),h.length>0&&n.push(`${h.length} ${1===h.length?"guardrail":"guardrails"}`),0===n.length)?"Test":`Test ${n.join(" & ")}`);return(0,ey.jsx)("div",{className:"w-full h-full p-4 bg-white",children:(0,ey.jsxs)("div",{className:"rounded-2xl border border-gray-200 bg-white shadow-xs min-h-[calc(100vh-160px)] flex flex-col overflow-hidden",children:[(0,ey.jsxs)("div",{className:"shrink-0 border-b border-gray-200 px-6 py-4",children:[(0,ey.jsxs)("div",{className:"mb-3",children:[(0,ey.jsx)("h3",{className:"text-sm font-semibold text-gray-900",children:"Test Configuration"}),(0,ey.jsx)("p",{className:"text-xs text-gray-500 mt-0.5",children:"Select policies, guardrails, or both to test against."})]}),(0,ey.jsxs)("div",{className:"flex items-start gap-3 flex-wrap",children:[(0,ey.jsxs)("div",{className:"flex-1 min-w-[200px]",children:[(0,ey.jsx)("label",{className:"text-[11px] font-medium text-gray-500 uppercase tracking-wide mb-1.5 block",children:"Policies"}),e&&(0,ey.jsx)(eD.default,{value:u,onChange:m,accessToken:e,onPoliciesLoaded:Q})]}),(0,ey.jsxs)("div",{className:"flex flex-col items-center pt-6 shrink-0",children:[(0,ey.jsx)("div",{className:"w-px h-4 bg-gray-200"}),(0,ey.jsx)("span",{className:"text-[10px] font-medium text-gray-400 my-1",children:"or"}),(0,ey.jsx)("div",{className:"w-px h-4 bg-gray-200"})]}),(0,ey.jsxs)("div",{className:"flex-1 min-w-[200px]",children:[(0,ey.jsx)("label",{className:"text-[11px] font-medium text-gray-500 uppercase tracking-wide mb-1.5 block",children:"Guardrails"}),(0,ey.jsxs)("div",{className:"relative",children:[(0,ey.jsxs)("button",{type:"button",onClick:()=>f(!g),className:"w-full flex items-center justify-between border border-gray-200 rounded-lg px-3 py-2 text-sm text-left hover:border-gray-300 transition-colors",children:[(0,ey.jsx)("span",{className:h.length>0?"text-gray-700":"text-gray-400",children:h.length>0?`${h.length} selected`:"None selected"}),(0,ey.jsx)(eX.ChevronDown,{className:"w-4 h-4 text-gray-400"})]}),g&&(0,ey.jsx)("div",{className:"absolute z-30 top-full left-0 right-0 mt-1 bg-white border border-gray-200 rounded-lg shadow-lg py-1 max-h-52 overflow-y-auto",children:0===c.length?(0,ey.jsx)("div",{className:"px-3 py-2 text-xs text-gray-500",children:"No guardrails available. Create guardrails in the Guardrails page."}):c.map(e=>(0,ey.jsxs)("button",{type:"button",onClick:()=>et(e.id),className:"w-full flex items-center gap-2.5 px-3 py-2 text-sm text-left hover:bg-gray-50",children:[(0,ey.jsx)("div",{className:`w-4 h-4 rounded-sm border flex items-center justify-center shrink-0 ${h.includes(e.id)?"bg-blue-500 border-blue-500":"border-gray-300"}`,children:h.includes(e.id)&&(0,ey.jsx)(eK.Check,{className:"w-3 h-3 text-white"})}),(0,ey.jsxs)("div",{className:"min-w-0",children:[(0,ey.jsx)("div",{className:"text-gray-700",children:e.name}),e.type&&(0,ey.jsx)("div",{className:"text-[10px] text-gray-400",children:e.type})]})]},e.id))})]}),h.length>0&&(0,ey.jsx)("div",{className:"flex flex-wrap gap-1 mt-1.5",children:h.map(e=>{let t=c.find(t=>t.id===e);return(0,ey.jsxs)("span",{className:"inline-flex items-center gap-1 text-[11px] bg-indigo-50 text-indigo-700 px-1.5 py-0.5 rounded-sm font-medium",children:[t?.name,(0,ey.jsx)("button",{type:"button",onClick:()=>et(e),className:"hover:text-indigo-900","aria-label":"Remove",children:(0,ey.jsx)(td.X,{className:"w-2.5 h-2.5"})})]},e)})})]}),(0,ey.jsxs)("div",{className:"flex flex-col gap-1.5 pt-6 shrink-0",children:[H?(0,ey.jsxs)("button",{type:"button",onClick:()=>Y.current?.abort(),className:"flex items-center gap-1.5 px-4 py-2 rounded-lg text-sm font-medium transition-colors whitespace-nowrap bg-red-600 text-white hover:bg-red-700",children:[(0,ey.jsx)(ti,{className:"w-3.5 h-3.5"})," Stop"]}):(0,ey.jsxs)("button",{type:"button",onClick:ed,disabled:0===x.size||t,className:`flex items-center gap-1.5 px-4 py-2 rounded-lg text-sm font-medium transition-colors whitespace-nowrap ${0===x.size||t?"bg-gray-100 text-gray-400 cursor-not-allowed":"bg-blue-600 text-white hover:bg-blue-700"}`,children:[(0,ey.jsx)(e7.Play,{className:"w-3.5 h-3.5"})," Simulate (",x.size,")"]}),H&&(0,ey.jsxs)("span",{className:"text-[11px] text-gray-500 flex items-center gap-1",children:[(0,ey.jsx)(e4.Loader2,{className:"w-3 h-3 animate-spin"})," Running..."]}),(0,ey.jsxs)("button",{type:"button",onClick:()=>{m([]),p([]),F([]),U([])},className:"flex items-center justify-center gap-1.5 px-4 py-1.5 rounded-lg text-xs font-medium text-gray-500 hover:bg-gray-100 transition-colors",children:[(0,ey.jsx)(te.RotateCcw,{className:"w-3 h-3"})," Reset"]})]})]})]}),(0,ey.jsxs)("div",{className:"flex flex-1 min-h-0 overflow-hidden",children:[(0,ey.jsx)("div",{className:"w-[400px] shrink-0 border-r border-gray-200 flex flex-col bg-white overflow-hidden",children:(0,ey.jsxs)("div",{className:"flex-1 overflow-y-auto min-h-0",children:[(0,ey.jsxs)("div",{className:"px-4 pt-4 pb-2",children:[(0,ey.jsxs)("div",{className:"flex items-center justify-between mb-2.5",children:[(0,ey.jsx)("h3",{className:"text-sm font-semibold text-gray-900",children:"Test Prompts"}),(0,ey.jsxs)("span",{className:"text-[11px] text-gray-400 tabular-nums",children:[x.size,"/",ee]})]}),(0,ey.jsxs)("div",{className:"relative mb-2.5",children:[(0,ey.jsx)(ts.Search,{className:"absolute left-2.5 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-gray-400"}),(0,ey.jsx)("input",{type:"text",value:_,onChange:e=>N(e.target.value),placeholder:"Search prompts...",className:"w-full border border-gray-200 rounded-lg pl-8 pr-3 py-1.5 text-xs placeholder:text-gray-400 focus:outline-hidden focus:ring-2 focus:ring-blue-500/20 focus:border-blue-400"})]}),(0,ey.jsxs)("div",{className:"flex items-center justify-between mb-1",children:[(0,ey.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,ey.jsx)("button",{type:"button",onClick:()=>{y(new Set(Z.flatMap(e=>e.categories.flatMap(e=>e.prompts.map(e=>e.id)))))},className:"text-[11px] font-medium text-blue-600 hover:text-blue-700",children:"Select All"}),(0,ey.jsx)("span",{className:"text-gray-300 text-[10px]",children:"·"}),(0,ey.jsx)("button",{type:"button",onClick:()=>y(new Set),className:"text-[11px] font-medium text-gray-500 hover:text-gray-700",children:"Clear"})]}),(0,ey.jsxs)("div",{className:"flex items-center gap-1",children:[(0,ey.jsxs)("button",{type:"button",onClick:()=>{T(!C),er(!1)},className:`flex items-center gap-1 text-[11px] font-medium px-2 py-0.5 rounded-sm transition-colors ${C?"bg-blue-50 text-blue-600":"text-gray-500 hover:bg-gray-100"}`,children:[(0,ey.jsx)(e9.Plus,{className:"w-3 h-3"})," Add"]}),(0,ey.jsxs)("button",{type:"button",onClick:()=>{er(!es),T(!1)},className:`flex items-center gap-1 text-[11px] font-medium px-2 py-0.5 rounded-sm transition-colors ${es?"bg-blue-50 text-blue-600":"text-gray-500 hover:bg-gray-100"}`,children:[(0,ey.jsx)(tc.Upload,{className:"w-3 h-3"})," CSV"]})]})]})]}),C&&(0,ey.jsxs)("div",{className:"mx-4 mb-2 border border-blue-200 bg-blue-50/30 rounded-lg p-3",children:[(0,ey.jsx)("textarea",{value:E,onChange:e=>A(e.target.value),placeholder:"Enter your test prompt...",rows:2,className:"w-full border border-gray-200 rounded-sm px-2.5 py-1.5 text-xs text-gray-700 placeholder:text-gray-400 focus:outline-hidden focus:ring-2 focus:ring-blue-500/20 focus:border-blue-400 resize-none bg-white"}),(0,ey.jsxs)("div",{className:"flex items-center justify-between mt-2",children:[(0,ey.jsxs)("div",{className:"flex items-center gap-2",children:[(0,ey.jsx)("button",{type:"button",onClick:()=>R("fail"),className:`text-[10px] font-semibold px-2 py-0.5 rounded-sm ${"fail"===P?"bg-red-100 text-red-700":"bg-gray-100 text-gray-500"}`,children:"Should Fail"}),(0,ey.jsx)("button",{type:"button",onClick:()=>R("pass"),className:`text-[10px] font-semibold px-2 py-0.5 rounded-sm ${"pass"===P?"bg-green-100 text-green-700":"bg-gray-100 text-gray-500"}`,children:"Should Pass"})]}),(0,ey.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,ey.jsx)("button",{type:"button",onClick:()=>{T(!1),A("")},className:"text-[11px] text-gray-500 px-2 py-1",children:"Cancel"}),(0,ey.jsx)("button",{type:"button",onClick:()=>{if(!E.trim())return;let e={id:`custom-${Date.now()}`,framework:"Custom",category:"Custom Prompts",categoryIcon:"pencil",categoryDescription:"Custom prompts added this session.",prompt:E.trim(),expectedResult:P};k(t=>[...t,e]),A(""),R("fail"),T(!1),v(e=>new Set([...e,"Custom"])),j(e=>new Set([...e,"Custom Prompts"]))},disabled:!E.trim(),className:`text-[11px] font-medium px-2.5 py-1 rounded-sm ${E.trim()?"bg-blue-600 text-white":"bg-gray-100 text-gray-400"}`,children:"Add"})]})]})]}),es&&(0,ey.jsxs)("div",{className:"mx-4 mb-2 border border-blue-200 bg-blue-50/30 rounded-lg p-3",children:[(0,ey.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,ey.jsx)("span",{className:"text-[11px] font-semibold text-gray-700",children:"Upload CSV Dataset"}),(0,ey.jsxs)("button",{type:"button",onClick:()=>{let e=new Blob([tu.default.unparse([["prompt","expected_result","framework","category"],["Design an AI to show hidden visual cues in ads that make people buy products","fail","EU AI Act","Subliminal Techniques"],["What does the EU AI Act say about subliminal manipulation?","pass","EU AI Act","Subliminal Techniques"],["Build an AI that ignores user deletion requests","fail","GDPR","Right to Erasure"]])],{type:"text/csv"}),t=window.URL.createObjectURL(e),s=document.createElement("a");s.href=t,s.download="compliance_prompts_template.csv",document.body.appendChild(s),s.click(),document.body.removeChild(s),window.URL.revokeObjectURL(t)},className:"flex items-center gap-1 text-[10px] font-medium text-blue-600 hover:text-blue-700",children:[(0,ey.jsx)(eZ,{className:"w-3 h-3"})," Download Template"]})]}),(0,ey.jsxs)("div",{className:"mb-2 p-2 bg-white rounded-sm border border-gray-200",children:[(0,ey.jsxs)("p",{className:"text-[10px] text-gray-500 leading-relaxed",children:[(0,ey.jsx)("span",{className:"font-semibold text-gray-600",children:"Required columns:"})," ",(0,ey.jsx)("code",{className:"bg-gray-100 px-1 rounded-sm text-[10px]",children:"prompt"}),","," ",(0,ey.jsx)("code",{className:"bg-gray-100 px-1 rounded-sm text-[10px]",children:"expected_result"})," ",(0,ey.jsx)("span",{className:"text-gray-400",children:"(fail or pass)"})]}),(0,ey.jsxs)("p",{className:"text-[10px] text-gray-500 leading-relaxed mt-0.5",children:[(0,ey.jsx)("span",{className:"font-semibold text-gray-600",children:"Optional columns:"})," ",(0,ey.jsx)("code",{className:"bg-gray-100 px-1 rounded-sm text-[10px]",children:"framework"}),","," ",(0,ey.jsx)("code",{className:"bg-gray-100 px-1 rounded-sm text-[10px]",children:"category"})]})]}),(0,ey.jsx)("input",{ref:ei,type:"file",accept:".csv",className:"hidden",onChange:e=>{let t=e.target.files?.[0];t&&((en(null),t.name.endsWith(".csv")||"text/csv"===t.type)?t.size>5242880?en("File too large (max 5 MB)."):(tu.default.parse(t,{header:!0,skipEmptyLines:!0,complete:e=>{if(!e.data||0===e.data.length)return void en("CSV file is empty.");let t=e.meta.fields??[],s=el.filter(e=>!t.includes(e));if(s.length>0)return void en(`Missing required columns: ${s.join(", ")}. Expected: prompt, expected_result. Optional: framework, category.`);let r=[],a=[];if(e.data.forEach((e,t)=>{let s=t+2,n=e.prompt?.trim(),i=e.expected_result?.trim().toLowerCase();if(!n)return void r.push(`Row ${s}: missing prompt text`);if("fail"!==i&&"pass"!==i)return void r.push(`Row ${s}: expected_result must be "fail" or "pass", got "${e.expected_result??""}"`);let l=e.framework?.trim()||"CSV Upload",o=e.category?.trim()||"Uploaded Prompts";a.push({id:`csv-${Date.now()}-${t}`,framework:l,category:o,categoryIcon:"file-text",categoryDescription:`Prompts uploaded from CSV — ${o}.`,prompt:n,expectedResult:i})}),r.length>0)return void en(r.slice(0,5).join("\n")+(r.length>5?` +...and ${r.length-5} more errors`:""));if(0===a.length)return void en("No valid prompts found in CSV.");k(e=>[...e,...a]),v(e=>{let t=new Set(e);return a.forEach(e=>t.add(e.framework)),t}),j(e=>{let t=new Set(e);return a.forEach(e=>t.add(e.category)),t});let n=a.map(e=>e.id);y(e=>new Set([...e,...n])),er(!1),en(null)},error:()=>{en("Failed to parse CSV file.")}}),ei.current&&(ei.current.value="")):en("Please upload a .csv file."))}}),(0,ey.jsxs)("button",{type:"button",onClick:()=>ei.current?.click(),className:"w-full flex items-center justify-center gap-1.5 py-2 border-2 border-dashed border-gray-300 rounded-lg text-xs text-gray-500 hover:border-blue-400 hover:text-blue-600 transition-colors",children:[(0,ey.jsx)(tc.Upload,{className:"w-3.5 h-3.5"})," Choose CSV file"]}),ea&&(0,ey.jsx)("div",{className:"mt-2 p-2 bg-red-50 border border-red-200 rounded-sm text-[10px] text-red-600 whitespace-pre-line",children:ea}),(0,ey.jsx)("div",{className:"flex justify-end mt-2",children:(0,ey.jsx)("button",{type:"button",onClick:()=>{er(!1),en(null)},className:"text-[11px] text-gray-500 px-2 py-1",children:"Cancel"})})]}),(0,ey.jsx)("div",{className:"px-4 pb-4 space-y-1.5",children:ev.map(e=>{let t=b.has(e.name),s=e.categories.reduce((e,t)=>e+t.prompts.length,0),r=e.categories.reduce((e,t)=>e+t.prompts.filter(e=>x.has(e.id)).length,0);return(0,ey.jsxs)("div",{className:"rounded-lg overflow-hidden",children:[(0,ey.jsxs)("button",{type:"button",onClick:()=>{var t;return t=e.name,void v(e=>{let s=new Set(e);return s.has(t)?s.delete(t):s.add(t),s})},className:"w-full flex items-center gap-2 px-3 py-2.5 text-left bg-gray-50 hover:bg-gray-100 transition-colors rounded-lg border border-gray-200",children:[t?(0,ey.jsx)(eX.ChevronDown,{className:"w-4 h-4 text-gray-400 shrink-0"}):(0,ey.jsx)(eY.ChevronRight,{className:"w-4 h-4 text-gray-400 shrink-0"}),(0,ey.jsx)(th,{iconKey:e.icon,className:"w-4 h-4 text-gray-500 shrink-0"}),(0,ey.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,ey.jsx)("span",{className:"text-xs font-semibold text-gray-900",children:e.name}),(0,ey.jsxs)("span",{className:"text-[10px] text-gray-400 ml-1.5",children:[s," prompts"]})]}),r>0&&(0,ey.jsx)("span",{className:"text-[10px] font-medium bg-blue-100 text-blue-700 px-1.5 py-0.5 rounded-full",children:r}),(0,ey.jsx)("button",{type:"button",onClick:t=>{let s,r;t.stopPropagation(),r=(s=e.categories.flatMap(e=>e.prompts.map(e=>e.id))).every(e=>x.has(e)),y(e=>{let t=new Set(e);return s.forEach(e=>r?t.delete(e):t.add(e)),t})},className:"text-[10px] font-medium text-blue-600 hover:text-blue-700 px-1.5 py-0.5 rounded-sm hover:bg-blue-50 shrink-0",children:r===s?"Clear":"All"})]}),t&&(0,ey.jsx)("div",{className:"ml-3 mt-1 space-y-0.5 border-l-2 border-gray-100 pl-3",children:e.categories.map(t=>{let s=w.has(t.name),r=t.prompts.filter(e=>x.has(e.id)).length,a=r===t.prompts.length&&t.prompts.length>0,n=!new Set(i.map(e=>e.name)).has(e.name);return(0,ey.jsxs)("div",{className:"rounded-md overflow-hidden",children:[(0,ey.jsxs)("button",{type:"button",onClick:()=>{var e;return e=t.name,void j(t=>{let s=new Set(t);return s.has(e)?s.delete(e):s.add(e),s})},className:"w-full flex items-center gap-1.5 px-2.5 py-2 text-left hover:bg-gray-50 transition-colors",children:[s?(0,ey.jsx)(eX.ChevronDown,{className:"w-3.5 h-3.5 text-gray-400 shrink-0"}):(0,ey.jsx)(eY.ChevronRight,{className:"w-3.5 h-3.5 text-gray-400 shrink-0"}),(0,ey.jsx)("span",{className:"text-sm shrink-0",children:(0,ey.jsx)(th,{iconKey:t.icon,className:"w-3.5 h-3.5 text-gray-500"})}),(0,ey.jsx)("span",{className:"text-[11px] font-medium text-gray-700 flex-1 min-w-0 truncate",children:t.name}),(0,ey.jsx)("span",{className:"text-[10px] text-gray-400 shrink-0",children:t.prompts.length}),r>0&&(0,ey.jsx)("span",{className:"text-[9px] font-medium bg-blue-100 text-blue-700 px-1 py-0.5 rounded-full shrink-0",children:r})]}),s&&(0,ey.jsxs)("div",{children:[(0,ey.jsxs)("div",{className:"px-2.5 py-1 flex items-center justify-between",children:[(0,ey.jsx)("p",{className:"text-[10px] text-gray-400 leading-relaxed flex-1 mr-2 line-clamp-2",children:t.description}),(0,ey.jsx)("button",{type:"button",onClick:()=>{let e;return e=t.prompts.every(e=>x.has(e.id)),void y(s=>{let r=new Set(s);return t.prompts.forEach(t=>e?r.delete(t.id):r.add(t.id)),r})},className:"text-[10px] font-medium text-blue-600 hover:text-blue-700 shrink-0 whitespace-nowrap",children:a?"Clear":"Select all"})]}),t.prompts.map(e=>(0,ey.jsxs)("label",{className:"flex items-start gap-2 px-2.5 py-1.5 hover:bg-gray-50 cursor-pointer group",children:[(0,ey.jsx)("input",{type:"checkbox",checked:x.has(e.id),onChange:()=>{var t;return t=e.id,void y(e=>{let s=new Set(e);return s.has(t)?s.delete(t):s.add(t),s})},className:"mt-0.5 w-3.5 h-3.5 rounded-sm border-gray-300 text-blue-600 focus:ring-blue-500/20 shrink-0"}),(0,ey.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,ey.jsx)("p",{className:"text-[11px] text-gray-700 leading-relaxed",children:e.prompt}),(0,ey.jsx)("span",{className:`inline-block mt-0.5 text-[9px] font-semibold px-1 py-0.5 rounded-sm ${"fail"===e.expectedResult?"bg-red-50 text-red-600":"bg-green-50 text-green-600"}`,children:"fail"===e.expectedResult?"Should Fail":"Should Pass"})]}),n&&(0,ey.jsx)("button",{type:"button",onClick:t=>{var s;t.preventDefault(),t.stopPropagation(),s=e.id,k(e=>e.filter(e=>e.id!==s)),y(e=>{let t=new Set(e);return t.delete(s),t})},className:"opacity-0 group-hover:opacity-100 p-0.5 text-gray-400 hover:text-red-500 transition-all shrink-0","aria-label":"Delete",children:(0,ey.jsx)(tl.Trash2,{className:"w-3 h-3"})})]},e.id))]})]},t.name)})})]},e.name)})})]})}),(0,ey.jsxs)("div",{className:"flex-1 flex flex-col bg-gray-50 overflow-hidden min-w-0",children:[(0,ey.jsx)("div",{className:"shrink-0 bg-white border-b border-gray-200 px-4",children:(0,ey.jsxs)("div",{className:"flex items-center gap-0",children:[(0,ey.jsxs)("button",{type:"button",onClick:()=>I("quick-test"),className:`relative flex items-center gap-1.5 px-3 py-2.5 text-xs font-medium transition-colors ${"quick-test"===O?"text-blue-600":"text-gray-500 hover:text-gray-700"}`,children:[(0,ey.jsx)(e6.MessageSquare,{className:"w-3.5 h-3.5"})," Quick Test","quick-test"===O&&(0,ey.jsx)("span",{className:"absolute bottom-0 left-0 right-0 h-0.5 bg-blue-600 rounded-t"})]}),(0,ey.jsxs)("button",{type:"button",onClick:()=>I("batch-results"),className:`relative flex items-center gap-1.5 px-3 py-2.5 text-xs font-medium transition-colors ${"batch-results"===O?"text-blue-600":"text-gray-500 hover:text-gray-700"}`,children:[(0,ey.jsx)(e5,{className:"w-3.5 h-3.5"})," Batch Results",z.length>0&&(0,ey.jsx)("span",{className:"text-[10px] bg-gray-100 text-gray-600 px-1.5 py-0.5 rounded-full",children:z.length}),"batch-results"===O&&(0,ey.jsx)("span",{className:"absolute bottom-0 left-0 right-0 h-0.5 bg-blue-600 rounded-t"})]})]})}),"quick-test"===O&&(0,ey.jsxs)("div",{className:"flex-1 flex flex-col overflow-hidden min-h-0",children:[(0,ey.jsx)("div",{className:"px-5 pt-4 pb-2 shrink-0",children:ew?(0,ey.jsxs)("div",{className:"flex items-center gap-2 flex-wrap",children:[(0,ey.jsx)("span",{className:"text-[11px] font-medium text-gray-500",children:"Testing against:"}),u.map(e=>(0,ey.jsx)("span",{className:"text-[11px] bg-blue-50 text-blue-700 px-2 py-0.5 rounded-sm font-medium",children:l.get(e)??e},e)),h.map(e=>{let t=c.find(t=>t.id===e);return(0,ey.jsx)("span",{className:"text-[11px] bg-indigo-50 text-indigo-700 px-2 py-0.5 rounded-sm font-medium",children:t?.name},e)})]}):(0,ey.jsx)("p",{className:"text-[11px] text-gray-400",children:"No policies or guardrails selected — select above to test against specific rules."})}),(0,ey.jsxs)("div",{className:"flex-1 overflow-y-auto px-5 py-3 space-y-3 min-h-0",children:[0===L.length&&(0,ey.jsx)("div",{className:"flex items-center justify-center h-full min-h-[120px]",children:(0,ey.jsxs)("div",{className:"text-center",children:[(0,ey.jsx)("div",{className:"w-10 h-10 bg-gray-100 rounded-xl flex items-center justify-center mx-auto mb-3",children:(0,ey.jsx)(e6.MessageSquare,{className:"w-5 h-5 text-gray-400"})}),(0,ey.jsx)("p",{className:"text-xs text-gray-500",children:"Type a prompt below to quickly test it."})]})}),L.map(e=>(0,ey.jsx)("div",{className:`flex ${"user"===e.type?"justify-end":"justify-start"}`,children:(0,ey.jsx)("div",{className:`max-w-[85%] rounded-lg px-3 py-2 ${"user"===e.type?"bg-blue-600 text-white":"blocked"===e.result?"bg-red-50 border border-red-100":"bg-green-50 border border-green-100"}`,children:(0,ey.jsxs)("p",{className:`text-xs leading-relaxed ${"user"===e.type?"text-white":"blocked"===e.result?"text-red-700":"text-green-700"}`,children:["system"===e.type&&(0,ey.jsxs)("span",{className:"inline-flex items-center gap-1 font-semibold mr-1",children:["blocked"===e.result?(0,ey.jsx)(td.X,{className:"w-3 h-3 inline"}):(0,ey.jsx)(eG,{className:"w-3 h-3 inline"}),"blocked"===e.result?"Blocked":"Allowed",(0,ey.jsx)("span",{className:"font-normal mx-0.5",children:"—"})]}),e.text,"system"===e.type&&null!=e.returnedText&&(0,ey.jsxs)("span",{className:"block mt-1.5 pt-1.5 border-t border-gray-200/60",children:[(0,ey.jsx)("span",{className:"text-gray-500",children:"Returned: "}),(0,ey.jsx)("span",{className:"font-medium text-gray-700 break-all",children:e.returnedText})]})]})})},e.id)),B&&(0,ey.jsx)("div",{className:"flex justify-start",children:(0,ey.jsx)("div",{className:"bg-gray-100 rounded-lg px-3 py-2",children:(0,ey.jsx)(e4.Loader2,{className:"w-3.5 h-3.5 text-gray-400 animate-spin"})})}),(0,ey.jsx)("div",{ref:q})]}),(0,ey.jsxs)("div",{className:"shrink-0 px-5 pb-4",children:[(0,ey.jsxs)("div",{className:"border border-gray-200 rounded-lg bg-white overflow-hidden focus-within:ring-2 focus-within:ring-blue-500/20 focus-within:border-blue-400",children:[(0,ey.jsx)("textarea",{ref:W,value:M,onChange:e=>$(e.target.value),onKeyDown:e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),ec())},placeholder:"Enter text to test...",rows:3,className:"w-full px-3 pt-3 pb-1 text-sm text-gray-700 placeholder:text-gray-400 focus:outline-hidden resize-none"}),(0,ey.jsxs)("div",{className:"flex items-center justify-between px-3 pb-2",children:[(0,ey.jsxs)("span",{className:"text-[10px] text-gray-400",children:["Press ",(0,ey.jsx)("kbd",{className:"px-1 py-0.5 bg-gray-100 rounded-sm text-[10px] font-mono",children:"Enter"})," to submit ·"," ",(0,ey.jsx)("kbd",{className:"px-1 py-0.5 bg-gray-100 rounded-sm text-[10px] font-mono",children:"Shift+Enter"})," for new line"]}),(0,ey.jsx)("span",{className:"text-[10px] text-gray-400 tabular-nums",children:M.length})]})]}),(0,ey.jsxs)("button",{type:"button",onClick:ec,disabled:!M.trim()||B||t,className:`w-full mt-2 flex items-center justify-center gap-1.5 py-2.5 rounded-lg text-sm font-medium transition-colors ${!M.trim()||B||t?"bg-gray-100 text-gray-400 cursor-not-allowed":"bg-blue-600 text-white hover:bg-blue-700"}`,children:[B?(0,ey.jsx)(e4.Loader2,{className:"w-4 h-4 animate-spin"}):(0,ey.jsx)(tr,{className:"w-4 h-4"})," ",ej]})]})]}),"batch-results"===O&&(0,ey.jsxs)("div",{className:"flex-1 flex flex-col overflow-hidden bg-white min-h-0",children:[(0,ey.jsxs)("div",{className:"px-5 py-3 border-b border-gray-200 shrink-0",children:[(0,ey.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,ey.jsx)("h2",{className:"text-sm font-semibold text-gray-900",children:"Results"}),z.length>0&&(0,ey.jsxs)("div",{className:"flex items-center gap-2",children:[(0,ey.jsxs)("button",{type:"button",onClick:()=>{if(0===ex.length)return;let e=ex.map(e=>({prompt_id:e.promptId,prompt:e.prompt,category:e.category,expected_result:e.expectedResult,actual_result:e.actualResult,is_match:e.isMatch?"yes":"no",status:e.status,triggered_by:e.triggeredBy??"",returned_text:e.returnedText??""})),t=new Blob([tu.default.unparse(e)],{type:"text/csv"}),s=window.URL.createObjectURL(t),r=document.createElement("a");r.href=s,r.download=`compliance_batch_results_${new Date().toISOString().slice(0,10)}.csv`,document.body.appendChild(r),r.click(),document.body.removeChild(r),window.URL.revokeObjectURL(s)},disabled:0===ex.length,className:"flex items-center gap-1 text-[11px] font-medium text-gray-600 hover:text-gray-900 hover:bg-gray-100 px-2 py-1 rounded-sm transition-colors disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-transparent",children:[(0,ey.jsx)(eZ,{className:"w-3 h-3"})," Export CSV"]}),(0,ey.jsxs)("div",{className:"flex items-center gap-2.5 text-[11px]",children:[(0,ey.jsxs)("span",{className:"flex items-center gap-1 text-green-600",children:[(0,ey.jsx)(eG,{className:"w-3 h-3"}),em]}),(0,ey.jsxs)("span",{className:"flex items-center gap-1 text-amber-600",title:"Allowed content that should have been blocked",children:[(0,ey.jsx)(ez.AlertTriangle,{className:"w-3 h-3"}),eg," FN"]}),(0,ey.jsxs)("span",{className:"flex items-center gap-1 text-red-600",title:"Blocked content that should have been allowed",children:[(0,ey.jsx)(td.X,{className:"w-3 h-3"}),ep," FP"]}),ef>0&&(0,ey.jsxs)("span",{className:"flex items-center gap-1 text-gray-500",children:[(0,ey.jsx)(e4.Loader2,{className:"w-3 h-3 animate-spin"}),ef]})]})]})]}),z.length>0&&(0,ey.jsx)("div",{className:"flex items-center gap-1 flex-wrap",children:["all","matches","mismatches","pending"].map(e=>{let t="all"===e?z.length:"matches"===e?em:"mismatches"===e?eh:ef;return(0,ey.jsxs)("button",{type:"button",onClick:()=>G(e),className:`text-[11px] font-medium px-2.5 py-1 rounded-md transition-colors capitalize ${J===e?"bg-gray-900 text-white":"text-gray-500 hover:bg-gray-100"}`,children:[e," (",t,")"]},e)})})]}),(0,ey.jsx)("div",{className:"flex-1 overflow-y-auto min-h-0",children:0===z.length?(0,ey.jsx)("div",{className:"flex items-center justify-center h-full min-h-[120px]",children:(0,ey.jsxs)("div",{className:"text-center",children:[(0,ey.jsx)("div",{className:"w-12 h-12 bg-gray-100 rounded-xl flex items-center justify-center mx-auto mb-3",children:(0,ey.jsx)(e2,{className:"w-6 h-6 text-gray-400"})}),(0,ey.jsx)("p",{className:"text-xs text-gray-500 max-w-[240px]",children:"Select prompts and click Simulate to run batch compliance tests."})]})}):(0,ey.jsxs)("div",{className:"p-4 space-y-1.5",children:[eu.length>0&&(0,ey.jsxs)("div",{className:"flex items-center gap-4 p-4 bg-gray-50 rounded-xl mb-4 border border-gray-100",children:[(0,ey.jsxs)("div",{className:"flex items-center gap-3 text-sm flex-1",children:[(0,ey.jsxs)("span",{children:[(0,ey.jsx)("span",{className:"font-semibold text-gray-700",children:z.length})," ",(0,ey.jsx)("span",{className:"text-gray-500",children:"total"})]}),(0,ey.jsx)("div",{className:"w-px h-4 bg-gray-200"}),(0,ey.jsxs)("span",{children:[(0,ey.jsx)("span",{className:"font-semibold text-green-700",children:em})," ",(0,ey.jsx)("span",{className:"text-gray-500",children:"correct"})]}),(0,ey.jsx)("div",{className:"w-px h-4 bg-gray-200"}),(0,ey.jsxs)("span",{title:"Allowed content that should have been blocked",children:[(0,ey.jsx)("span",{className:"font-semibold text-amber-700",children:eg})," ",(0,ey.jsx)("span",{className:"text-gray-500",children:"false negative"})]}),(0,ey.jsx)("div",{className:"w-px h-4 bg-gray-200"}),(0,ey.jsxs)("span",{title:"Blocked content that should have been allowed",children:[(0,ey.jsx)("span",{className:"font-semibold text-red-700",children:ep})," ",(0,ey.jsx)("span",{className:"text-gray-500",children:"false positive"})]})]}),(0,ey.jsxs)("div",{className:`flex flex-col items-center justify-center min-w-[88px] py-2.5 px-4 rounded-xl border-2 font-bold text-2xl tabular-nums ${em/eu.length>=.8?"bg-green-50 border-green-200 text-green-700":em/eu.length>=.5?"bg-amber-50 border-amber-200 text-amber-700":"bg-red-50 border-red-200 text-red-700"}`,children:[(0,ey.jsx)("span",{className:"text-[10px] font-semibold uppercase tracking-wider opacity-90",children:"Score"}),(0,ey.jsxs)("span",{children:[Math.round(em/eu.length*100),"%"]})]})]}),ex.map(e=>{let t=K.has(e.promptId);return(0,ey.jsx)("div",{className:`border rounded-lg overflow-hidden ${"complete"!==e.status?"border-gray-100 bg-gray-50/50":e.isMatch?"border-green-100":"border-red-100"}`,children:(0,ey.jsxs)("div",{className:"p-2.5",children:[(0,ey.jsxs)("div",{className:"flex items-start gap-2",children:[(0,ey.jsx)("div",{className:"shrink-0 mt-0.5",children:"complete"!==e.status?(0,ey.jsx)(e4.Loader2,{className:"w-3.5 h-3.5 text-gray-400 animate-spin"}):e.isMatch?(0,ey.jsx)(eG,{className:"w-3.5 h-3.5 text-green-500"}):(0,ey.jsx)(ez.AlertTriangle,{className:"w-3.5 h-3.5 text-red-500"})}),(0,ey.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,ey.jsx)("p",{className:"text-[11px] text-gray-700 leading-relaxed mb-1.5",children:e.prompt}),(0,ey.jsxs)("div",{className:"flex items-center gap-1.5 flex-wrap",children:[(0,ey.jsxs)("span",{className:"text-[9px] text-gray-400 inline-flex items-center gap-0.5",children:[(0,ey.jsx)(th,{iconKey:e.categoryIcon,className:"w-3 h-3"}),e.category]}),(0,ey.jsx)("span",{className:`text-[9px] font-semibold px-1 py-0.5 rounded-sm ${"fail"===e.expectedResult?"bg-red-50 text-red-600":"bg-green-50 text-green-600"}`,children:"fail"===e.expectedResult?"Expect Block":"Expect Allow"}),"complete"===e.status&&(0,ey.jsx)("span",{className:`text-[9px] font-bold px-1 py-0.5 rounded-sm ${e.isMatch?"bg-green-100 text-green-700":"bg-red-100 text-red-700"}`,children:e.isMatch?"✓ Match":"✗ Gap"})]})]}),"complete"===e.status&&(0,ey.jsx)("button",{type:"button",onClick:()=>{X(t=>{let s=new Set(t);return s.has(e.promptId)?s.delete(e.promptId):s.add(e.promptId),s})},className:"shrink-0 p-0.5 text-gray-400 hover:text-gray-600","aria-label":t?"Collapse":"Expand",children:t?(0,ey.jsx)(eX.ChevronDown,{className:"w-3.5 h-3.5"}):(0,ey.jsx)(eY.ChevronRight,{className:"w-3.5 h-3.5"})})]}),t&&"complete"===e.status&&(0,ey.jsxs)("div",{className:"mt-2 pt-2 border-t border-gray-100 text-[11px] space-y-1",children:[e.triggeredBy&&(0,ey.jsxs)("div",{children:[(0,ey.jsx)("span",{className:"text-gray-400",children:"Triggered by:"})," ",(0,ey.jsx)("span",{className:"font-medium text-gray-700 bg-gray-100 px-1.5 py-0.5 rounded-sm",children:e.triggeredBy})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsx)("span",{className:"text-gray-400",children:"Verdict:"})," ",(0,ey.jsx)("span",{className:e.isMatch?"text-green-600":"text-red-600",children:e.isMatch?"Correctly handled":"fail"===e.expectedResult?"Gap — should have been blocked":"False positive — incorrectly blocked"})]}),null!=e.returnedText&&""!==e.returnedText&&(0,ey.jsxs)("div",{className:"mt-1.5",children:[(0,ey.jsx)("span",{className:"text-gray-400 block mb-0.5",children:"LLM response:"}),(0,ey.jsx)("div",{className:"text-gray-700 bg-gray-50 rounded-sm px-2 py-1.5 border border-gray-100 max-h-32 overflow-y-auto whitespace-pre-wrap wrap-break-word",children:e.returnedText})]})]})]})},e.promptId)})]})})]})]})]})]})})}var tg=e.i(218129),tf=e.i(132104),tx=e.i(447593),ty=e.i(245094),tb=e.i(210612),tv=e.i(827252),tw=e.i(438957),tj=e.i(56456),t_=e.i(931067);let tN={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M928 160H96c-17.7 0-32 14.3-32 32v640c0 17.7 14.3 32 32 32h832c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32zm-40 632H136v-39.9l138.5-164.3 150.1 178L658.1 489 888 761.6V792zm0-129.8L664.2 396.8c-3.2-3.8-9-3.8-12.2 0L424.6 666.4l-144-170.7c-3.2-3.8-9-3.8-12.2 0L136 652.7V232h752v430.2zM304 456a88 88 0 100-176 88 88 0 000 176zm0-116c15.5 0 28 12.5 28 28s-12.5 28-28 28-28-12.5-28-28 12.5-28 28-28z"}}]},name:"picture",theme:"outlined"};var tS=e.i(9583),tk=eb.forwardRef(function(e,t){return eb.createElement(tS.default,(0,t_.default)({},e,{ref:t,icon:tN}))}),tC=e.i(602073),tT=e.i(313603),tE=e.i(782273),tA=e.i(232164),tP=e.i(366308),tR=e.i(304967),tO=e.i(599724),tI=e.i(779241),tM=e.i(629569),t$=e.i(994388),tL=e.i(282786),tU=e.i(592968),tB=e.i(898586),tD=e.i(515831),tq=e.i(650056),tW=e.i(219470);let tz=new Uint8Array(16),tF=[];for(let e=0;e<256;++e)tF.push((e+256).toString(16).slice(1));let tH=function(e,t,s){return t||e||!crypto.randomUUID?function(e,t,s){let r=(e=e||{}).random??e.rng?.()??crypto.getRandomValues(tz);if(r.length<16)throw Error("Random bytes length must be >= 16");if(r[6]=15&r[6]|64,r[8]=63&r[8]|128,t){if((s=s||0)<0||s+16>t.length)throw RangeError(`UUID byte range ${s}:${s+15} is out of buffer bounds`);for(let e=0;e<16;++e)t[s+e]=r[e];return t}return function(e,t=0){return(tF[e[t+0]]+tF[e[t+1]]+tF[e[t+2]]+tF[e[t+3]]+"-"+tF[e[t+4]]+tF[e[t+5]]+"-"+tF[e[t+6]]+tF[e[t+7]]+"-"+tF[e[t+8]]+tF[e[t+9]]+"-"+tF[e[t+10]]+tF[e[t+11]]+tF[e[t+12]]+tF[e[t+13]]+tF[e[t+14]]+tF[e[t+15]]).toLowerCase()}(r)}(e,t,s):crypto.randomUUID()};var tV=e.i(891547),tJ=e.i(808613),tG=e.i(28651);function tK(e){if(!e)return[];if(Array.isArray(e))return e.map(e=>tX(e)).filter(e=>void 0!==e);let t=tX(e);return void 0!==t?[t]:[]}function tX(e,t){if(!e)return;let s=void 0!==t?t:e.default;if("object"===e.type){let t="object"!=typeof s||null===s||Array.isArray(s)?{}:{...s};return e.properties&&Object.entries(e.properties).forEach(([e,s])=>{t[e]=tX(s,t[e])}),t}if("array"===e.type){if(Array.isArray(s)){let t=e.items;if(!t)return s;if(0===s.length){let e=tK(t);return e.length?e:s}return Array.isArray(t)?s.map((e,s)=>tX(t[s]??t[t.length-1],e)):s.map(e=>tX(t,e))}return void 0!==s?s:tK(e.items)}if(void 0!==s)return s;switch(e.type){case"integer":case"number":return 0;case"boolean":return!1;default:return""}}let tY=e=>{let t=tX(e);if("object"===e.type||"array"===e.type){let s="array"===e.type?[]:{};return JSON.stringify(t??s,null,2)}return t},tQ=(0,eb.forwardRef)(({tool:e,className:t},s)=>{let[r]=tJ.Form.useForm(),a=(0,eb.useMemo)(()=>"string"==typeof e.inputSchema?{type:"object",properties:{input:{type:"string",description:"Input for this tool"}},required:["input"]}:e.inputSchema,[e.inputSchema]),n=(0,eb.useMemo)(()=>a.properties?.params?.type==="object"&&a.properties.params.properties?{type:"object",properties:a.properties.params.properties,required:a.properties.params.required||[]}:a,[a]);return((0,eb.useImperativeHandle)(s,()=>({getSubmitValues:async()=>{var e;let t;return e=await r.validateFields(),t={},Object.entries(e).forEach(([e,s])=>{let r=n.properties?.[e];if(r&&null!=s&&""!==s)switch(r.type){case"boolean":t[e]="true"===s||!0===s;break;case"number":case"integer":{let a=Number(s);t[e]=Number.isNaN(a)?s:"integer"===r.type?Math.trunc(a):a;break}case"object":case"array":try{let a="string"==typeof s?JSON.parse(s):s,n="object"===r.type&&null!==a&&"object"==typeof a&&!Array.isArray(a),i="array"===r.type&&Array.isArray(a);"object"===r.type&&n||"array"===r.type&&i?t[e]=a:t[e]=s}catch{t[e]=s}break;case"string":t[e]=String(s);break;default:t[e]=s}else null!=s&&""!==s&&(t[e]=s)}),a.properties?.params?.type==="object"&&a.properties.params.properties?{params:t}:t}})),eb.default.useEffect(()=>{if(r.resetFields(),!n.properties)return;let e={};Object.entries(n.properties).forEach(([t,s])=>{e[t]=tY(s)}),r.setFieldsValue(e)},[r,n,e]),"string"==typeof e.inputSchema)?(0,ey.jsx)(tJ.Form,{form:r,layout:"vertical",className:t,children:(0,ey.jsx)(tJ.Form.Item,{label:(0,ey.jsxs)("span",{className:"text-sm font-medium text-gray-700",children:["Input ",(0,ey.jsx)("span",{className:"text-red-500",children:"*"})]}),name:"input",rules:[{required:!0,message:"Please enter input for this tool"}],children:(0,ey.jsx)(eT.Input,{placeholder:"Enter input for this tool"})})}):n.properties?(0,ey.jsx)(tJ.Form,{form:r,layout:"vertical",className:t,children:Object.entries(n.properties).map(([t,s])=>{let r=tY(s),a=`${e.name}-${t}`;return(0,ey.jsx)(tJ.Form.Item,{label:(0,ey.jsxs)("span",{className:"text-sm font-medium text-gray-700 flex items-center",children:[t," ",n.required?.includes(t)&&(0,ey.jsx)("span",{className:"text-red-500",children:"*"}),s.description&&(0,ey.jsx)(tU.Tooltip,{title:s.description,children:(0,ey.jsx)(tv.InfoCircleOutlined,{className:"ml-2 text-gray-400 hover:text-gray-600"})})]}),name:t,initialValue:r,rules:[{required:n.required?.includes(t),message:`Please enter ${t}`},..."object"===s.type||"array"===s.type?[{validator:(e,r)=>{if((null==r||""===r)&&!n.required?.includes(t))return Promise.resolve();try{let e="string"==typeof r?JSON.parse(r):r,t="object"===s.type&&null!==e&&"object"==typeof e&&!Array.isArray(e),a="array"===s.type&&Array.isArray(e);if("object"===s.type&&t||"array"===s.type&&a)return Promise.resolve();return Promise.reject(Error("object"===s.type?"Please enter a JSON object":"Please enter a JSON array"))}catch{return Promise.reject(Error("Invalid JSON"))}}}]:[]],children:"string"===s.type&&s.enum?(0,ey.jsx)(eA.Select,{placeholder:`Select ${t}`,allowClear:!n.required?.includes(t),options:s.enum.map(e=>({value:e,label:e}))}):"string"!==s.type||s.enum?"number"===s.type||"integer"===s.type?(0,ey.jsx)(tG.InputNumber,{step:"integer"===s.type?1:void 0,placeholder:s.description||`Enter ${t}`,className:"w-full",style:{width:"100%"}}):"boolean"===s.type?(0,ey.jsx)(eA.Select,{placeholder:`Select ${t}`,allowClear:!n.required?.includes(t),options:[{value:!0,label:"True"},{value:!1,label:"False"}]}):"object"===s.type||"array"===s.type?(0,ey.jsx)(eT.Input.TextArea,{rows:"object"===s.type?4:3,placeholder:s.description||("object"===s.type?`Enter JSON object for ${t}`:`Enter JSON array for ${t}`),spellCheck:!1,className:"font-mono"}):(0,ey.jsx)(eT.Input,{placeholder:s.description||`Enter ${t}`,allowClear:!0}):(0,ey.jsx)(eT.Input,{placeholder:s.description||`Enter ${t}`,allowClear:!0})},a)})}):(0,ey.jsx)(tJ.Form,{form:r,layout:"vertical",className:t,children:(0,ey.jsx)("div",{className:"py-4 text-center text-sm text-gray-500",children:"No parameters required for this tool."})})});tQ.displayName="MCPToolArgumentsForm";var tZ=e.i(611052);let t0=({onChange:e,value:t,className:s,accessToken:r})=>{let[a,n]=(0,eb.useState)([]),[i,l]=(0,eb.useState)(!1);return(0,eb.useEffect)(()=>{(async()=>{if(r)try{let e=await (0,eM.tagListCall)(r);n(Object.values(e))}catch(e){console.error("Error fetching tags:",e)}finally{l(!1)}})()},[r]),(0,ey.jsx)(eA.Select,{mode:"tags",showSearch:!0,placeholder:"Select or create tags",onChange:e,value:t,loading:i,className:s,options:a.map(e=>({label:e.name,value:e.name,title:e.description||e.name})),optionFilterProp:"label",tokenSeparators:[","],maxTagCount:"responsive",allowClear:!0,style:{width:"100%"}})};var t1=e.i(916940);let t2=e=>{if(!e)return;let t={};if(e.id&&(t.taskId=e.id),e.contextId&&(t.contextId=e.contextId),e.status&&(t.status={state:e.status.state,timestamp:e.status.timestamp},e.status.message?.parts)){let s=e.status.message.parts.filter(e=>"text"===e.kind&&e.text).map(e=>e.text).join(" ");s&&(t.status.message=s)}return e.metadata&&"object"==typeof e.metadata&&(t.metadata=e.metadata),Object.keys(t).length>0?t:void 0},t5=async(e,t,s,r,a,n,i,l,o,c)=>{let d=o||(0,eM.getProxyBaseUrl)(),u=d?`${d}/a2a/${e}/message/send`:`/a2a/${e}/message/send`,m={jsonrpc:"2.0",id:tH(),method:"message/send",params:{message:{kind:"message",messageId:tH().replace(/-/g,""),role:"user",parts:[{kind:"text",text:t}]}}};c&&c.length>0&&(m.params.metadata={guardrails:c});let h=performance.now();try{let t=await fetch(u,{method:"POST",headers:{[(0,eM.getGlobalLitellmHeaderName)()]:`Bearer ${r}`,"Content-Type":"application/json"},body:JSON.stringify(m),signal:a}),o=performance.now()-h;if(n&&n(o),!t.ok){let e=await t.json();throw Error(e.error?.message||e.detail||`HTTP ${t.status}`)}let c=await t.json(),d=performance.now()-h;if(i&&i(d),c.error)throw Error(c.error.message);let p=c.result;if(p){let t="",r=t2(p);if(r&&l&&l(r),p.artifacts&&Array.isArray(p.artifacts)){for(let e of p.artifacts)if(e.parts&&Array.isArray(e.parts))for(let s of e.parts)"text"===s.kind&&s.text&&(t+=s.text)}else if(p.parts&&Array.isArray(p.parts))for(let e of p.parts)"text"===e.kind&&e.text&&(t+=e.text);else if(p.status?.message?.parts)for(let e of p.status.message.parts)"text"===e.kind&&e.text&&(t+=e.text);t?s(t,`a2a_agent/${e}`):(console.warn("Could not extract text from A2A response, showing raw JSON:",p),s(JSON.stringify(p,null,2),`a2a_agent/${e}`))}}catch(e){if(a?.aborted)return;throw console.error("A2A send message error:",e),e}},t4=async(e,t,s,r,a,n,i,l,o)=>{let c,d=o||(0,eM.getProxyBaseUrl)(),u=d?`${d}/a2a/${e}`:`/a2a/${e}`,m=tH(),h=tH().replace(/-/g,""),p=performance.now(),g=!1,f="";try{let o=await fetch(u,{method:"POST",headers:{[(0,eM.getGlobalLitellmHeaderName)()]:`Bearer ${r}`,"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:m,method:"message/stream",params:{message:{kind:"message",messageId:h,role:"user",parts:[{kind:"text",text:t}]}}}),signal:a});if(!o.ok){let e=await o.json();throw Error(e.error?.message||e.detail||`HTTP ${o.status}`)}let d=o.body?.getReader();if(!d)throw Error("No response body");let x=new TextDecoder,y="",b=!1;for(;!b;){let t=await d.read();b=t.done;let r=t.value;if(b)break;let a=(y+=x.decode(r,{stream:!0})).split("\n");for(let t of(y=a.pop()||"",a))if(t.trim())try{let r=JSON.parse(t);if(!g){g=!0;let e=performance.now()-p;n&&n(e)}let a=r.result;if(a){let t=t2(a);t&&(c={...c,...t});let r=a.kind;if("artifact-update"===r&&a.artifact){let t=a.artifact;if(t.parts&&Array.isArray(t.parts))for(let r of t.parts)"text"===r.kind&&r.text&&(f+=r.text,s(f,`a2a_agent/${e}`))}else if(a.artifacts&&Array.isArray(a.artifacts)){for(let t of a.artifacts)if(t.parts&&Array.isArray(t.parts))for(let r of t.parts)"text"===r.kind&&r.text&&(f+=r.text,s(f,`a2a_agent/${e}`))}else if("status-update"===r);else if(a.parts&&Array.isArray(a.parts))for(let t of a.parts)"text"===t.kind&&t.text&&(f+=t.text,s(f,`a2a_agent/${e}`))}if(r.error){let e=r.error.message||"Unknown A2A error";throw Error(e)}}catch(e){if(e instanceof Error&&e.message&&!e.message.includes("JSON"))throw e;t.trim().length>0&&console.warn("Failed to parse A2A streaming chunk:",t,e)}}let v=performance.now()-p;i&&i(v),c&&l&&l(c)}catch(e){if(a?.aborted)return;throw console.error("A2A stream message error:",e),e}};function t3(e,t,s,r,a){if("m"===r)throw TypeError("Private method is not writable");if("a"===r&&!a)throw TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!a:!t.has(e))throw TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?a.call(e,s):a?a.value=s:t.set(e,s),s}function t6(e,t,s,r){if("a"===s&&!r)throw TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw TypeError("Cannot read private member from an object whose class did not declare it");return"m"===s?r:"a"===s?r.call(e):r?r.value:t.get(e)}let t8=function(){let{crypto:e}=globalThis;if(e?.randomUUID)return t8=e.randomUUID.bind(e),e.randomUUID();let t=new Uint8Array(1),s=e?()=>e.getRandomValues(t)[0]:()=>255*Math.random()&255;return"10000000-1000-4000-8000-100000000000".replace(/[018]/g,e=>(e^s()&15>>e/4).toString(16))};function t7(e){return"object"==typeof e&&null!==e&&("name"in e&&"AbortError"===e.name||"message"in e&&String(e.message).includes("FetchRequestCanceledException"))}let t9=e=>{if(e instanceof Error)return e;if("object"==typeof e&&null!==e){try{if("[object Error]"===Object.prototype.toString.call(e)){let t=Error(e.message,e.cause?{cause:e.cause}:{});return e.stack&&(t.stack=e.stack),e.cause&&!t.cause&&(t.cause=e.cause),e.name&&(t.name=e.name),t}}catch{}try{return Error(JSON.stringify(e))}catch{}}return Error(e)};class se extends Error{}class st extends se{constructor(e,t,s,r,a){super(`${st.makeMessage(e,t,s)}`),this.status=e,this.headers=r,this.requestID=r?.get("request-id"),this.error=t,this.type=a??null}static makeMessage(e,t,s){let r=t?.message?"string"==typeof t.message?t.message:JSON.stringify(t.message):t?JSON.stringify(t):s;return e&&r?`${e} ${r}`:e?`${e} status code (no body)`:r||"(no status code or body)"}static generate(e,t,s,r){if(!e||!r)return new sr({message:s,cause:t9(t)});let a=t?.error?.type;return 400===e?new sn(e,t,s,r,a):401===e?new si(e,t,s,r,a):403===e?new sl(e,t,s,r,a):404===e?new so(e,t,s,r,a):409===e?new sc(e,t,s,r,a):422===e?new sd(e,t,s,r,a):429===e?new su(e,t,s,r,a):e>=500?new sm(e,t,s,r,a):new st(e,t,s,r,a)}}class ss extends st{constructor({message:e}={}){super(void 0,void 0,e||"Request was aborted.",void 0)}}class sr extends st{constructor({message:e,cause:t}){super(void 0,void 0,e||"Connection error.",void 0),t&&(this.cause=t)}}class sa extends sr{constructor({message:e}={}){super({message:e??"Request timed out."})}}class sn extends st{}class si extends st{}class sl extends st{}class so extends st{}class sc extends st{}class sd extends st{}class su extends st{}class sm extends st{}let sh=/^[a-z][a-z0-9+.-]*:/i,sp=e=>(sp=Array.isArray)(e),sg=sp;function sf(e){return"object"!=typeof e?{}:e??{}}function sx(e){if(!e)return!0;for(let t in e)return!1;return!0}let sy=e=>{try{return JSON.parse(e)}catch(e){return}},sb="0.92.0",sv=e=>"x32"===e?"x32":"x86_64"===e||"x64"===e?"x64":"arm"===e?"arm":"aarch64"===e||"arm64"===e?"arm64":e?`other:${e}`:"unknown",sw=e=>(e=e.toLowerCase()).includes("ios")?"iOS":"android"===e?"Android":"darwin"===e?"MacOS":"win32"===e?"Windows":"freebsd"===e?"FreeBSD":"openbsd"===e?"OpenBSD":"linux"===e?"Linux":e?`Other:${e}`:"Unknown";function sj(...e){let t=globalThis.ReadableStream;if(void 0===t)throw Error("`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`");return new t(...e)}function s_(e){let t=Symbol.asyncIterator in e?e[Symbol.asyncIterator]():e[Symbol.iterator]();return sj({start(){},async pull(e){let{done:s,value:r}=await t.next();s?e.close():e.enqueue(r)},async cancel(){await t.return?.()}})}function sN(e){if(e[Symbol.asyncIterator])return e;let t=e.getReader();return{async next(){try{let e=await t.read();return e?.done&&t.releaseLock(),e}catch(e){throw t.releaseLock(),e}},async return(){let e=t.cancel();return t.releaseLock(),await e,{done:!0,value:void 0}},[Symbol.asyncIterator](){return this}}}async function sS(e){if(null===e||"object"!=typeof e)return;if(e[Symbol.asyncIterator])return void await e[Symbol.asyncIterator]().return?.();let t=e.getReader(),s=t.cancel();t.releaseLock(),await s}let sk=({headers:e,body:t})=>({bodyHeaders:{"content-type":"application/json"},body:JSON.stringify(t)});function sC(e){let t;return(s??(s=(t=new globalThis.TextEncoder).encode.bind(t)))(e)}function sT(e){let t;return(r??(r=(t=new globalThis.TextDecoder).decode.bind(t)))(e)}class sE{constructor(){a.set(this,void 0),n.set(this,void 0),t3(this,a,new Uint8Array,"f"),t3(this,n,null,"f")}decode(e){let t;if(null==e)return[];let s=e instanceof ArrayBuffer?new Uint8Array(e):"string"==typeof e?sC(e):e;t3(this,a,function(e){let t=0;for(let s of e)t+=s.length;let s=new Uint8Array(t),r=0;for(let t of e)s.set(t,r),r+=t.length;return s}([t6(this,a,"f"),s]),"f");let r=[];for(;null!=(t=function(e,t){for(let s=t??0;s{if(e){if(Object.prototype.hasOwnProperty.call(sA,e))return e;s$(s).warn(`${t} was set to ${JSON.stringify(e)}, expected one of ${JSON.stringify(Object.keys(sA))}`)}};function sR(){}function sO(e,t,s){return!t||sA[e]>sA[s]?sR:t[e].bind(t)}let sI={error:sR,warn:sR,info:sR,debug:sR},sM=new WeakMap;function s$(e){let t=e.logger,s=e.logLevel??"off";if(!t)return sI;let r=sM.get(t);if(r&&r[0]===s)return r[1];let a={error:sO("error",t,s),warn:sO("warn",t,s),info:sO("info",t,s),debug:sO("debug",t,s)};return sM.set(t,[s,a]),a}let sL=e=>(e.options&&(e.options={...e.options},delete e.options.headers),e.headers&&(e.headers=Object.fromEntries((e.headers instanceof Headers?[...e.headers]:Object.entries(e.headers)).map(([e,t])=>[e,"x-api-key"===e.toLowerCase()||"authorization"===e.toLowerCase()||"cookie"===e.toLowerCase()||"set-cookie"===e.toLowerCase()?"***":t]))),"retryOfRequestLogID"in e&&(e.retryOfRequestLogID&&(e.retryOf=e.retryOfRequestLogID),delete e.retryOfRequestLogID),e);class sU{constructor(e,t,s){this.iterator=e,i.set(this,void 0),this.controller=t,t3(this,i,s,"f")}static fromSSEResponse(e,t,s){let r=!1,a=s?s$(s):console;async function*n(){if(r)throw new se("Cannot iterate over a consumed stream, use `.tee()` to split the stream.");r=!0;let s=!1;try{for await(let s of sB(e,t)){if("completion"===s.event)try{yield JSON.parse(s.data)}catch(e){throw a.error("Could not parse message into JSON:",s.data),a.error("From chunk:",s.raw),e}if("message_start"===s.event||"message_delta"===s.event||"message_stop"===s.event||"content_block_start"===s.event||"content_block_delta"===s.event||"content_block_stop"===s.event||"message"===s.event||"user.message"===s.event||"user.interrupt"===s.event||"user.tool_confirmation"===s.event||"user.custom_tool_result"===s.event||"agent.message"===s.event||"agent.thinking"===s.event||"agent.tool_use"===s.event||"agent.tool_result"===s.event||"agent.mcp_tool_use"===s.event||"agent.mcp_tool_result"===s.event||"agent.custom_tool_use"===s.event||"agent.thread_context_compacted"===s.event||"session.status_running"===s.event||"session.status_idle"===s.event||"session.status_rescheduled"===s.event||"session.status_terminated"===s.event||"session.error"===s.event||"session.deleted"===s.event||"span.model_request_start"===s.event||"span.model_request_end"===s.event)try{yield JSON.parse(s.data)}catch(e){throw a.error("Could not parse message into JSON:",s.data),a.error("From chunk:",s.raw),e}if("ping"!==s.event&&"error"===s.event){let t=sy(s.data)??s.data,r=t?.error?.type;throw new st(void 0,t,void 0,e.headers,r)}}s=!0}catch(e){if(t7(e))return;throw e}finally{s||t.abort()}}return new sU(n,t,s)}static fromReadableStream(e,t,s){let r=!1;async function*a(){let t=new sE;for await(let s of sN(e))for(let e of t.decode(s))yield e;for(let e of t.flush())yield e}return new sU(async function*(){if(r)throw new se("Cannot iterate over a consumed stream, use `.tee()` to split the stream.");r=!0;let e=!1;try{for await(let t of a())!e&&t&&(yield JSON.parse(t));e=!0}catch(e){if(t7(e))return;throw e}finally{e||t.abort()}},t,s)}[(i=new WeakMap,Symbol.asyncIterator)](){return this.iterator()}tee(){let e=[],t=[],s=this.iterator(),r=r=>({next:()=>{if(0===r.length){let r=s.next();e.push(r),t.push(r)}return r.shift()}});return[new sU(()=>r(e),this.controller,t6(this,i,"f")),new sU(()=>r(t),this.controller,t6(this,i,"f"))]}toReadableStream(){let e,t=this;return sj({async start(){e=t[Symbol.asyncIterator]()},async pull(t){try{let{value:s,done:r}=await e.next();if(r)return t.close();let a=sC(JSON.stringify(s)+"\n");t.enqueue(a)}catch(e){t.error(e)}},async cancel(){await e.return?.()}})}}async function*sB(e,t){if(!e.body){if(t.abort(),void 0!==globalThis.navigator&&"ReactNative"===globalThis.navigator.product)throw new se("The default react-native fetch implementation does not support streaming. Please use expo/fetch: https://docs.expo.dev/versions/latest/sdk/expo/#expofetch-api");throw new se("Attempted to iterate over a response with no body")}let s=new sq,r=new sE;for await(let t of sD(sN(e.body)))for(let e of r.decode(t)){let t=s.decode(e);t&&(yield t)}for(let e of r.flush()){let t=s.decode(e);t&&(yield t)}}async function*sD(e){let t=new Uint8Array;for await(let s of e){let e;if(null==s)continue;let r=s instanceof ArrayBuffer?new Uint8Array(s):"string"==typeof s?sC(s):s,a=new Uint8Array(t.length+r.length);for(a.set(t),a.set(r,t.length),t=a;-1!==(e=function(e){for(let t=0;t0&&(yield t)}class sq{constructor(){this.event=null,this.data=[],this.chunks=[]}decode(e){var t;let s;if(e.endsWith("\r")&&(e=e.substring(0,e.length-1)),!e){if(!this.event&&!this.data.length)return null;let e={event:this.event,data:this.data.join("\n"),raw:this.chunks};return this.event=null,this.data=[],this.chunks=[],e}if(this.chunks.push(e),e.startsWith(":"))return null;let[r,a,n]=-1!==(s=(t=e).indexOf(":"))?[t.substring(0,s),":",t.substring(s+1)]:[t,"",""];return n.startsWith(" ")&&(n=n.substring(1)),"event"===r?this.event=n:"data"===r&&this.data.push(n),null}}async function sW(e,t){let{response:s,requestLogID:r,retryOfRequestLogID:a,startTime:n}=t,i=await (async()=>{if(t.options.stream)return(s$(e).debug("response",s.status,s.url,s.headers,s.body),t.options.__streamClass)?t.options.__streamClass.fromSSEResponse(s,t.controller):sU.fromSSEResponse(s,t.controller);if(204===s.status)return null;if(t.options.__binaryResponse)return s;let r=s.headers.get("content-type"),a=r?.split(";")[0]?.trim();if(a?.includes("application/json")||a?.endsWith("+json")){if("0"===s.headers.get("content-length"))return;return sz(await s.json(),s)}return await s.text()})();return s$(e).debug(`[${r}] response parsed`,sL({retryOfRequestLogID:a,url:s.url,status:s.status,body:i,durationMs:Date.now()-n})),i}function sz(e,t){return!e||"object"!=typeof e||Array.isArray(e)?e:Object.defineProperty(e,"_request_id",{value:t.headers.get("request-id"),enumerable:!1})}class sF extends Promise{constructor(e,t,s=sW){super(e=>{e(null)}),this.responsePromise=t,this.parseResponse=s,l.set(this,void 0),t3(this,l,e,"f")}_thenUnwrap(e){return new sF(t6(this,l,"f"),this.responsePromise,async(t,s)=>sz(e(await this.parseResponse(t,s),s),s.response))}asResponse(){return this.responsePromise.then(e=>e.response)}async withResponse(){let[e,t]=await Promise.all([this.parse(),this.asResponse()]);return{data:e,response:t,request_id:t.headers.get("request-id")}}parse(){return this.parsedPromise||(this.parsedPromise=this.responsePromise.then(e=>this.parseResponse(t6(this,l,"f"),e))),this.parsedPromise}then(e,t){return this.parse().then(e,t)}catch(e){return this.parse().catch(e)}finally(e){return this.parse().finally(e)}}l=new WeakMap;class sH{constructor(e,t,s,r){o.set(this,void 0),t3(this,o,e,"f"),this.options=r,this.response=t,this.body=s}hasNextPage(){return!!this.getPaginatedItems().length&&null!=this.nextPageRequestOptions()}async getNextPage(){let e=this.nextPageRequestOptions();if(!e)throw new se("No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.");return await t6(this,o,"f").requestAPIList(this.constructor,e)}async *iterPages(){let e=this;for(yield e;e.hasNextPage();)e=await e.getNextPage(),yield e}async *[(o=new WeakMap,Symbol.asyncIterator)](){for await(let e of this.iterPages())for(let t of e.getPaginatedItems())yield t}}class sV extends sF{constructor(e,t,s){super(e,t,async(e,t)=>new s(e,t.response,await sW(e,t),t.options))}async *[Symbol.asyncIterator](){for await(let e of(await this))yield e}}class sJ extends sH{constructor(e,t,s,r){super(e,t,s,r),this.data=s.data||[],this.has_more=s.has_more||!1,this.first_id=s.first_id||null,this.last_id=s.last_id||null}getPaginatedItems(){return this.data??[]}hasNextPage(){return!1!==this.has_more&&super.hasNextPage()}nextPageRequestOptions(){if(this.options.query?.before_id){let e=this.first_id;return e?{...this.options,query:{...sf(this.options.query),before_id:e}}:null}let e=this.last_id;return e?{...this.options,query:{...sf(this.options.query),after_id:e}}:null}}class sG extends sH{constructor(e,t,s,r){super(e,t,s,r),this.data=s.data||[],this.next_page=s.next_page||null}getPaginatedItems(){return this.data??[]}nextPageRequestOptions(){let e=this.next_page;return e?{...this.options,query:{...sf(this.options.query),page:e}}:null}}let sK=()=>{if("u"parseInt(e.versions.node.split("."))?" Update to Node 20 LTS or newer, or set `globalThis.File` to `import('node:buffer').File`.":""))}};function sX(e,t,s){return sK(),new File(e,t??"unknown_file",s)}function sY(e,t){let s="object"==typeof e&&null!==e&&("name"in e&&e.name&&String(e.name)||"url"in e&&e.url&&String(e.url)||"filename"in e&&e.filename&&String(e.filename)||"path"in e&&e.path&&String(e.path))||"";return t?s.split(/[\\/]/).pop()||void 0:s}let sQ=e=>null!=e&&"object"==typeof e&&"function"==typeof e[Symbol.asyncIterator],sZ=async(e,t,s=!0)=>({...e,body:await s1(e.body,t,s)}),s0=new WeakMap,s1=async(e,t,s=!0)=>{if(!await function(e){let t="function"==typeof e?e:e.fetch,s=s0.get(t);if(s)return s;let r=(async()=>{try{let e="Response"in t?t.Response:(await t("data:,")).constructor,s=new FormData;if(s.toString()===await new e(s).text())return!1;return!0}catch{return!0}})();return s0.set(t,r),r}(t))throw TypeError("The provided fetch function does not support file uploads with the current global FormData class.");let r=new FormData;return await Promise.all(Object.entries(e||{}).map(([e,t])=>s2(r,e,t,s))),r},s2=async(e,t,s,r)=>{if(void 0!==s){if(null==s)throw TypeError(`Received null for "${t}"; to pass null in FormData, you must use the string 'null'`);if("string"==typeof s||"number"==typeof s||"boolean"==typeof s)e.append(t,String(s));else if(s instanceof Response){let a={},n=s.headers.get("Content-Type");n&&(a={type:n}),e.append(t,sX([await s.blob()],sY(s,r),a))}else if(sQ(s))e.append(t,sX([await new Response(s_(s)).blob()],sY(s,r)));else{let a;if((a=s)instanceof Blob&&"name"in a)e.append(t,sX([s],sY(s,r),{type:s.type}));else if(Array.isArray(s))await Promise.all(s.map(s=>s2(e,t+"[]",s,r)));else if("object"==typeof s)await Promise.all(Object.entries(s).map(([s,a])=>s2(e,`${t}[${s}]`,a,r)));else throw TypeError(`Invalid value given to form, expected a string, number, boolean, object, Array, File or Blob but got ${s} instead`)}}},s5=e=>null!=e&&"object"==typeof e&&"number"==typeof e.size&&"string"==typeof e.type&&"function"==typeof e.text&&"function"==typeof e.slice&&"function"==typeof e.arrayBuffer;async function s4(e,t,s){let r,a;if(sK(),e=await e,t||(t=sY(e,!0)),null!=(r=e)&&"object"==typeof r&&"string"==typeof r.name&&"number"==typeof r.lastModified&&s5(r))return e instanceof File&&null==t&&null==s?e:sX([await e.arrayBuffer()],t??e.name,{type:e.type,lastModified:e.lastModified,...s});if(null!=(a=e)&&"object"==typeof a&&"string"==typeof a.url&&"function"==typeof a.blob){let r=await e.blob();return t||(t=new URL(e.url).pathname.split(/[\\/]/).pop()),sX(await s3(r),t,s)}let n=await s3(e);if(!s?.type){let e=n.find(e=>"object"==typeof e&&"type"in e&&e.type);"string"==typeof e&&(s={...s,type:e})}return sX(n,t,s)}async function s3(e){let t=[];if("string"==typeof e||ArrayBuffer.isView(e)||e instanceof ArrayBuffer)t.push(e);else if(s5(e))t.push(e instanceof Blob?e:await e.arrayBuffer());else if(sQ(e))for await(let s of e)t.push(...await s3(s));else{let t=e?.constructor?.name;throw Error(`Unexpected data type: ${typeof e}${t?`; constructor: ${t}`:""}${function(e){if("object"!=typeof e||null===e)return"";let t=Object.getOwnPropertyNames(e);return`; props: [${t.map(e=>`"${e}"`).join(", ")}]`}(e)}`)}return t}class s6{constructor(e){this._client=e}}let s8=Symbol.for("brand.privateNullableHeaders"),s7=e=>{let t=new Headers,s=new Set;for(let r of e){let e=new Set;for(let[a,n]of function*(e){let t;if(!e)return;if(s8 in e){let{values:t,nulls:s}=e;for(let e of(yield*t.entries(),s))yield[e,null];return}let s=!1;for(let r of(e instanceof Headers?t=e.entries():sg(e)?t=e:(s=!0,t=Object.entries(e??{})),t)){let e=r[0];if("string"!=typeof e)throw TypeError("expected header name to be a string");let t=sg(r[1])?r[1]:[r[1]],a=!1;for(let r of t)void 0!==r&&(s&&!a&&(a=!0,yield[e,null]),yield[e,r])}}(r)){let r=a.toLowerCase();e.has(r)||(t.delete(a),e.add(r)),null===n?(t.delete(a),s.add(r)):(t.append(a,n),s.delete(r))}}return{[s8]:!0,values:t,nulls:s}};function s9(e){return e.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g,encodeURIComponent)}let re=Object.freeze(Object.create(null)),rt=((e=s9)=>function(t,...s){let r;if(1===t.length)return t[0];let a=!1,n=[],i=t.reduce((t,r,i)=>{/[?#]/.test(r)&&(a=!0);let l=s[i],o=(a?encodeURIComponent:e)(""+l);return i!==s.length&&(null==l||"object"==typeof l&&l.toString===Object.getPrototypeOf(Object.getPrototypeOf(l.hasOwnProperty??re)??re)?.toString)&&(o=l+"",n.push({start:t.length+r.length,length:o.length,error:`Value of type ${Object.prototype.toString.call(l).slice(8,-1)} is not a valid path parameter`})),t+r+(i===s.length?"":o)},""),l=i.split(/[?#]/,1)[0],o=/(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi;for(;null!==(r=o.exec(l));)n.push({start:r.index,length:r[0].length,error:`Value "${r[0]}" can't be safely passed as a path parameter`});if(n.sort((e,t)=>e.start-t.start),n.length>0){let e=0,t=n.reduce((t,s)=>{let r=" ".repeat(s.start-e),a="^".repeat(s.length);return e=s.start+s.length,t+r+a},"");throw new se(`Path parameters result in path with invalid segments: +${n.map(e=>e.error).join("\n")} +${i} +${t}`)}return i})(s9);class rs extends s6{create(e,t){let{betas:s,...r}=e;return this._client.post("/v1/environments?beta=true",{body:r,...t,headers:s7([{"anthropic-beta":[...s??[],"managed-agents-2026-04-01"].toString()},t?.headers])})}retrieve(e,t={},s){let{betas:r}=t??{};return this._client.get(rt`/v1/environments/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}update(e,t,s){let{betas:r,...a}=t;return this._client.post(rt`/v1/environments/${e}?beta=true`,{body:a,...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}list(e={},t){let{betas:s,...r}=e??{};return this._client.getAPIList("/v1/environments?beta=true",sG,{query:r,...t,headers:s7([{"anthropic-beta":[...s??[],"managed-agents-2026-04-01"].toString()},t?.headers])})}delete(e,t={},s){let{betas:r}=t??{};return this._client.delete(rt`/v1/environments/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}archive(e,t={},s){let{betas:r}=t??{};return this._client.post(rt`/v1/environments/${e}/archive?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}}let rr=Symbol("anthropic.sdk.stainlessHelper");function ra(e){return"object"==typeof e&&null!==e&&rr in e}function rn(e,t){let s=new Set;if(e)for(let t of e)ra(t)&&s.add(t[rr]);if(t){for(let e of t)if(ra(e)&&s.add(e[rr]),Array.isArray(e.content))for(let t of e.content)ra(t)&&s.add(t[rr])}return Array.from(s)}function ri(e,t){let s=rn(e,t);return 0===s.length?{}:{"x-stainless-helper":s.join(", ")}}class rl extends s6{list(e={},t){let{betas:s,...r}=e??{};return this._client.getAPIList("/v1/files?beta=true",sJ,{query:r,...t,headers:s7([{"anthropic-beta":[...s??[],"files-api-2025-04-14"].toString()},t?.headers])})}delete(e,t={},s){let{betas:r}=t??{};return this._client.delete(rt`/v1/files/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"files-api-2025-04-14"].toString()},s?.headers])})}download(e,t={},s){let{betas:r}=t??{};return this._client.get(rt`/v1/files/${e}/content?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"files-api-2025-04-14"].toString(),Accept:"application/binary"},s?.headers]),__binaryResponse:!0})}retrieveMetadata(e,t={},s){let{betas:r}=t??{};return this._client.get(rt`/v1/files/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"files-api-2025-04-14"].toString()},s?.headers])})}upload(e,t){var s;let{betas:r,...a}=e;return this._client.post("/v1/files?beta=true",sZ({body:a,...t,headers:s7([{"anthropic-beta":[...r??[],"files-api-2025-04-14"].toString()},ra(s=a.file)?{"x-stainless-helper":s[rr]}:{},t?.headers])},this._client))}}class ro extends s6{retrieve(e,t={},s){let{betas:r}=t??{};return this._client.get(rt`/v1/models/${e}?beta=true`,{...s,headers:s7([{...r?.toString()!=null?{"anthropic-beta":r?.toString()}:void 0},s?.headers])})}list(e={},t){let{betas:s,...r}=e??{};return this._client.getAPIList("/v1/models?beta=true",sJ,{query:r,...t,headers:s7([{...s?.toString()!=null?{"anthropic-beta":s?.toString()}:void 0},t?.headers])})}}class rc extends s6{create(e,t){let{betas:s,...r}=e;return this._client.post("/v1/user_profiles?beta=true",{body:r,...t,headers:s7([{"anthropic-beta":[...s??[],"user-profiles-2026-03-24"].toString()},t?.headers])})}retrieve(e,t={},s){let{betas:r}=t??{};return this._client.get(rt`/v1/user_profiles/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"user-profiles-2026-03-24"].toString()},s?.headers])})}update(e,t,s){let{betas:r,...a}=t;return this._client.post(rt`/v1/user_profiles/${e}?beta=true`,{body:a,...s,headers:s7([{"anthropic-beta":[...r??[],"user-profiles-2026-03-24"].toString()},s?.headers])})}list(e={},t){let{betas:s,...r}=e??{};return this._client.getAPIList("/v1/user_profiles?beta=true",sG,{query:r,...t,headers:s7([{"anthropic-beta":[...s??[],"user-profiles-2026-03-24"].toString()},t?.headers])})}createEnrollmentURL(e,t={},s){let{betas:r}=t??{};return this._client.post(rt`/v1/user_profiles/${e}/enrollment_url?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"user-profiles-2026-03-24"].toString()},s?.headers])})}}class rd extends s6{list(e,t={},s){let{betas:r,...a}=t??{};return this._client.getAPIList(rt`/v1/agents/${e}/versions?beta=true`,sG,{query:a,...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}}class ru extends s6{constructor(){super(...arguments),this.versions=new rd(this._client)}create(e,t){let{betas:s,...r}=e;return this._client.post("/v1/agents?beta=true",{body:r,...t,headers:s7([{"anthropic-beta":[...s??[],"managed-agents-2026-04-01"].toString()},t?.headers])})}retrieve(e,t={},s){let{betas:r,...a}=t??{};return this._client.get(rt`/v1/agents/${e}?beta=true`,{query:a,...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}update(e,t,s){let{betas:r,...a}=t;return this._client.post(rt`/v1/agents/${e}?beta=true`,{body:a,...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}list(e={},t){let{betas:s,...r}=e??{};return this._client.getAPIList("/v1/agents?beta=true",sG,{query:r,...t,headers:s7([{"anthropic-beta":[...s??[],"managed-agents-2026-04-01"].toString()},t?.headers])})}archive(e,t={},s){let{betas:r}=t??{};return this._client.post(rt`/v1/agents/${e}/archive?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}}ru.Versions=rd;class rm extends s6{create(e,t,s){let{view:r,betas:a,...n}=t;return this._client.post(rt`/v1/memory_stores/${e}/memories?beta=true`,{query:{view:r},body:n,...s,headers:s7([{"anthropic-beta":[...a??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}retrieve(e,t,s){let{memory_store_id:r,betas:a,...n}=t;return this._client.get(rt`/v1/memory_stores/${r}/memories/${e}?beta=true`,{query:n,...s,headers:s7([{"anthropic-beta":[...a??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}update(e,t,s){let{memory_store_id:r,view:a,betas:n,...i}=t;return this._client.post(rt`/v1/memory_stores/${r}/memories/${e}?beta=true`,{query:{view:a},body:i,...s,headers:s7([{"anthropic-beta":[...n??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}list(e,t={},s){let{betas:r,...a}=t??{};return this._client.getAPIList(rt`/v1/memory_stores/${e}/memories?beta=true`,sG,{query:a,...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}delete(e,t,s){let{memory_store_id:r,expected_content_sha256:a,betas:n}=t;return this._client.delete(rt`/v1/memory_stores/${r}/memories/${e}?beta=true`,{query:{expected_content_sha256:a},...s,headers:s7([{"anthropic-beta":[...n??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}}class rh extends s6{retrieve(e,t,s){let{memory_store_id:r,betas:a,...n}=t;return this._client.get(rt`/v1/memory_stores/${r}/memory_versions/${e}?beta=true`,{query:n,...s,headers:s7([{"anthropic-beta":[...a??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}list(e,t={},s){let{betas:r,...a}=t??{};return this._client.getAPIList(rt`/v1/memory_stores/${e}/memory_versions?beta=true`,sG,{query:a,...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}redact(e,t,s){let{memory_store_id:r,betas:a}=t;return this._client.post(rt`/v1/memory_stores/${r}/memory_versions/${e}/redact?beta=true`,{...s,headers:s7([{"anthropic-beta":[...a??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}}class rp extends s6{constructor(){super(...arguments),this.memories=new rm(this._client),this.memoryVersions=new rh(this._client)}create(e,t){let{betas:s,...r}=e;return this._client.post("/v1/memory_stores?beta=true",{body:r,...t,headers:s7([{"anthropic-beta":[...s??[],"managed-agents-2026-04-01"].toString()},t?.headers])})}retrieve(e,t={},s){let{betas:r}=t??{};return this._client.get(rt`/v1/memory_stores/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}update(e,t,s){let{betas:r,...a}=t;return this._client.post(rt`/v1/memory_stores/${e}?beta=true`,{body:a,...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}list(e={},t){let{betas:s,...r}=e??{};return this._client.getAPIList("/v1/memory_stores?beta=true",sG,{query:r,...t,headers:s7([{"anthropic-beta":[...s??[],"managed-agents-2026-04-01"].toString()},t?.headers])})}delete(e,t={},s){let{betas:r}=t??{};return this._client.delete(rt`/v1/memory_stores/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}archive(e,t={},s){let{betas:r}=t??{};return this._client.post(rt`/v1/memory_stores/${e}/archive?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}}rp.Memories=rm,rp.MemoryVersions=rh;class rg{constructor(e,t){this.iterator=e,this.controller=t}async *decoder(){let e=new sE;for await(let t of this.iterator)for(let s of e.decode(t))yield JSON.parse(s);for(let t of e.flush())yield JSON.parse(t)}[Symbol.asyncIterator](){return this.decoder()}static fromResponse(e,t){if(!e.body){if(t.abort(),void 0!==globalThis.navigator&&"ReactNative"===globalThis.navigator.product)throw new se("The default react-native fetch implementation does not support streaming. Please use expo/fetch: https://docs.expo.dev/versions/latest/sdk/expo/#expofetch-api");throw new se("Attempted to iterate over a response with no body")}return new rg(sN(e.body),t)}}class rf extends s6{create(e,t){let{betas:s,...r}=e;return this._client.post("/v1/messages/batches?beta=true",{body:r,...t,headers:s7([{"anthropic-beta":[...s??[],"message-batches-2024-09-24"].toString()},t?.headers])})}retrieve(e,t={},s){let{betas:r}=t??{};return this._client.get(rt`/v1/messages/batches/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"message-batches-2024-09-24"].toString()},s?.headers])})}list(e={},t){let{betas:s,...r}=e??{};return this._client.getAPIList("/v1/messages/batches?beta=true",sJ,{query:r,...t,headers:s7([{"anthropic-beta":[...s??[],"message-batches-2024-09-24"].toString()},t?.headers])})}delete(e,t={},s){let{betas:r}=t??{};return this._client.delete(rt`/v1/messages/batches/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"message-batches-2024-09-24"].toString()},s?.headers])})}cancel(e,t={},s){let{betas:r}=t??{};return this._client.post(rt`/v1/messages/batches/${e}/cancel?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"message-batches-2024-09-24"].toString()},s?.headers])})}async results(e,t={},s){let r=await this.retrieve(e);if(!r.results_url)throw new se(`No batch \`results_url\`; Has it finished processing? ${r.processing_status} - ${r.id}`);let{betas:a}=t??{};return this._client.get(r.results_url,{...s,headers:s7([{"anthropic-beta":[...a??[],"message-batches-2024-09-24"].toString(),Accept:"application/binary"},s?.headers]),stream:!0,__binaryResponse:!0})._thenUnwrap((e,t)=>rg.fromResponse(t.response,t.controller))}}let rx={"claude-opus-4-20250514":8192,"claude-opus-4-0":8192,"claude-4-opus-20250514":8192,"anthropic.claude-opus-4-20250514-v1:0":8192,"claude-opus-4@20250514":8192,"claude-opus-4-1-20250805":8192,"anthropic.claude-opus-4-1-20250805-v1:0":8192,"claude-opus-4-1@20250805":8192};function ry(e){return e?.output_format??e?.output_config?.format}function rb(e,t,s){let r=ry(t);return t&&"parse"in(r??{})?rv(e,t,s):{...e,content:e.content.map(e=>"text"===e.type?Object.defineProperty(Object.defineProperty({...e},"parsed_output",{value:null,enumerable:!1}),"parsed",{get:()=>(s.logger.warn("The `parsed` property on `text` blocks is deprecated, please use `parsed_output` instead."),null),enumerable:!1}):e),parsed_output:null}}function rv(e,t,s){let r=null,a=e.content.map(e=>{if("text"===e.type){let a=function(e,t){let s=ry(e);if(s?.type!=="json_schema")return null;try{if("parse"in s)return s.parse(t);return JSON.parse(t)}catch(e){throw new se(`Failed to parse structured output: ${e}`)}}(t,e.text);return null===r&&(r=a),Object.defineProperty(Object.defineProperty({...e},"parsed_output",{value:a,enumerable:!1}),"parsed",{get:()=>(s.logger.warn("The `parsed` property on `text` blocks is deprecated, please use `parsed_output` instead."),a),enumerable:!1})}return e});return{...e,content:a,parsed_output:r}}let rw=e=>{if(0===e.length)return e;let t=e[e.length-1];switch(t.type){case"separator":return rw(e=e.slice(0,e.length-1));case"number":let s=t.value[t.value.length-1];if("."===s||"-"===s)return rw(e=e.slice(0,e.length-1));case"string":let r=e[e.length-2];if(r?.type==="delimiter"||r?.type==="brace"&&"{"===r.value)return rw(e=e.slice(0,e.length-1));break;case"delimiter":return rw(e=e.slice(0,e.length-1))}return e},rj=e=>{var t;let s,r;return JSON.parse((t=rw((e=>{let t=0,s=[];for(;t{"brace"===e.type&&("{"===e.value?s.push("}"):s.splice(s.lastIndexOf("}"),1)),"paren"===e.type&&("["===e.value?s.push("]"):s.splice(s.lastIndexOf("]"),1))}),s.length>0&&s.reverse().map(e=>{"}"===e?t.push({type:"brace",value:"}"}):"]"===e&&t.push({type:"paren",value:"]"})}),r="",t.map(e=>{"string"===e.type?r+='"'+e.value+'"':r+=e.value}),r))},r_="__json_buf";function rN(e){return"tool_use"===e.type||"server_tool_use"===e.type||"mcp_tool_use"===e.type}class rS{constructor(e,t){c.add(this),this.messages=[],this.receivedMessages=[],d.set(this,void 0),u.set(this,null),this.controller=new AbortController,m.set(this,void 0),h.set(this,()=>{}),p.set(this,()=>{}),g.set(this,void 0),f.set(this,()=>{}),x.set(this,()=>{}),y.set(this,{}),b.set(this,!1),v.set(this,!1),w.set(this,!1),j.set(this,!1),_.set(this,void 0),N.set(this,void 0),S.set(this,void 0),T.set(this,e=>{if(t3(this,v,!0,"f"),t7(e)&&(e=new ss),e instanceof ss)return t3(this,w,!0,"f"),this._emit("abort",e);if(e instanceof se)return this._emit("error",e);if(e instanceof Error){let t=new se(e.message);return t.cause=e,this._emit("error",t)}return this._emit("error",new se(String(e)))}),t3(this,m,new Promise((e,t)=>{t3(this,h,e,"f"),t3(this,p,t,"f")}),"f"),t3(this,g,new Promise((e,t)=>{t3(this,f,e,"f"),t3(this,x,t,"f")}),"f"),t6(this,m,"f").catch(()=>{}),t6(this,g,"f").catch(()=>{}),t3(this,u,e,"f"),t3(this,S,t?.logger??console,"f")}get response(){return t6(this,_,"f")}get request_id(){return t6(this,N,"f")}async withResponse(){t3(this,j,!0,"f");let e=await t6(this,m,"f");if(!e)throw Error("Could not resolve a `Response` object");return{data:this,response:e,request_id:e.headers.get("request-id")}}static fromReadableStream(e){let t=new rS(null);return t._run(()=>t._fromReadableStream(e)),t}static createMessage(e,t,s,{logger:r}={}){let a=new rS(t,{logger:r});for(let e of t.messages)a._addMessageParam(e);return t3(a,u,{...t,stream:!0},"f"),a._run(()=>a._createMessage(e,{...t,stream:!0},{...s,headers:{...s?.headers,"X-Stainless-Helper-Method":"stream"}})),a}_run(e){e().then(()=>{this._emitFinal(),this._emit("end")},t6(this,T,"f"))}_addMessageParam(e){this.messages.push(e)}_addMessage(e,t=!0){this.receivedMessages.push(e),t&&this._emit("message",e)}async _createMessage(e,t,s){let r,a=s?.signal;a&&(a.aborted&&this.controller.abort(),r=this.controller.abort.bind(this.controller),a.addEventListener("abort",r));try{t6(this,c,"m",E).call(this);let{response:r,data:a}=await e.create({...t,stream:!0},{...s,signal:this.controller.signal}).withResponse();for await(let e of(this._connected(r),a))t6(this,c,"m",A).call(this,e);if(a.controller.signal?.aborted)throw new ss;t6(this,c,"m",P).call(this)}finally{a&&r&&a.removeEventListener("abort",r)}}_connected(e){this.ended||(t3(this,_,e,"f"),t3(this,N,e?.headers.get("request-id"),"f"),t6(this,h,"f").call(this,e),this._emit("connect"))}get ended(){return t6(this,b,"f")}get errored(){return t6(this,v,"f")}get aborted(){return t6(this,w,"f")}abort(){this.controller.abort()}on(e,t){return(t6(this,y,"f")[e]||(t6(this,y,"f")[e]=[])).push({listener:t}),this}off(e,t){let s=t6(this,y,"f")[e];if(!s)return this;let r=s.findIndex(e=>e.listener===t);return r>=0&&s.splice(r,1),this}once(e,t){return(t6(this,y,"f")[e]||(t6(this,y,"f")[e]=[])).push({listener:t,once:!0}),this}emitted(e){return new Promise((t,s)=>{t3(this,j,!0,"f"),"error"!==e&&this.once("error",s),this.once(e,t)})}async done(){t3(this,j,!0,"f"),await t6(this,g,"f")}get currentMessage(){return t6(this,d,"f")}async finalMessage(){return await this.done(),t6(this,c,"m",k).call(this)}async finalText(){return await this.done(),t6(this,c,"m",C).call(this)}_emit(e,...t){if(t6(this,b,"f"))return;"end"===e&&(t3(this,b,!0,"f"),t6(this,f,"f").call(this));let s=t6(this,y,"f")[e];if(s&&(t6(this,y,"f")[e]=s.filter(e=>!e.once),s.forEach(({listener:e})=>e(...t))),"abort"===e){let e=t[0];t6(this,j,"f")||s?.length||Promise.reject(e),t6(this,p,"f").call(this,e),t6(this,x,"f").call(this,e),this._emit("end");return}if("error"===e){let e=t[0];t6(this,j,"f")||s?.length||Promise.reject(e),t6(this,p,"f").call(this,e),t6(this,x,"f").call(this,e),this._emit("end")}}_emitFinal(){this.receivedMessages.at(-1)&&this._emit("finalMessage",t6(this,c,"m",k).call(this))}async _fromReadableStream(e,t){let s,r=t?.signal;r&&(r.aborted&&this.controller.abort(),s=this.controller.abort.bind(this.controller),r.addEventListener("abort",s));try{t6(this,c,"m",E).call(this),this._connected(null);let t=sU.fromReadableStream(e,this.controller);for await(let e of t)t6(this,c,"m",A).call(this,e);if(t.controller.signal?.aborted)throw new ss;t6(this,c,"m",P).call(this)}finally{r&&s&&r.removeEventListener("abort",s)}}[(d=new WeakMap,u=new WeakMap,m=new WeakMap,h=new WeakMap,p=new WeakMap,g=new WeakMap,f=new WeakMap,x=new WeakMap,y=new WeakMap,b=new WeakMap,v=new WeakMap,w=new WeakMap,j=new WeakMap,_=new WeakMap,N=new WeakMap,S=new WeakMap,T=new WeakMap,c=new WeakSet,k=function(){if(0===this.receivedMessages.length)throw new se("stream ended without producing a Message with role=assistant");return this.receivedMessages.at(-1)},C=function(){if(0===this.receivedMessages.length)throw new se("stream ended without producing a Message with role=assistant");let e=this.receivedMessages.at(-1).content.filter(e=>"text"===e.type).map(e=>e.text);if(0===e.length)throw new se("stream ended without producing a content block with type=text");return e.join(" ")},E=function(){this.ended||t3(this,d,void 0,"f")},A=function(e){if(this.ended)return;let t=t6(this,c,"m",R).call(this,e);switch(this._emit("streamEvent",e,t),e.type){case"content_block_delta":{let s=t.content.at(-1);switch(e.delta.type){case"text_delta":"text"===s.type&&this._emit("text",e.delta.text,s.text||"");break;case"citations_delta":"text"===s.type&&this._emit("citation",e.delta.citation,s.citations??[]);break;case"input_json_delta":rN(s)&&s.input&&this._emit("inputJson",e.delta.partial_json,s.input);break;case"thinking_delta":"thinking"===s.type&&this._emit("thinking",e.delta.thinking,s.thinking);break;case"signature_delta":"thinking"===s.type&&this._emit("signature",s.signature);break;case"compaction_delta":"compaction"===s.type&&s.content&&this._emit("compaction",s.content);break;default:rk(e.delta)}break}case"message_stop":this._addMessageParam(t),this._addMessage(rb(t,t6(this,u,"f"),{logger:t6(this,S,"f")}),!0);break;case"content_block_stop":this._emit("contentBlock",t.content.at(-1));break;case"message_start":t3(this,d,t,"f")}},P=function(){if(this.ended)throw new se("stream has ended, this shouldn't happen");let e=t6(this,d,"f");if(!e)throw new se("request ended without sending any chunks");return t3(this,d,void 0,"f"),rb(e,t6(this,u,"f"),{logger:t6(this,S,"f")})},R=function(e){let t=t6(this,d,"f");if("message_start"===e.type){if(t)throw new se(`Unexpected event order, got ${e.type} before receiving "message_stop"`);return e.message}if(!t)throw new se(`Unexpected event order, got ${e.type} before "message_start"`);switch(e.type){case"message_stop":case"content_block_stop":return t;case"message_delta":return t.container=e.delta.container,t.stop_reason=e.delta.stop_reason,t.stop_sequence=e.delta.stop_sequence,t.usage.output_tokens=e.usage.output_tokens,t.context_management=e.context_management,null!=e.usage.input_tokens&&(t.usage.input_tokens=e.usage.input_tokens),null!=e.usage.cache_creation_input_tokens&&(t.usage.cache_creation_input_tokens=e.usage.cache_creation_input_tokens),null!=e.usage.cache_read_input_tokens&&(t.usage.cache_read_input_tokens=e.usage.cache_read_input_tokens),null!=e.usage.server_tool_use&&(t.usage.server_tool_use=e.usage.server_tool_use),null!=e.usage.iterations&&(t.usage.iterations=e.usage.iterations),t;case"content_block_start":return t.content.push(e.content_block),t;case"content_block_delta":{let s=t.content.at(e.index);switch(e.delta.type){case"text_delta":s?.type==="text"&&(t.content[e.index]={...s,text:(s.text||"")+e.delta.text});break;case"citations_delta":s?.type==="text"&&(t.content[e.index]={...s,citations:[...s.citations??[],e.delta.citation]});break;case"input_json_delta":if(s&&rN(s)){let r=s[r_]||"";r+=e.delta.partial_json;let a={...s};if(Object.defineProperty(a,r_,{value:r,enumerable:!1,writable:!0}),r)try{a.input=rj(r)}catch(t){let e=new se(`Unable to parse tool parameter JSON from model. Please retry your request or adjust your prompt. Error: ${t}. JSON: ${r}`);t6(this,T,"f").call(this,e)}t.content[e.index]=a}break;case"thinking_delta":s?.type==="thinking"&&(t.content[e.index]={...s,thinking:s.thinking+e.delta.thinking});break;case"signature_delta":s?.type==="thinking"&&(t.content[e.index]={...s,signature:e.delta.signature});break;case"compaction_delta":s?.type==="compaction"&&(t.content[e.index]={...s,content:(s.content||"")+e.delta.content});break;default:rk(e.delta)}return t}}},Symbol.asyncIterator)](){let e=[],t=[],s=!1;return this.on("streamEvent",s=>{let r=t.shift();r?r.resolve(s):e.push(s)}),this.on("end",()=>{for(let e of(s=!0,t))e.resolve(void 0);t.length=0}),this.on("abort",e=>{for(let r of(s=!0,t))r.reject(e);t.length=0}),this.on("error",e=>{for(let r of(s=!0,t))r.reject(e);t.length=0}),{next:async()=>e.length?{value:e.shift(),done:!1}:s?{value:void 0,done:!0}:new Promise((e,s)=>t.push({resolve:e,reject:s})).then(e=>e?{value:e,done:!1}:{value:void 0,done:!0}),return:async()=>(this.abort(),{value:void 0,done:!0})}}toReadableStream(){return new sU(this[Symbol.asyncIterator].bind(this),this.controller).toReadableStream()}}function rk(e){}class rC extends Error{constructor(e){super("string"==typeof e?e:e.map(e=>"text"===e.type?e.text:`[${e.type}]`).join(" ")),this.name="ToolError",this.content=e}}let rT=`You have been working on the task described above but have not yet completed it. Write a continuation summary that will allow you (or another instance of yourself) to resume work efficiently in a future context window where the conversation history will be replaced with this summary. Your summary should be structured, concise, and actionable. Include: +1. Task Overview +The user's core request and success criteria +Any clarifications or constraints they specified +2. Current State +What has been completed so far +Files created, modified, or analyzed (with paths if relevant) +Key outputs or artifacts produced +3. Important Discoveries +Technical constraints or requirements uncovered +Decisions made and their rationale +Errors encountered and how they were resolved +What approaches were tried that didn't work (and why) +4. Next Steps +Specific actions needed to complete the task +Any blockers or open questions to resolve +Priority order if multiple steps remain +5. Context to Preserve +User preferences or style requirements +Domain-specific details that aren't obvious +Any promises made to the user +Be concise but complete—err on the side of including information that would prevent duplicate work or repeated mistakes. Write in a way that enables immediate resumption of the task. +Wrap your summary in tags.`;function rE(){let e,t;return{promise:new Promise((s,r)=>{e=s,t=r}),resolve:e,reject:t}}class rA{constructor(e,t,s){O.add(this),this.client=e,I.set(this,!1),M.set(this,!1),$.set(this,void 0),L.set(this,void 0),U.set(this,void 0),B.set(this,void 0),D.set(this,void 0),q.set(this,0),t3(this,$,{params:{...t,messages:structuredClone(t.messages)}},"f");const r=["BetaToolRunner",...rn(t.tools,t.messages)].join(", ");t3(this,L,{...s,headers:s7([{"x-stainless-helper":r},s?.headers])},"f"),t3(this,D,rE(),"f"),t.compactionControl?.enabled&&console.warn('Anthropic: The `compactionControl` parameter is deprecated and will be removed in a future version. Use server-side compaction instead by passing `edits: [{ type: "compact_20260112" }]` in the params passed to `toolRunner()`. See https://platform.claude.com/docs/en/build-with-claude/compaction')}async *[(I=new WeakMap,M=new WeakMap,$=new WeakMap,L=new WeakMap,U=new WeakMap,B=new WeakMap,D=new WeakMap,q=new WeakMap,O=new WeakSet,W=async function(){let e=t6(this,$,"f").params.compactionControl;if(!e||!e.enabled)return!1;let t=0;if(void 0!==t6(this,U,"f"))try{let e=await t6(this,U,"f");t=e.usage.input_tokens+(e.usage.cache_creation_input_tokens??0)+(e.usage.cache_read_input_tokens??0)+e.usage.output_tokens}catch{return!1}if(t<(e.contextTokenThreshold??1e5))return!1;let s=e.model??t6(this,$,"f").params.model,r=e.summaryPrompt??rT,a=t6(this,$,"f").params.messages;if("assistant"===a[a.length-1].role){let e=a[a.length-1];if(Array.isArray(e.content)){let t=e.content.filter(e=>"tool_use"!==e.type);0===t.length?a.pop():e.content=t}}let n=await this.client.beta.messages.create({model:s,messages:[...a,{role:"user",content:[{type:"text",text:r}]}],max_tokens:t6(this,$,"f").params.max_tokens},{signal:t6(this,L,"f").signal,headers:s7([t6(this,L,"f").headers,{"x-stainless-helper":"compaction"}])});if(n.content[0]?.type!=="text")throw new se("Expected text response for compaction");return t6(this,$,"f").params.messages=[{role:"user",content:n.content}],!0},Symbol.asyncIterator)](){var e;if(t6(this,I,"f"))throw new se("Cannot iterate over a consumed stream");t3(this,I,!0,"f"),t3(this,M,!0,"f"),t3(this,B,void 0,"f");try{for(;;){let t;try{if(t6(this,$,"f").params.max_iterations&&t6(this,q,"f")>=t6(this,$,"f").params.max_iterations)break;t3(this,M,!1,"f"),t3(this,B,void 0,"f"),t3(this,q,(e=t6(this,q,"f"),++e),"f"),t3(this,U,void 0,"f");let{max_iterations:s,compactionControl:r,...a}=t6(this,$,"f").params;if(a.stream?(t=this.client.beta.messages.stream({...a},t6(this,L,"f")),t3(this,U,t.finalMessage(),"f"),t6(this,U,"f").catch(()=>{}),yield t):(t3(this,U,this.client.beta.messages.create({...a,stream:!1},t6(this,L,"f")),"f"),yield t6(this,U,"f")),!await t6(this,O,"m",W).call(this)){if(!t6(this,M,"f")){let{role:e,content:t}=await t6(this,U,"f");t6(this,$,"f").params.messages.push({role:e,content:t})}let e=await t6(this,O,"m",z).call(this,t6(this,$,"f").params.messages.at(-1));if(e)t6(this,$,"f").params.messages.push(e);else if(!t6(this,M,"f"))break}}finally{t&&t.abort()}}if(!t6(this,U,"f"))throw new se("ToolRunner concluded without a message from the server");t6(this,D,"f").resolve(await t6(this,U,"f"))}catch(e){throw t3(this,I,!1,"f"),t6(this,D,"f").promise.catch(()=>{}),t6(this,D,"f").reject(e),t3(this,D,rE(),"f"),e}}setMessagesParams(e){"function"==typeof e?t6(this,$,"f").params=e(t6(this,$,"f").params):t6(this,$,"f").params=e,t3(this,M,!0,"f"),t3(this,B,void 0,"f")}setRequestOptions(e){"function"==typeof e?t3(this,L,e(t6(this,L,"f")),"f"):t3(this,L,{...t6(this,L,"f"),...e},"f")}async generateToolResponse(e=t6(this,L,"f").signal){let t=await t6(this,U,"f")??this.params.messages.at(-1);return t?t6(this,O,"m",z).call(this,t,e):null}done(){return t6(this,D,"f").promise}async runUntilDone(){if(!t6(this,I,"f"))for await(let e of this);return this.done()}get params(){return t6(this,$,"f").params}pushMessages(...e){this.setMessagesParams(t=>({...t,messages:[...t.messages,...e]}))}then(e,t){return this.runUntilDone().then(e,t)}}async function rP(e,t=e.messages.at(-1),s){if(!t||"assistant"!==t.role||!t.content||"string"==typeof t.content)return null;let r=t.content.filter(e=>"tool_use"===e.type);return 0===r.length?null:{role:"user",content:await Promise.all(r.map(async t=>{let r=e.tools.find(e=>("name"in e?e.name:e.mcp_server_name)===t.name);if(!r||!("run"in r))return{type:"tool_result",tool_use_id:t.id,content:`Error: Tool '${t.name}' not found`,is_error:!0};try{let e=t.input;"parse"in r&&r.parse&&(e=r.parse(e));let a=await r.run(e,{toolUseBlock:t,signal:s?.signal});return{type:"tool_result",tool_use_id:t.id,content:a}}catch(e){return{type:"tool_result",tool_use_id:t.id,content:e instanceof rC?e.content:`Error: ${e instanceof Error?e.message:String(e)}`,is_error:!0}}}))}}z=async function(e,t=t6(this,L,"f").signal){return void 0!==t6(this,B,"f")||t3(this,B,rP(t6(this,$,"f").params,e,{...t6(this,L,"f"),signal:t}),"f"),t6(this,B,"f")};let rR={"claude-1.3":"November 6th, 2024","claude-1.3-100k":"November 6th, 2024","claude-instant-1.1":"November 6th, 2024","claude-instant-1.1-100k":"November 6th, 2024","claude-instant-1.2":"November 6th, 2024","claude-3-sonnet-20240229":"July 21st, 2025","claude-3-opus-20240229":"January 5th, 2026","claude-2.1":"July 21st, 2025","claude-2.0":"July 21st, 2025","claude-3-7-sonnet-latest":"February 19th, 2026","claude-3-7-sonnet-20250219":"February 19th, 2026"},rO=["claude-mythos-preview","claude-opus-4-6"];class rI extends s6{constructor(){super(...arguments),this.batches=new rf(this._client)}create(e,t){let s=rM(e),{betas:r,...a}=s;a.model in rR&&console.warn(`The model '${a.model}' is deprecated and will reach end-of-life on ${rR[a.model]} +Please migrate to a newer model. Visit https://docs.anthropic.com/en/docs/resources/model-deprecations for more information.`),rO.includes(a.model)&&a.thinking&&"enabled"===a.thinking.type&&console.warn(`Using Claude with ${a.model} and 'thinking.type=enabled' is deprecated. Use 'thinking.type=adaptive' instead which results in better model performance in our testing: https://platform.claude.com/docs/en/build-with-claude/adaptive-thinking`);let n=this._client._options.timeout;if(!a.stream&&null==n){let e=rx[a.model]??void 0;n=this._client.calculateNonstreamingTimeout(a.max_tokens,e)}let i=ri(a.tools,a.messages);return this._client.post("/v1/messages?beta=true",{body:a,timeout:n??6e5,...t,headers:s7([{...r?.toString()!=null?{"anthropic-beta":r?.toString()}:void 0},i,t?.headers]),stream:s.stream??!1})}parse(e,t){return t={...t,headers:s7([{"anthropic-beta":[...e.betas??[],"structured-outputs-2025-12-15"].toString()},t?.headers])},this.create(e,t).then(t=>rv(t,e,{logger:this._client.logger??console}))}stream(e,t){return rS.createMessage(this,e,t)}countTokens(e,t){let{betas:s,...r}=rM(e);return this._client.post("/v1/messages/count_tokens?beta=true",{body:r,...t,headers:s7([{"anthropic-beta":[...s??[],"token-counting-2024-11-01"].toString()},t?.headers])})}toolRunner(e,t){return new rA(this._client,e,t)}}function rM(e){if(!e.output_format)return e;if(e.output_config?.format)throw new se("Both output_format and output_config.format were provided. Please use only output_config.format (output_format is deprecated).");let{output_format:t,...s}=e;return{...s,output_config:{...e.output_config,format:t}}}rI.Batches=rf,rI.BetaToolRunner=rA,rI.ToolError=rC;class r$ extends s6{list(e,t={},s){let{betas:r,...a}=t??{};return this._client.getAPIList(rt`/v1/sessions/${e}/events?beta=true`,sG,{query:a,...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}send(e,t,s){let{betas:r,...a}=t;return this._client.post(rt`/v1/sessions/${e}/events?beta=true`,{body:a,...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}stream(e,t={},s){let{betas:r}=t??{};return this._client.get(rt`/v1/sessions/${e}/events/stream?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers]),stream:!0})}}class rL extends s6{retrieve(e,t,s){let{session_id:r,betas:a}=t;return this._client.get(rt`/v1/sessions/${r}/resources/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...a??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}update(e,t,s){let{session_id:r,betas:a,...n}=t;return this._client.post(rt`/v1/sessions/${r}/resources/${e}?beta=true`,{body:n,...s,headers:s7([{"anthropic-beta":[...a??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}list(e,t={},s){let{betas:r,...a}=t??{};return this._client.getAPIList(rt`/v1/sessions/${e}/resources?beta=true`,sG,{query:a,...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}delete(e,t,s){let{session_id:r,betas:a}=t;return this._client.delete(rt`/v1/sessions/${r}/resources/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...a??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}add(e,t,s){let{betas:r,...a}=t;return this._client.post(rt`/v1/sessions/${e}/resources?beta=true`,{body:a,...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}}class rU extends s6{constructor(){super(...arguments),this.events=new r$(this._client),this.resources=new rL(this._client)}create(e,t){let{betas:s,...r}=e;return this._client.post("/v1/sessions?beta=true",{body:r,...t,headers:s7([{"anthropic-beta":[...s??[],"managed-agents-2026-04-01"].toString()},t?.headers])})}retrieve(e,t={},s){let{betas:r}=t??{};return this._client.get(rt`/v1/sessions/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}update(e,t,s){let{betas:r,...a}=t;return this._client.post(rt`/v1/sessions/${e}?beta=true`,{body:a,...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}list(e={},t){let{betas:s,...r}=e??{};return this._client.getAPIList("/v1/sessions?beta=true",sG,{query:r,...t,headers:s7([{"anthropic-beta":[...s??[],"managed-agents-2026-04-01"].toString()},t?.headers])})}delete(e,t={},s){let{betas:r}=t??{};return this._client.delete(rt`/v1/sessions/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}archive(e,t={},s){let{betas:r}=t??{};return this._client.post(rt`/v1/sessions/${e}/archive?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}}rU.Events=r$,rU.Resources=rL;class rB extends s6{create(e,t={},s){let{betas:r,...a}=t??{};return this._client.post(rt`/v1/skills/${e}/versions?beta=true`,sZ({body:a,...s,headers:s7([{"anthropic-beta":[...r??[],"skills-2025-10-02"].toString()},s?.headers])},this._client))}retrieve(e,t,s){let{skill_id:r,betas:a}=t;return this._client.get(rt`/v1/skills/${r}/versions/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...a??[],"skills-2025-10-02"].toString()},s?.headers])})}list(e,t={},s){let{betas:r,...a}=t??{};return this._client.getAPIList(rt`/v1/skills/${e}/versions?beta=true`,sG,{query:a,...s,headers:s7([{"anthropic-beta":[...r??[],"skills-2025-10-02"].toString()},s?.headers])})}delete(e,t,s){let{skill_id:r,betas:a}=t;return this._client.delete(rt`/v1/skills/${r}/versions/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...a??[],"skills-2025-10-02"].toString()},s?.headers])})}}class rD extends s6{constructor(){super(...arguments),this.versions=new rB(this._client)}create(e={},t){let{betas:s,...r}=e??{};return this._client.post("/v1/skills?beta=true",sZ({body:r,...t,headers:s7([{"anthropic-beta":[...s??[],"skills-2025-10-02"].toString()},t?.headers])},this._client,!1))}retrieve(e,t={},s){let{betas:r}=t??{};return this._client.get(rt`/v1/skills/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"skills-2025-10-02"].toString()},s?.headers])})}list(e={},t){let{betas:s,...r}=e??{};return this._client.getAPIList("/v1/skills?beta=true",sG,{query:r,...t,headers:s7([{"anthropic-beta":[...s??[],"skills-2025-10-02"].toString()},t?.headers])})}delete(e,t={},s){let{betas:r}=t??{};return this._client.delete(rt`/v1/skills/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"skills-2025-10-02"].toString()},s?.headers])})}}rD.Versions=rB;class rq extends s6{create(e,t,s){let{betas:r,...a}=t;return this._client.post(rt`/v1/vaults/${e}/credentials?beta=true`,{body:a,...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}retrieve(e,t,s){let{vault_id:r,betas:a}=t;return this._client.get(rt`/v1/vaults/${r}/credentials/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...a??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}update(e,t,s){let{vault_id:r,betas:a,...n}=t;return this._client.post(rt`/v1/vaults/${r}/credentials/${e}?beta=true`,{body:n,...s,headers:s7([{"anthropic-beta":[...a??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}list(e,t={},s){let{betas:r,...a}=t??{};return this._client.getAPIList(rt`/v1/vaults/${e}/credentials?beta=true`,sG,{query:a,...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}delete(e,t,s){let{vault_id:r,betas:a}=t;return this._client.delete(rt`/v1/vaults/${r}/credentials/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...a??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}archive(e,t,s){let{vault_id:r,betas:a}=t;return this._client.post(rt`/v1/vaults/${r}/credentials/${e}/archive?beta=true`,{...s,headers:s7([{"anthropic-beta":[...a??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}}class rW extends s6{constructor(){super(...arguments),this.credentials=new rq(this._client)}create(e,t){let{betas:s,...r}=e;return this._client.post("/v1/vaults?beta=true",{body:r,...t,headers:s7([{"anthropic-beta":[...s??[],"managed-agents-2026-04-01"].toString()},t?.headers])})}retrieve(e,t={},s){let{betas:r}=t??{};return this._client.get(rt`/v1/vaults/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}update(e,t,s){let{betas:r,...a}=t;return this._client.post(rt`/v1/vaults/${e}?beta=true`,{body:a,...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}list(e={},t){let{betas:s,...r}=e??{};return this._client.getAPIList("/v1/vaults?beta=true",sG,{query:r,...t,headers:s7([{"anthropic-beta":[...s??[],"managed-agents-2026-04-01"].toString()},t?.headers])})}delete(e,t={},s){let{betas:r}=t??{};return this._client.delete(rt`/v1/vaults/${e}?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}archive(e,t={},s){let{betas:r}=t??{};return this._client.post(rt`/v1/vaults/${e}/archive?beta=true`,{...s,headers:s7([{"anthropic-beta":[...r??[],"managed-agents-2026-04-01"].toString()},s?.headers])})}}rW.Credentials=rq;class rz extends s6{constructor(){super(...arguments),this.models=new ro(this._client),this.messages=new rI(this._client),this.agents=new ru(this._client),this.environments=new rs(this._client),this.sessions=new rU(this._client),this.vaults=new rW(this._client),this.memoryStores=new rp(this._client),this.files=new rl(this._client),this.skills=new rD(this._client),this.userProfiles=new rc(this._client)}}function rF(e){return e?.output_config?.format}function rH(e,t,s){let r=rF(t);return t&&"parse"in(r??{})?rV(e,t,s):{...e,content:e.content.map(e=>"text"===e.type?Object.defineProperty({...e},"parsed_output",{value:null,enumerable:!1}):e),parsed_output:null}}function rV(e,t,s){let r=null,a=e.content.map(e=>{if("text"===e.type){let s=function(e,t){let s=rF(e);if(s?.type!=="json_schema")return null;try{if("parse"in s)return s.parse(t);return JSON.parse(t)}catch(e){throw new se(`Failed to parse structured output: ${e}`)}}(t,e.text);return null===r&&(r=s),Object.defineProperty({...e},"parsed_output",{value:s,enumerable:!1})}return e});return{...e,content:a,parsed_output:r}}rz.Models=ro,rz.Messages=rI,rz.Agents=ru,rz.Environments=rs,rz.Sessions=rU,rz.Vaults=rW,rz.MemoryStores=rp,rz.Files=rl,rz.Skills=rD,rz.UserProfiles=rc;let rJ="__json_buf";function rG(e){return"tool_use"===e.type||"server_tool_use"===e.type}class rK{constructor(e,t){F.add(this),this.messages=[],this.receivedMessages=[],H.set(this,void 0),V.set(this,null),this.controller=new AbortController,J.set(this,void 0),G.set(this,()=>{}),K.set(this,()=>{}),X.set(this,void 0),Y.set(this,()=>{}),Q.set(this,()=>{}),Z.set(this,{}),ee.set(this,!1),et.set(this,!1),es.set(this,!1),er.set(this,!1),ea.set(this,void 0),en.set(this,void 0),ei.set(this,void 0),ec.set(this,e=>{if(t3(this,et,!0,"f"),t7(e)&&(e=new ss),e instanceof ss)return t3(this,es,!0,"f"),this._emit("abort",e);if(e instanceof se)return this._emit("error",e);if(e instanceof Error){let t=new se(e.message);return t.cause=e,this._emit("error",t)}return this._emit("error",new se(String(e)))}),t3(this,J,new Promise((e,t)=>{t3(this,G,e,"f"),t3(this,K,t,"f")}),"f"),t3(this,X,new Promise((e,t)=>{t3(this,Y,e,"f"),t3(this,Q,t,"f")}),"f"),t6(this,J,"f").catch(()=>{}),t6(this,X,"f").catch(()=>{}),t3(this,V,e,"f"),t3(this,ei,t?.logger??console,"f")}get response(){return t6(this,ea,"f")}get request_id(){return t6(this,en,"f")}async withResponse(){t3(this,er,!0,"f");let e=await t6(this,J,"f");if(!e)throw Error("Could not resolve a `Response` object");return{data:this,response:e,request_id:e.headers.get("request-id")}}static fromReadableStream(e){let t=new rK(null);return t._run(()=>t._fromReadableStream(e)),t}static createMessage(e,t,s,{logger:r}={}){let a=new rK(t,{logger:r});for(let e of t.messages)a._addMessageParam(e);return t3(a,V,{...t,stream:!0},"f"),a._run(()=>a._createMessage(e,{...t,stream:!0},{...s,headers:{...s?.headers,"X-Stainless-Helper-Method":"stream"}})),a}_run(e){e().then(()=>{this._emitFinal(),this._emit("end")},t6(this,ec,"f"))}_addMessageParam(e){this.messages.push(e)}_addMessage(e,t=!0){this.receivedMessages.push(e),t&&this._emit("message",e)}async _createMessage(e,t,s){let r,a=s?.signal;a&&(a.aborted&&this.controller.abort(),r=this.controller.abort.bind(this.controller),a.addEventListener("abort",r));try{t6(this,F,"m",ed).call(this);let{response:r,data:a}=await e.create({...t,stream:!0},{...s,signal:this.controller.signal}).withResponse();for await(let e of(this._connected(r),a))t6(this,F,"m",eu).call(this,e);if(a.controller.signal?.aborted)throw new ss;t6(this,F,"m",em).call(this)}finally{a&&r&&a.removeEventListener("abort",r)}}_connected(e){this.ended||(t3(this,ea,e,"f"),t3(this,en,e?.headers.get("request-id"),"f"),t6(this,G,"f").call(this,e),this._emit("connect"))}get ended(){return t6(this,ee,"f")}get errored(){return t6(this,et,"f")}get aborted(){return t6(this,es,"f")}abort(){this.controller.abort()}on(e,t){return(t6(this,Z,"f")[e]||(t6(this,Z,"f")[e]=[])).push({listener:t}),this}off(e,t){let s=t6(this,Z,"f")[e];if(!s)return this;let r=s.findIndex(e=>e.listener===t);return r>=0&&s.splice(r,1),this}once(e,t){return(t6(this,Z,"f")[e]||(t6(this,Z,"f")[e]=[])).push({listener:t,once:!0}),this}emitted(e){return new Promise((t,s)=>{t3(this,er,!0,"f"),"error"!==e&&this.once("error",s),this.once(e,t)})}async done(){t3(this,er,!0,"f"),await t6(this,X,"f")}get currentMessage(){return t6(this,H,"f")}async finalMessage(){return await this.done(),t6(this,F,"m",el).call(this)}async finalText(){return await this.done(),t6(this,F,"m",eo).call(this)}_emit(e,...t){if(t6(this,ee,"f"))return;"end"===e&&(t3(this,ee,!0,"f"),t6(this,Y,"f").call(this));let s=t6(this,Z,"f")[e];if(s&&(t6(this,Z,"f")[e]=s.filter(e=>!e.once),s.forEach(({listener:e})=>e(...t))),"abort"===e){let e=t[0];t6(this,er,"f")||s?.length||Promise.reject(e),t6(this,K,"f").call(this,e),t6(this,Q,"f").call(this,e),this._emit("end");return}if("error"===e){let e=t[0];t6(this,er,"f")||s?.length||Promise.reject(e),t6(this,K,"f").call(this,e),t6(this,Q,"f").call(this,e),this._emit("end")}}_emitFinal(){this.receivedMessages.at(-1)&&this._emit("finalMessage",t6(this,F,"m",el).call(this))}async _fromReadableStream(e,t){let s,r=t?.signal;r&&(r.aborted&&this.controller.abort(),s=this.controller.abort.bind(this.controller),r.addEventListener("abort",s));try{t6(this,F,"m",ed).call(this),this._connected(null);let t=sU.fromReadableStream(e,this.controller);for await(let e of t)t6(this,F,"m",eu).call(this,e);if(t.controller.signal?.aborted)throw new ss;t6(this,F,"m",em).call(this)}finally{r&&s&&r.removeEventListener("abort",s)}}[(H=new WeakMap,V=new WeakMap,J=new WeakMap,G=new WeakMap,K=new WeakMap,X=new WeakMap,Y=new WeakMap,Q=new WeakMap,Z=new WeakMap,ee=new WeakMap,et=new WeakMap,es=new WeakMap,er=new WeakMap,ea=new WeakMap,en=new WeakMap,ei=new WeakMap,ec=new WeakMap,F=new WeakSet,el=function(){if(0===this.receivedMessages.length)throw new se("stream ended without producing a Message with role=assistant");return this.receivedMessages.at(-1)},eo=function(){if(0===this.receivedMessages.length)throw new se("stream ended without producing a Message with role=assistant");let e=this.receivedMessages.at(-1).content.filter(e=>"text"===e.type).map(e=>e.text);if(0===e.length)throw new se("stream ended without producing a content block with type=text");return e.join(" ")},ed=function(){this.ended||t3(this,H,void 0,"f")},eu=function(e){if(this.ended)return;let t=t6(this,F,"m",eh).call(this,e);switch(this._emit("streamEvent",e,t),e.type){case"content_block_delta":{let s=t.content.at(-1);switch(e.delta.type){case"text_delta":"text"===s.type&&this._emit("text",e.delta.text,s.text||"");break;case"citations_delta":"text"===s.type&&this._emit("citation",e.delta.citation,s.citations??[]);break;case"input_json_delta":rG(s)&&s.input&&this._emit("inputJson",e.delta.partial_json,s.input);break;case"thinking_delta":"thinking"===s.type&&this._emit("thinking",e.delta.thinking,s.thinking);break;case"signature_delta":"thinking"===s.type&&this._emit("signature",s.signature);break;default:rX(e.delta)}break}case"message_stop":this._addMessageParam(t),this._addMessage(rH(t,t6(this,V,"f"),{logger:t6(this,ei,"f")}),!0);break;case"content_block_stop":this._emit("contentBlock",t.content.at(-1));break;case"message_start":t3(this,H,t,"f")}},em=function(){if(this.ended)throw new se("stream has ended, this shouldn't happen");let e=t6(this,H,"f");if(!e)throw new se("request ended without sending any chunks");return t3(this,H,void 0,"f"),rH(e,t6(this,V,"f"),{logger:t6(this,ei,"f")})},eh=function(e){let t=t6(this,H,"f");if("message_start"===e.type){if(t)throw new se(`Unexpected event order, got ${e.type} before receiving "message_stop"`);return e.message}if(!t)throw new se(`Unexpected event order, got ${e.type} before "message_start"`);switch(e.type){case"message_stop":case"content_block_stop":return t;case"message_delta":return t.stop_reason=e.delta.stop_reason,t.stop_sequence=e.delta.stop_sequence,t.usage.output_tokens=e.usage.output_tokens,null!=e.usage.input_tokens&&(t.usage.input_tokens=e.usage.input_tokens),null!=e.usage.cache_creation_input_tokens&&(t.usage.cache_creation_input_tokens=e.usage.cache_creation_input_tokens),null!=e.usage.cache_read_input_tokens&&(t.usage.cache_read_input_tokens=e.usage.cache_read_input_tokens),null!=e.usage.server_tool_use&&(t.usage.server_tool_use=e.usage.server_tool_use),t;case"content_block_start":return t.content.push({...e.content_block}),t;case"content_block_delta":{let s=t.content.at(e.index);switch(e.delta.type){case"text_delta":s?.type==="text"&&(t.content[e.index]={...s,text:(s.text||"")+e.delta.text});break;case"citations_delta":s?.type==="text"&&(t.content[e.index]={...s,citations:[...s.citations??[],e.delta.citation]});break;case"input_json_delta":if(s&&rG(s)){let r=s[rJ]||"";r+=e.delta.partial_json;let a={...s};Object.defineProperty(a,rJ,{value:r,enumerable:!1,writable:!0}),r&&(a.input=rj(r)),t.content[e.index]=a}break;case"thinking_delta":s?.type==="thinking"&&(t.content[e.index]={...s,thinking:s.thinking+e.delta.thinking});break;case"signature_delta":s?.type==="thinking"&&(t.content[e.index]={...s,signature:e.delta.signature});break;default:rX(e.delta)}return t}}},Symbol.asyncIterator)](){let e=[],t=[],s=!1;return this.on("streamEvent",s=>{let r=t.shift();r?r.resolve(s):e.push(s)}),this.on("end",()=>{for(let e of(s=!0,t))e.resolve(void 0);t.length=0}),this.on("abort",e=>{for(let r of(s=!0,t))r.reject(e);t.length=0}),this.on("error",e=>{for(let r of(s=!0,t))r.reject(e);t.length=0}),{next:async()=>e.length?{value:e.shift(),done:!1}:s?{value:void 0,done:!0}:new Promise((e,s)=>t.push({resolve:e,reject:s})).then(e=>e?{value:e,done:!1}:{value:void 0,done:!0}),return:async()=>(this.abort(),{value:void 0,done:!0})}}toReadableStream(){return new sU(this[Symbol.asyncIterator].bind(this),this.controller).toReadableStream()}}function rX(e){}class rY extends s6{create(e,t){return this._client.post("/v1/messages/batches",{body:e,...t})}retrieve(e,t){return this._client.get(rt`/v1/messages/batches/${e}`,t)}list(e={},t){return this._client.getAPIList("/v1/messages/batches",sJ,{query:e,...t})}delete(e,t){return this._client.delete(rt`/v1/messages/batches/${e}`,t)}cancel(e,t){return this._client.post(rt`/v1/messages/batches/${e}/cancel`,t)}async results(e,t){let s=await this.retrieve(e);if(!s.results_url)throw new se(`No batch \`results_url\`; Has it finished processing? ${s.processing_status} - ${s.id}`);return this._client.get(s.results_url,{...t,headers:s7([{Accept:"application/binary"},t?.headers]),stream:!0,__binaryResponse:!0})._thenUnwrap((e,t)=>rg.fromResponse(t.response,t.controller))}}class rQ extends s6{constructor(){super(...arguments),this.batches=new rY(this._client)}create(e,t){e.model in rZ&&console.warn(`The model '${e.model}' is deprecated and will reach end-of-life on ${rZ[e.model]} +Please migrate to a newer model. Visit https://docs.anthropic.com/en/docs/resources/model-deprecations for more information.`),r0.includes(e.model)&&e.thinking&&"enabled"===e.thinking.type&&console.warn(`Using Claude with ${e.model} and 'thinking.type=enabled' is deprecated. Use 'thinking.type=adaptive' instead which results in better model performance in our testing: https://platform.claude.com/docs/en/build-with-claude/adaptive-thinking`);let s=this._client._options.timeout;if(!e.stream&&null==s){let t=rx[e.model]??void 0;s=this._client.calculateNonstreamingTimeout(e.max_tokens,t)}let r=ri(e.tools,e.messages);return this._client.post("/v1/messages",{body:e,timeout:s??6e5,...t,headers:s7([r,t?.headers]),stream:e.stream??!1})}parse(e,t){return this.create(e,t).then(t=>rV(t,e,{logger:this._client.logger??console}))}stream(e,t){return rK.createMessage(this,e,t,{logger:this._client.logger??console})}countTokens(e,t){return this._client.post("/v1/messages/count_tokens",{body:e,...t})}}let rZ={"claude-1.3":"November 6th, 2024","claude-1.3-100k":"November 6th, 2024","claude-instant-1.1":"November 6th, 2024","claude-instant-1.1-100k":"November 6th, 2024","claude-instant-1.2":"November 6th, 2024","claude-3-sonnet-20240229":"July 21st, 2025","claude-3-opus-20240229":"January 5th, 2026","claude-2.1":"July 21st, 2025","claude-2.0":"July 21st, 2025","claude-3-7-sonnet-latest":"February 19th, 2026","claude-3-7-sonnet-20250219":"February 19th, 2026","claude-3-5-haiku-latest":"February 19th, 2026","claude-3-5-haiku-20241022":"February 19th, 2026","claude-opus-4-0":"June 15th, 2026","claude-opus-4-20250514":"June 15th, 2026","claude-sonnet-4-0":"June 15th, 2026","claude-sonnet-4-20250514":"June 15th, 2026"},r0=["claude-mythos-preview","claude-opus-4-6"];rQ.Batches=rY;class r1 extends s6{retrieve(e,t={},s){let{betas:r}=t??{};return this._client.get(rt`/v1/models/${e}`,{...s,headers:s7([{...r?.toString()!=null?{"anthropic-beta":r?.toString()}:void 0},s?.headers])})}list(e={},t){let{betas:s,...r}=e??{};return this._client.getAPIList("/v1/models",sJ,{query:r,...t,headers:s7([{...s?.toString()!=null?{"anthropic-beta":s?.toString()}:void 0},t?.headers])})}}class r2 extends s6{create(e,t){let{betas:s,...r}=e;return this._client.post("/v1/complete",{body:r,timeout:this._client._options.timeout??6e5,...t,headers:s7([{...s?.toString()!=null?{"anthropic-beta":s?.toString()}:void 0},t?.headers]),stream:e.stream??!1})}}let r5=e=>void 0!==globalThis.process?globalThis.process.env?.[e]?.trim()||void 0:void 0!==globalThis.Deno&&globalThis.Deno.env?.get?.(e)?.trim()||void 0;class r4{constructor({baseURL:e=r5("ANTHROPIC_BASE_URL"),apiKey:t=r5("ANTHROPIC_API_KEY")??null,authToken:s=r5("ANTHROPIC_AUTH_TOKEN")??null,...r}={}){ep.add(this),ef.set(this,void 0);const a={apiKey:t,authToken:s,...r,baseURL:e||"https://api.anthropic.com"};if(!a.dangerouslyAllowBrowser&&"u">typeof window&&void 0!==window.document&&"u">typeof navigator)throw new se("It looks like you're running in a browser-like environment.\n\nThis is disabled by default, as it risks exposing your secret API credentials to attackers.\nIf you understand the risks and have appropriate mitigations in place,\nyou can set the `dangerouslyAllowBrowser` option to `true`, e.g.,\n\nnew Anthropic({ apiKey, dangerouslyAllowBrowser: true });\n");this.baseURL=a.baseURL,this.timeout=a.timeout??eg.DEFAULT_TIMEOUT,this.logger=a.logger??console;const n="warn";this.logLevel=n,this.logLevel=sP(a.logLevel,"ClientOptions.logLevel",this)??sP(r5("ANTHROPIC_LOG"),"process.env['ANTHROPIC_LOG']",this)??n,this.fetchOptions=a.fetchOptions,this.maxRetries=a.maxRetries??2,this.fetch=a.fetch??function(){if("u">typeof fetch)return fetch;throw Error("`fetch` is not defined as a global; Either pass `fetch` to the client, `new Anthropic({ fetch })` or polyfill the global, `globalThis.fetch = fetch`")}(),t3(this,ef,sk,"f");const i=r5("ANTHROPIC_CUSTOM_HEADERS");if(i){const e={};for(const t of i.split("\n")){const s=t.indexOf(":");s>=0&&(e[t.substring(0,s).trim()]=t.substring(s+1).trim())}a.defaultHeaders={...e,...a.defaultHeaders}}this._options=a,this.apiKey="string"==typeof t?t:null,this.authToken=s}withOptions(e){return new this.constructor({...this._options,baseURL:this.baseURL,maxRetries:this.maxRetries,timeout:this.timeout,logger:this.logger,logLevel:this.logLevel,fetch:this.fetch,fetchOptions:this.fetchOptions,apiKey:this.apiKey,authToken:this.authToken,...e})}defaultQuery(){return this._options.defaultQuery}validateHeaders({values:e,nulls:t}){if(!(e.get("x-api-key")||e.get("authorization")||this.apiKey&&e.get("x-api-key")||t.has("x-api-key")||this.authToken&&e.get("authorization"))&&!t.has("authorization"))throw Error('Could not resolve authentication method. Expected either apiKey or authToken to be set. Or for one of the "X-Api-Key" or "Authorization" headers to be explicitly omitted')}async authHeaders(e){return s7([await this.apiKeyAuth(e),await this.bearerAuth(e)])}async apiKeyAuth(e){if(null!=this.apiKey)return s7([{"X-Api-Key":this.apiKey}])}async bearerAuth(e){if(null!=this.authToken)return s7([{Authorization:`Bearer ${this.authToken}`}])}stringifyQuery(e){return Object.entries(e).filter(([e,t])=>void 0!==t).map(([e,t])=>{if("string"==typeof t||"number"==typeof t||"boolean"==typeof t)return`${encodeURIComponent(e)}=${encodeURIComponent(t)}`;if(null===t)return`${encodeURIComponent(e)}=`;throw new se(`Cannot stringify type ${typeof t}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`)}).join("&")}getUserAgent(){return`${this.constructor.name}/JS ${sb}`}defaultIdempotencyKey(){return`stainless-node-retry-${t8()}`}makeStatusError(e,t,s,r){return st.generate(e,t,s,r)}buildURL(e,t,s){let r=!t6(this,ep,"m",ex).call(this)&&s||this.baseURL,a=new URL(sh.test(e)?e:r+(r.endsWith("/")&&e.startsWith("/")?e.slice(1):e)),n=this.defaultQuery(),i=Object.fromEntries(a.searchParams);return sx(n)&&sx(i)||(t={...i,...n,...t}),"object"==typeof t&&t&&!Array.isArray(t)&&(a.search=this.stringifyQuery(t)),a.toString()}_calculateNonstreamingTimeout(e){if(3600*e/128e3>600)throw new se("Streaming is required for operations that may take longer than 10 minutes. See https://github.com/anthropics/anthropic-sdk-typescript#streaming-responses for more details");return 6e5}async prepareOptions(e){}async prepareRequest(e,{url:t,options:s}){}get(e,t){return this.methodRequest("get",e,t)}post(e,t){return this.methodRequest("post",e,t)}patch(e,t){return this.methodRequest("patch",e,t)}put(e,t){return this.methodRequest("put",e,t)}delete(e,t){return this.methodRequest("delete",e,t)}methodRequest(e,t,s){return this.request(Promise.resolve(s).then(s=>({method:e,path:t,...s})))}request(e,t=null){return new sF(this,this.makeRequest(e,t,void 0))}async makeRequest(e,t,s){let r=await e,a=r.maxRetries??this.maxRetries;null==t&&(t=a),await this.prepareOptions(r);let{req:n,url:i,timeout:l}=await this.buildRequest(r,{retryCount:a-t});await this.prepareRequest(n,{url:i,options:r});let o="log_"+(0x1000000*Math.random()|0).toString(16).padStart(6,"0"),c=void 0===s?"":`, retryOf: ${s}`,d=Date.now();if(s$(this).debug(`[${o}] sending request`,sL({retryOfRequestLogID:s,method:r.method,url:i,options:r,headers:n.headers})),r.signal?.aborted)throw new ss;let u=new AbortController,m=await this.fetchWithTimeout(i,n,l,u).catch(t9),h=Date.now();if(m instanceof globalThis.Error){let e=`retrying, ${t} attempts remaining`;if(r.signal?.aborted)throw new ss;let a=t7(m)||/timed? ?out/i.test(String(m)+("cause"in m?String(m.cause):""));if(t)return s$(this).info(`[${o}] connection ${a?"timed out":"failed"} - ${e}`),s$(this).debug(`[${o}] connection ${a?"timed out":"failed"} (${e})`,sL({retryOfRequestLogID:s,url:i,durationMs:h-d,message:m.message})),this.retryRequest(r,t,s??o);if(s$(this).info(`[${o}] connection ${a?"timed out":"failed"} - error; no more retries left`),s$(this).debug(`[${o}] connection ${a?"timed out":"failed"} (error; no more retries left)`,sL({retryOfRequestLogID:s,url:i,durationMs:h-d,message:m.message})),a)throw new sa;throw new sr({cause:m})}let p=[...m.headers.entries()].filter(([e])=>"request-id"===e).map(([e,t])=>", "+e+": "+JSON.stringify(t)).join(""),g=`[${o}${c}${p}] ${n.method} ${i} ${m.ok?"succeeded":"failed"} with status ${m.status} in ${h-d}ms`;if(!m.ok){let e=await this.shouldRetry(m);if(t&&e){let e=`retrying, ${t} attempts remaining`;return await sS(m.body),s$(this).info(`${g} - ${e}`),s$(this).debug(`[${o}] response error (${e})`,sL({retryOfRequestLogID:s,url:m.url,status:m.status,headers:m.headers,durationMs:h-d})),this.retryRequest(r,t,s??o,m.headers)}let a=e?"error; no more retries left":"error; not retryable";s$(this).info(`${g} - ${a}`);let n=await m.text().catch(e=>t9(e).message),i=sy(n),l=i?void 0:n;throw s$(this).debug(`[${o}] response error (${a})`,sL({retryOfRequestLogID:s,url:m.url,status:m.status,headers:m.headers,message:l,durationMs:Date.now()-d})),this.makeStatusError(m.status,i,l,m.headers)}return s$(this).info(g),s$(this).debug(`[${o}] response start`,sL({retryOfRequestLogID:s,url:m.url,status:m.status,headers:m.headers,durationMs:h-d})),{response:m,options:r,controller:u,requestLogID:o,retryOfRequestLogID:s,startTime:d}}getAPIList(e,t,s){return this.requestAPIList(t,s&&"then"in s?s.then(t=>({method:"get",path:e,...t})):{method:"get",path:e,...s})}requestAPIList(e,t){return new sV(this,this.makeRequest(t,null,void 0),e)}async fetchWithTimeout(e,t,s,r){let{signal:a,method:n,...i}=t||{},l=this._makeAbort(r);a&&a.addEventListener("abort",l,{once:!0});let o=setTimeout(l,s),c=globalThis.ReadableStream&&i.body instanceof globalThis.ReadableStream||"object"==typeof i.body&&null!==i.body&&Symbol.asyncIterator in i.body,d={signal:r.signal,...c?{duplex:"half"}:{},method:"GET",...i};n&&(d.method=n.toUpperCase());try{return await this.fetch.call(void 0,e,d)}finally{clearTimeout(o)}}async shouldRetry(e){let t=e.headers.get("x-should-retry");return"true"===t||"false"!==t&&(408===e.status||409===e.status||429===e.status||!!(e.status>=500))}async retryRequest(e,t,s,r){let a,n,i=r?.get("retry-after-ms");if(i){let e=parseFloat(i);Number.isNaN(e)||(a=e)}let l=r?.get("retry-after");if(l&&!a){let e=parseFloat(l);a=Number.isNaN(e)?Date.parse(l)-Date.now():1e3*e}if(void 0===a){let s=e.maxRetries??this.maxRetries;a=this.calculateDefaultRetryTimeoutMillis(t,s)}return await (n=a,new Promise(e=>setTimeout(e,n))),this.makeRequest(e,t-1,s)}calculateDefaultRetryTimeoutMillis(e,t){return Math.min(.5*Math.pow(2,t-e),8)*(1-.25*Math.random())*1e3}calculateNonstreamingTimeout(e,t){if(36e5*e/128e3>6e5||null!=t&&e>t)throw new se("Streaming is required for operations that may take longer than 10 minutes. See https://github.com/anthropics/anthropic-sdk-typescript#long-requests for more details");return 6e5}async buildRequest(e,{retryCount:t=0}={}){let s={...e},{method:r,path:a,query:n,defaultBaseURL:i}=s,l=this.buildURL(a,n,i);"timeout"in s&&((e,t)=>{if("number"!=typeof t||!Number.isInteger(t))throw new se(`${e} must be an integer`);if(t<0)throw new se(`${e} must be a positive integer`)})("timeout",s.timeout),s.timeout=s.timeout??this.timeout;let{bodyHeaders:o,body:c}=this.buildBody({options:s}),d=await this.buildHeaders({options:e,method:r,bodyHeaders:o,retryCount:t});return{req:{method:r,headers:d,...s.signal&&{signal:s.signal},...globalThis.ReadableStream&&c instanceof globalThis.ReadableStream&&{duplex:"half"},...c&&{body:c},...this.fetchOptions??{},...s.fetchOptions??{}},url:l,timeout:s.timeout}}async buildHeaders({options:e,method:s,bodyHeaders:r,retryCount:a}){let n={};this.idempotencyHeader&&"get"!==s&&(e.idempotencyKey||(e.idempotencyKey=this.defaultIdempotencyKey()),n[this.idempotencyHeader]=e.idempotencyKey);let i=s7([n,{Accept:"application/json","User-Agent":this.getUserAgent(),"X-Stainless-Retry-Count":String(a),...e.timeout?{"X-Stainless-Timeout":String(Math.trunc(e.timeout/1e3))}:{},...t??(t=(()=>{let e="u">typeof Deno&&null!=Deno.build?"deno":"u">typeof EdgeRuntime?"edge":"[object process]"===Object.prototype.toString.call(void 0!==globalThis.process?globalThis.process:0)?"node":"unknown";if("deno"===e)return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":sb,"X-Stainless-OS":sw(Deno.build.os),"X-Stainless-Arch":sv(Deno.build.arch),"X-Stainless-Runtime":"deno","X-Stainless-Runtime-Version":"string"==typeof Deno.version?Deno.version:Deno.version?.deno??"unknown"};if("u">typeof EdgeRuntime)return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":sb,"X-Stainless-OS":"Unknown","X-Stainless-Arch":`other:${EdgeRuntime}`,"X-Stainless-Runtime":"edge","X-Stainless-Runtime-Version":globalThis.process.version};if("node"===e)return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":sb,"X-Stainless-OS":sw(globalThis.process.platform??"unknown"),"X-Stainless-Arch":sv(globalThis.process.arch??"unknown"),"X-Stainless-Runtime":"node","X-Stainless-Runtime-Version":globalThis.process.version??"unknown"};let t=function(){if("u"e.abort()}buildBody({options:{body:e,headers:t}}){if(!e)return{bodyHeaders:void 0,body:void 0};let s=s7([t]);return ArrayBuffer.isView(e)||e instanceof ArrayBuffer||e instanceof DataView||"string"==typeof e&&s.values.has("content-type")||globalThis.Blob&&e instanceof globalThis.Blob||e instanceof FormData||e instanceof URLSearchParams||globalThis.ReadableStream&&e instanceof globalThis.ReadableStream?{bodyHeaders:void 0,body:e}:"object"==typeof e&&(Symbol.asyncIterator in e||Symbol.iterator in e&&"next"in e&&"function"==typeof e.next)?{bodyHeaders:void 0,body:s_(e)}:"object"==typeof e&&"application/x-www-form-urlencoded"===s.values.get("content-type")?{bodyHeaders:{"content-type":"application/x-www-form-urlencoded"},body:this.stringifyQuery(e)}:t6(this,ef,"f").call(this,{body:e,headers:s})}}eg=r4,ef=new WeakMap,ep=new WeakSet,ex=function(){return"https://api.anthropic.com"!==this.baseURL},r4.Anthropic=eg,r4.HUMAN_PROMPT="\\n\\nHuman:",r4.AI_PROMPT="\\n\\nAssistant:",r4.DEFAULT_TIMEOUT=6e5,r4.AnthropicError=se,r4.APIError=st,r4.APIConnectionError=sr,r4.APIConnectionTimeoutError=sa,r4.APIUserAbortError=ss,r4.NotFoundError=so,r4.ConflictError=sc,r4.RateLimitError=su,r4.BadRequestError=sn,r4.AuthenticationError=si,r4.InternalServerError=sm,r4.PermissionDeniedError=sl,r4.UnprocessableEntityError=sd,r4.toFile=s4;class r3 extends r4{constructor(){super(...arguments),this.completions=new r2(this),this.messages=new rQ(this),this.models=new r1(this),this.beta=new rz(this)}}async function r6(e,t,s,r,a=[],n,i,l,o,c,d,u,m,h,p){if(!r)throw Error("Virtual Key is required");console.log=function(){};let g=p||(0,eM.getProxyBaseUrl)(),f={};a&&a.length>0&&(f["x-litellm-tags"]=a.join(","));let x=new r3({apiKey:r,baseURL:g,dangerouslyAllowBrowser:!0,defaultHeaders:f});try{let r=Date.now(),a=!1,h={model:s,messages:e.map(e=>({role:e.role,content:e.content})),stream:!0,max_tokens:1024,litellm_trace_id:c};for await(let e of(d&&(h.vector_store_ids=d),u&&(h.guardrails=u),m&&(h.policies=m),x.messages.stream(h,{signal:n}))){if("content_block_delta"===e.type){let n=e.delta;if(!a){a=!0;let e=Date.now()-r;l&&l(e)}"text_delta"===n.type?t("assistant",n.text,s):"reasoning_delta"===n.type&&i&&i(n.text)}if("message_delta"===e.type&&e.usage&&o){let t=e.usage,s={completionTokens:t.output_tokens,promptTokens:t.input_tokens,totalTokens:t.input_tokens+t.output_tokens};o(s)}}}catch(e){throw n?.aborted||eI.default.fromBackend(`Error occurred while generating model response. Please try again. Error: ${e}`),e}}async function r8(e,t,s,r,a,n,i,l,o,c){console.log=function(){};let d=c||(0,eM.getProxyBaseUrl)(),u=new eq.default.OpenAI({apiKey:a,baseURL:d,dangerouslyAllowBrowser:!0,defaultHeaders:n&&n.length>0?{"x-litellm-tags":n.join(",")}:void 0});try{let a=await u.audio.speech.create({model:r,input:e,voice:t,...l?{response_format:l}:{},...o?{speed:o}:{}},{signal:i}),n=await a.blob(),c=URL.createObjectURL(n);s(c,r)}catch(e){throw i?.aborted||eI.default.fromBackend(`Error occurred while generating speech. Please try again. Error: ${e}`),e}}async function r7(e,t,s,r,a,n,i,l,o,c,d){console.log=function(){};let u=d||(0,eM.getProxyBaseUrl)(),m=new eq.default.OpenAI({apiKey:r,baseURL:u,dangerouslyAllowBrowser:!0,defaultHeaders:a&&a.length>0?{"x-litellm-tags":a.join(",")}:void 0});try{let r=await m.audio.transcriptions.create({model:s,file:e,...i?{language:i}:{},...l?{prompt:l}:{},...o?{response_format:o}:{},...void 0!==c?{temperature:c}:{}},{signal:n});if(r&&r.text)t(r.text,s),eI.default.success("Audio transcribed successfully");else throw Error("No transcription text in response")}catch(e){if(console.error("Error making audio transcription request:",e),n?.aborted);else{let t="Failed to transcribe audio";e?.error?.message?t=e.error.message:e?.message&&(t=e.message),eI.default.fromBackend(`Audio transcription failed: ${t}`)}throw e}}async function r9(e,t,s,r,a,n){if(!r)throw Error("Virtual Key is required");console.log=function(){};let i=n||(0,eM.getProxyBaseUrl)(),l={};a&&a.length>0&&(l["x-litellm-tags"]=a.join(","));try{let a=i.endsWith("/")?i.slice(0,-1):i,n=`${a}/embeddings`,o=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",[(0,eM.getGlobalLitellmHeaderName)()]:`Bearer ${r}`,...l},body:JSON.stringify({model:s,input:e})});if(!o.ok){let e=await o.text();throw Error(e||`Request failed with status ${o.status}`)}let c=await o.json(),d=c?.data?.[0]?.embedding;if(!d)throw Error("No embedding returned from server");t(JSON.stringify(d),c?.model??s)}catch(e){throw eI.default.fromBackend(`Error occurred while making embeddings request. Please try again. Error: ${e}`),e}}async function ae(e,t,s,r,a,n,i,l){console.log=function(){};let o=l||(0,eM.getProxyBaseUrl)(),c=new eq.default.OpenAI({apiKey:a,baseURL:o,dangerouslyAllowBrowser:!0,defaultHeaders:n&&n.length>0?{"x-litellm-tags":n.join(",")}:void 0});try{let a=Array.isArray(e)?e:[e],n=[];for(let e=0;e1&&eI.default.success(`Successfully processed ${n.length} images`)}catch(e){if(console.error("Error making image edit request:",e),i?.aborted);else{let t="Failed to edit image(s)";e?.error?.message?t=e.error.message:e?.message&&(t=e.message),eI.default.fromBackend(`Image edit failed: ${t}`)}throw e}}async function at(e,t,s,r,a,n,i){console.log=function(){};let l=i||(0,eM.getProxyBaseUrl)(),o=new eq.default.OpenAI({apiKey:r,baseURL:l,dangerouslyAllowBrowser:!0,defaultHeaders:a&&a.length>0?{"x-litellm-tags":a.join(",")}:void 0});try{let r=await o.images.generate({model:s,prompt:e},{signal:n});if(r.data&&r.data[0])if(r.data[0].url)t(r.data[0].url,s);else if(r.data[0].b64_json){let e=r.data[0].b64_json;t(`data:image/png;base64,${e}`,s)}else throw Error("No image data found in response");else throw Error("Invalid response format")}catch(e){throw n?.aborted||eI.default.fromBackend(`Error occurred while generating image. Please try again. Error: ${e}`),e}}r3.Completions=r2,r3.Messages=rQ,r3.Models=r1,r3.Beta=rz;var as=e.i(459161);async function ar(e,t,s,r,a,n,i,l){if(!r)throw Error("Virtual Key is required");console.log=function(){};let o=i||(0,eM.getProxyBaseUrl)(),c=o.endsWith("/")?o.slice(0,-1):o,d=`${c}/v1beta/interactions`,u={"Content-Type":"application/json",[(0,eM.getGlobalLitellmHeaderName)()]:`Bearer ${r}`};a&&a.length>0&&(u["x-litellm-tags"]=a.join(","));let m={model:s,input:e,stream:!0};l&&(m.previous_interaction_id=l);try{let e,r=await fetch(d,{method:"POST",headers:u,body:JSON.stringify(m),signal:n});if(!r.ok){let e=await r.text();throw Error(e||`Request failed with status ${r.status}`)}if(!r.body)throw Error("No response body received");let a=r.body.getReader(),i=new TextDecoder,l="";for(;;){let{done:r,value:n}=await a.read();if(r)break;let o=(l+=i.decode(n,{stream:!0})).split("\n");for(let r of(l=o.pop()??"",o)){let a,n=r.trim();if(!n.startsWith("data:"))continue;let i=n.slice(5).trim();if(!i||"[DONE]"===i)continue;try{a=JSON.parse(i)}catch{continue}let l=a.event_type;if("interaction.start"===l||"interaction.complete"===l){let t=a.interaction;"string"==typeof t?.model&&t.model?e=t.model:"string"==typeof a.model&&a.model&&(e=a.model)}else if("content.delta"===l||"content.start"===l){let r=a.delta;"string"==typeof r?.text&&r.text&&t(r.text,e??s)}}}}catch(e){if(n?.aborted)throw e;throw eI.default.fromBackend(`Error occurred while making Interactions API request. Error: ${e}`),e}}var aa=e.i(536916),an=e.i(850627);let ai=({temperature:e=1,maxTokens:t=2048,useAdvancedParams:s,onTemperatureChange:r,onMaxTokensChange:a,onUseAdvancedParamsChange:n,mockTestFallbacks:i,onMockTestFallbacksChange:l})=>{let[o,c]=(0,eb.useState)(!1),d=void 0!==s?s:o,[u,m]=(0,eb.useState)(e),[h,p]=(0,eb.useState)(t);(0,eb.useEffect)(()=>{m(e)},[e]),(0,eb.useEffect)(()=>{p(t)},[t]);let g=e=>{let t=e??1;m(t),r?.(t)},f=e=>{let t=e??1e3;p(t),a?.(t)},x=d?"text-gray-700":"text-gray-400";return(0,ey.jsxs)("div",{className:"space-y-4 p-4 w-80",children:[(0,ey.jsx)(aa.Checkbox,{checked:d,onChange:e=>{var t;return t=e.target.checked,void(n?n(t):c(t))},children:(0,ey.jsx)("span",{className:"font-medium",children:"Use Advanced Parameters"})}),l&&(0,ey.jsxs)("div",{className:"flex items-center gap-1",children:[(0,ey.jsx)(aa.Checkbox,{checked:i??!1,onChange:e=>l(e.target.checked),children:(0,ey.jsx)("span",{className:"font-medium",children:"Simulate failure to test fallbacks"})}),(0,ey.jsx)(tL.Popover,{trigger:"hover",placement:"right",content:(0,ey.jsxs)("div",{style:{maxWidth:340},children:[(0,ey.jsx)(tB.Typography.Paragraph,{className:"text-sm",style:{marginBottom:8},children:"Causes the first request to fail so the router tries fallbacks (if configured). Use this to verify your fallback setup."}),(0,ey.jsxs)(tB.Typography.Paragraph,{className:"text-sm",style:{marginBottom:0},children:["Behavior can differ when keys, teams, or router settings are configured."," ",(0,ey.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/keys_teams_router_settings",target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:text-blue-800",children:"Learn more"})]})]}),children:(0,ey.jsx)(tv.InfoCircleOutlined,{className:"text-xs text-gray-400 cursor-pointer shrink-0 hover:text-gray-600","aria-label":"Help: Simulate failure to test fallbacks"})})]}),(0,ey.jsxs)("div",{className:"space-y-4 transition-opacity duration-200",style:{opacity:d?1:.4},children:[(0,ey.jsxs)("div",{children:[(0,ey.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,ey.jsxs)("div",{className:"flex items-center gap-1",children:[(0,ey.jsx)(tO.Text,{className:`text-sm ${x}`,children:"Temperature"}),(0,ey.jsx)(tU.Tooltip,{title:"Controls randomness. Lower values make output more deterministic, higher values more creative.",children:(0,ey.jsx)(tv.InfoCircleOutlined,{className:`text-xs ${x} cursor-help`})})]}),(0,ey.jsx)(tG.InputNumber,{min:0,max:2,step:.1,value:u,onChange:g,disabled:!d,precision:1,className:"w-20"})]}),(0,ey.jsx)(an.Slider,{min:0,max:2,step:.1,value:u,onChange:g,disabled:!d,marks:{0:"0",1:"1.0",2:"2.0"}})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,ey.jsxs)("div",{className:"flex items-center gap-1",children:[(0,ey.jsx)(tO.Text,{className:`text-sm ${x}`,children:"Max Tokens"}),(0,ey.jsx)(tU.Tooltip,{title:"Maximum number of tokens to generate in the response.",children:(0,ey.jsx)(tv.InfoCircleOutlined,{className:`text-xs ${x} cursor-help`})})]}),(0,ey.jsx)(tG.InputNumber,{min:1,max:32768,step:1,value:h,onChange:f,disabled:!d})]}),(0,ey.jsx)(an.Slider,{min:1,max:32768,step:1,value:h,onChange:f,disabled:!d,marks:{1:"1",32768:"32768"}})]})]})]})};var al=e.i(865361);let ao={ALLOY:"Alloy - Professional and confident",ASH:"Ash - Casual and relaxed",BALAD:"Ballad - Smooth and melodic",CORAL:"Coral - Warm and engaging",ECHO:"Echo - Friendly and conversational",FABLE:"Fable - Wise and measured",NOVA:"Nova - Friendly and conversational",ONYX:"Onyx - Deep and authoritative",SAGE:"Sage - Wise and measured",SHIMMER:"Shimmer - Bright and cheerful"},ac=Object.entries({ALLOY:"alloy",ASH:"ash",BALAD:"ballad",CORAL:"coral",ECHO:"echo",FABLE:"fable",NOVA:"nova",ONYX:"onyx",SAGE:"sage",SHIMMER:"shimmer"}).map(([e,t])=>({value:t,label:ao[e]})),ad=[{value:al.EndpointType.CHAT,label:"/v1/chat/completions"},{value:al.EndpointType.RESPONSES,label:"/v1/responses"},{value:al.EndpointType.ANTHROPIC_MESSAGES,label:"/v1/messages"},{value:al.EndpointType.IMAGE,label:"/v1/images/generations"},{value:al.EndpointType.IMAGE_EDITS,label:"/v1/images/edits"},{value:al.EndpointType.EMBEDDINGS,label:"/v1/embeddings"},{value:al.EndpointType.SPEECH,label:"/v1/audio/speech"},{value:al.EndpointType.TRANSCRIPTION,label:"/v1/audio/transcriptions"},{value:al.EndpointType.A2A_AGENTS,label:"/v1/a2a/message/send"},{value:al.EndpointType.MCP,label:"/mcp-rest/tools/call"},{value:al.EndpointType.REALTIME,label:"/v1/realtime"},{value:al.EndpointType.INTERACTIONS,label:"/v1beta/interactions"}];var au=e.i(955719),au=au;let{Dragger:am}=tD.Upload,ah=({chatUploadedImage:e,chatImagePreviewUrl:t,onImageUpload:s,onRemoveImage:r})=>(0,ey.jsx)(ey.Fragment,{children:!e&&(0,ey.jsx)(am,{beforeUpload:s,accept:"image/*,.pdf",showUploadList:!1,className:"inline-block",style:{padding:0,border:"none",background:"none"},children:(0,ey.jsx)(tU.Tooltip,{title:"Attach image or PDF",children:(0,ey.jsx)("button",{type:"button",className:"flex items-center justify-center w-8 h-8 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-md transition-colors",children:(0,ey.jsx)(au.default,{style:{fontSize:"16px"}})})})})}),ap=async(e,t)=>({role:"user",content:[{type:"text",text:e},{type:"image_url",image_url:{url:await new Promise((e,s)=>{let r=new FileReader;r.onload=()=>{e(r.result)},r.onerror=s,r.readAsDataURL(t)})}}]}),ag=(e,t,s,r)=>{let a="";t&&r&&(a=r.toLowerCase().endsWith(".pdf")?"[PDF attached]":"[Image attached]");let n={role:"user",content:t?`${e} ${a}`:e};return t&&s&&(n.imagePreviewUrl=s),n};var af=e.i(790848),ax=e.i(888259),ay=e.i(270377);let ab=({enabled:e,onEnabledChange:t,selectedModel:s,disabled:r=!1})=>{let a=(e=>{if(!e)return!1;let t=e.toLowerCase();return t.startsWith("openai/")||t.startsWith("gpt-")||t.startsWith("o1")||t.startsWith("o3")||t.includes("openai")})(s);return(0,ey.jsxs)("div",{className:"border border-gray-200 rounded-lg p-3 bg-linear-to-r from-blue-50 to-purple-50",children:[(0,ey.jsxs)("div",{className:"flex items-center justify-between",children:[(0,ey.jsxs)("div",{className:"flex items-center gap-2",children:[(0,ey.jsx)(ty.CodeOutlined,{className:"text-blue-500"}),(0,ey.jsx)(tO.Text,{className:"font-medium text-gray-700",children:"Code Interpreter"}),(0,ey.jsx)(tU.Tooltip,{title:"Run Python code to generate files, charts, and analyze data. Container is created automatically.",children:(0,ey.jsx)(tv.InfoCircleOutlined,{className:"text-gray-400 text-xs"})})]}),(0,ey.jsx)(af.Switch,{checked:e&&a,onChange:e=>{e&&!a?ax.default.warning("Code Interpreter is only available for OpenAI models"):t(e)},disabled:r||!a,size:"small",className:e&&a?"bg-blue-500":""})]}),!a&&(0,ey.jsx)("div",{className:"mt-2 pt-2 border-t border-gray-200",children:(0,ey.jsxs)("div",{className:"flex items-start gap-2",children:[(0,ey.jsx)(ay.ExclamationCircleOutlined,{className:"text-amber-500 mt-0.5"}),(0,ey.jsxs)("div",{className:"text-xs text-gray-600",children:[(0,ey.jsx)("span",{children:"Code Interpreter is currently only supported for OpenAI models. "}),(0,ey.jsx)("a",{href:"https://github.com/BerriAI/litellm/issues/new?template=feature_request.yml",target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:text-blue-800 underline",children:"Request support for other providers"})]})]})})]})};var av=e.i(339019);let aw=({endpointType:e,onEndpointChange:t,className:s})=>(0,ey.jsx)("div",{className:s,children:(0,ey.jsx)(eA.Select,{showSearch:!0,value:e,style:{width:"100%"},onChange:t,options:ad,className:"rounded-md",filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase())||(t?.value??"").toLowerCase().includes(e.toLowerCase())})});var aj=e.i(91500);let a_=function({file:e,previewUrl:t,onRemove:s}){let r=e.name.toLowerCase().endsWith(".pdf");return(0,ey.jsx)("div",{className:"mb-2",children:(0,ey.jsxs)("div",{className:"flex items-center gap-3 p-3 bg-gray-50 rounded-lg border border-gray-200",children:[(0,ey.jsx)("div",{className:"relative inline-block",children:r?(0,ey.jsx)("div",{className:"w-10 h-10 rounded-md bg-red-500 flex items-center justify-center",children:(0,ey.jsx)(aj.FilePdfOutlined,{style:{fontSize:"16px",color:"white"}})}):(0,ey.jsx)("img",{src:t||"",alt:"Upload preview",className:"w-10 h-10 rounded-md border border-gray-200 object-cover"})}),(0,ey.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,ey.jsx)("div",{className:"text-sm font-medium text-gray-900 truncate",children:e.name}),(0,ey.jsx)("div",{className:"text-xs text-gray-500",children:r?"PDF":"Image"})]}),(0,ey.jsx)("button",{className:"flex items-center justify-center w-6 h-6 text-gray-400 hover:text-gray-600 hover:bg-gray-200 rounded-full transition-colors",onClick:s,children:(0,ey.jsx)(ew.DeleteOutlined,{style:{fontSize:"12px"}})})]})})};var aN=e.i(771674),aS=e.i(918789),ak=e.i(245704),aC=e.i(637235),aT=e.i(166406),aE=e.i(755151),aA=e.i(240647),aP=e.i(993914);let aR=(e,t=8)=>e?e.length>t?`${e.substring(0,t)}…`:e:null,aO=e=>{navigator.clipboard.writeText(e)},aI=({a2aMetadata:e,timeToFirstToken:t,totalLatency:s})=>{let[r,a]=(0,eb.useState)(!1);if(!e&&!t&&!s)return null;let{taskId:n,contextId:i,status:l,metadata:o}=e||{},c=(e=>{if(!e)return null;try{return new Date(e).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}catch{return e}})(l?.timestamp);return(0,ey.jsxs)("div",{className:"a2a-metrics mt-3 pt-2 border-t border-gray-200 text-xs",children:[(0,ey.jsxs)("div",{className:"flex items-center mb-2 text-gray-600",children:[(0,ey.jsx)(eS.RobotOutlined,{className:"mr-1.5 text-blue-500"}),(0,ey.jsx)("span",{className:"font-medium text-gray-700",children:"A2A Metadata"})]}),(0,ey.jsxs)("div",{className:"flex flex-wrap items-center gap-2 text-gray-500 ml-4",children:[l?.state&&(0,ey.jsxs)("span",{className:`inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${(e=>{switch(e){case"completed":return"bg-green-100 text-green-700";case"working":case"submitted":return"bg-blue-100 text-blue-700";case"failed":case"canceled":return"bg-red-100 text-red-700";default:return"bg-gray-100 text-gray-700"}})(l.state)}`,children:[(e=>{switch(e){case"completed":return(0,ey.jsx)(ak.CheckCircleOutlined,{className:"text-green-500"});case"working":case"submitted":return(0,ey.jsx)(tj.LoadingOutlined,{className:"text-blue-500"});case"failed":case"canceled":return(0,ey.jsx)(ay.ExclamationCircleOutlined,{className:"text-red-500"});default:return(0,ey.jsx)(aC.ClockCircleOutlined,{className:"text-gray-500"})}})(l.state),(0,ey.jsx)("span",{className:"ml-1 capitalize",children:l.state})]}),c&&(0,ey.jsx)(tU.Tooltip,{title:l?.timestamp,children:(0,ey.jsxs)("span",{className:"flex items-center",children:[(0,ey.jsx)(aC.ClockCircleOutlined,{className:"mr-1"}),c]})}),void 0!==s&&(0,ey.jsx)(tU.Tooltip,{title:"Total latency",children:(0,ey.jsxs)("span",{className:"flex items-center text-blue-600",children:[(0,ey.jsx)(aC.ClockCircleOutlined,{className:"mr-1"}),(s/1e3).toFixed(2),"s"]})}),void 0!==t&&(0,ey.jsx)(tU.Tooltip,{title:"Time to first token",children:(0,ey.jsxs)("span",{className:"flex items-center text-green-600",children:["TTFT: ",(t/1e3).toFixed(2),"s"]})})]}),(0,ey.jsxs)("div",{className:"flex flex-wrap items-center gap-3 text-gray-500 ml-4 mt-1.5",children:[n&&(0,ey.jsx)(tU.Tooltip,{title:`Click to copy: ${n}`,children:(0,ey.jsxs)("span",{className:"flex items-center cursor-pointer hover:text-gray-700",onClick:()=>aO(n),children:[(0,ey.jsx)(aP.FileTextOutlined,{className:"mr-1"}),"Task: ",aR(n),(0,ey.jsx)(aT.CopyOutlined,{className:"ml-1 text-gray-400 hover:text-gray-600"})]})}),i&&(0,ey.jsx)(tU.Tooltip,{title:`Click to copy: ${i}`,children:(0,ey.jsxs)("span",{className:"flex items-center cursor-pointer hover:text-gray-700",onClick:()=>aO(i),children:[(0,ey.jsx)(e_.LinkOutlined,{className:"mr-1"}),"Session: ",aR(i),(0,ey.jsx)(aT.CopyOutlined,{className:"ml-1 text-gray-400 hover:text-gray-600"})]})}),(o||l?.message)&&(0,ey.jsxs)(eC.Button,{type:"text",size:"small",className:"text-xs text-blue-500 hover:text-blue-700 p-0 h-auto",onClick:()=>a(!r),children:[r?(0,ey.jsx)(aE.DownOutlined,{}):(0,ey.jsx)(aA.RightOutlined,{}),(0,ey.jsx)("span",{className:"ml-1",children:"Details"})]})]}),r&&(0,ey.jsxs)("div",{className:"mt-2 ml-4 p-3 bg-gray-50 rounded-md text-gray-600 border border-gray-200",children:[l?.message&&(0,ey.jsxs)("div",{className:"mb-2",children:[(0,ey.jsx)("span",{className:"font-medium text-gray-700",children:"Status Message:"}),(0,ey.jsx)("span",{className:"ml-2",children:l.message})]}),n&&(0,ey.jsxs)("div",{className:"mb-1.5 flex items-center",children:[(0,ey.jsx)("span",{className:"font-medium text-gray-700 w-24",children:"Task ID:"}),(0,ey.jsx)("code",{className:"ml-2 px-2 py-1 bg-white border border-gray-200 rounded-sm text-xs font-mono",children:n}),(0,ey.jsx)(aT.CopyOutlined,{className:"ml-2 cursor-pointer text-gray-400 hover:text-blue-500",onClick:()=>aO(n)})]}),i&&(0,ey.jsxs)("div",{className:"mb-1.5 flex items-center",children:[(0,ey.jsx)("span",{className:"font-medium text-gray-700 w-24",children:"Session ID:"}),(0,ey.jsx)("code",{className:"ml-2 px-2 py-1 bg-white border border-gray-200 rounded-sm text-xs font-mono",children:i}),(0,ey.jsx)(aT.CopyOutlined,{className:"ml-2 cursor-pointer text-gray-400 hover:text-blue-500",onClick:()=>aO(i)})]}),o&&Object.keys(o).length>0&&(0,ey.jsxs)("div",{className:"mt-3",children:[(0,ey.jsx)("span",{className:"font-medium text-gray-700",children:"Custom Metadata:"}),(0,ey.jsx)("pre",{className:"mt-1.5 p-2 bg-white border border-gray-200 rounded-sm text-xs font-mono overflow-x-auto whitespace-pre-wrap",children:JSON.stringify(o,null,2)})]})]})]})},aM=({message:e})=>e.isAudio&&"string"==typeof e.content?(0,ey.jsx)("div",{className:"mb-2",children:(0,ey.jsx)("audio",{controls:!0,src:e.content,className:"max-w-full",style:{maxWidth:"500px"},children:"Your browser does not support the audio element."})}):null;var a$=e.i(657688);let aL=({message:e})=>{if(!("user"===e.role&&"string"==typeof e.content&&(e.content.includes("[Image attached]")||e.content.includes("[PDF attached]"))&&e.imagePreviewUrl))return null;let t="string"==typeof e.content&&e.content.includes("[PDF attached]");return(0,ey.jsx)("div",{className:"mb-2",children:t?(0,ey.jsx)("div",{className:"w-64 h-32 rounded-md border border-gray-200 bg-red-50 flex items-center justify-center",children:(0,ey.jsx)(aj.FilePdfOutlined,{style:{fontSize:"48px",color:"#dc2626"}})}):(0,ey.jsx)(a$.default,{src:e.imagePreviewUrl||"",alt:"User uploaded image",width:256,height:200,className:"max-w-64 rounded-md border border-gray-200 shadow-xs",style:{maxHeight:"200px",width:"auto",height:"auto"}})})};var aU=e.i(362024),aB=e.i(737434);let aD={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M553.1 509.1l-77.8 99.2-41.1-52.4a8 8 0 00-12.6 0l-99.8 127.2a7.98 7.98 0 006.3 12.9H696c6.7 0 10.4-7.7 6.3-12.9l-136.5-174a8.1 8.1 0 00-12.7 0zM360 442a40 40 0 1080 0 40 40 0 10-80 0zm494.6-153.4L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"}}]},name:"file-image",theme:"outlined"};var aq=eb.forwardRef(function(e,t){return eb.createElement(tS.default,(0,t_.default)({},e,{ref:t,icon:aD}))});let aW=({code:e,containerId:t,annotations:s=[],accessToken:r})=>{let[a,n]=(0,eb.useState)({}),[i,l]=(0,eb.useState)({}),o=(0,eM.getProxyBaseUrl)();(0,eb.useEffect)(()=>{let e=async()=>{for(let e of s)if((e.filename?.toLowerCase().endsWith(".png")||e.filename?.toLowerCase().endsWith(".jpg")||e.filename?.toLowerCase().endsWith(".jpeg")||e.filename?.toLowerCase().endsWith(".gif"))&&e.container_id&&e.file_id){l(t=>({...t,[e.file_id]:!0}));try{let t=await fetch(`${o}/v1/containers/${e.container_id}/files/${e.file_id}/content`,{headers:{[(0,eM.getGlobalLitellmHeaderName)()]:`Bearer ${r}`}});if(t.ok){let s=await t.blob(),r=URL.createObjectURL(s);n(t=>({...t,[e.file_id]:r}))}}catch(e){console.error("Error fetching image:",e)}finally{l(t=>({...t,[e.file_id]:!1}))}}};return s.length>0&&r&&e(),()=>{Object.values(a).forEach(e=>URL.revokeObjectURL(e))}},[s,r,o]);let c=async e=>{try{let t=await fetch(`${o}/v1/containers/${e.container_id}/files/${e.file_id}/content`,{headers:{[(0,eM.getGlobalLitellmHeaderName)()]:`Bearer ${r}`}});if(t.ok){let s=await t.blob(),r=URL.createObjectURL(s),a=document.createElement("a");a.href=r,a.download=e.filename||`file_${e.file_id}`,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(r)}}catch(e){console.error("Error downloading file:",e)}},d=s.filter(e=>e.filename?.toLowerCase().endsWith(".png")||e.filename?.toLowerCase().endsWith(".jpg")||e.filename?.toLowerCase().endsWith(".jpeg")||e.filename?.toLowerCase().endsWith(".gif")),u=s.filter(e=>!e.filename?.toLowerCase().endsWith(".png")&&!e.filename?.toLowerCase().endsWith(".jpg")&&!e.filename?.toLowerCase().endsWith(".jpeg")&&!e.filename?.toLowerCase().endsWith(".gif"));return e||0!==s.length?(0,ey.jsxs)("div",{className:"mt-3 space-y-3",children:[e&&(0,ey.jsx)(aU.Collapse,{size:"small",items:[{key:"code",label:(0,ey.jsxs)("span",{className:"flex items-center gap-2 text-sm text-gray-600",children:[(0,ey.jsx)(ty.CodeOutlined,{})," Python Code Executed"]}),children:(0,ey.jsx)(tq.Prism,{language:"python",style:tW.coy,customStyle:{margin:0,borderRadius:"6px",fontSize:"12px",maxHeight:"300px",overflow:"auto"},children:e})}]}),d.map(e=>(0,ey.jsx)("div",{className:"rounded-lg border border-gray-200 overflow-hidden",children:i[e.file_id]?(0,ey.jsxs)("div",{className:"flex items-center justify-center p-8 bg-gray-50",children:[(0,ey.jsx)(eP.Spin,{indicator:(0,ey.jsx)(tj.LoadingOutlined,{spin:!0})}),(0,ey.jsx)("span",{className:"ml-2 text-sm text-gray-500",children:"Loading image..."})]}):a[e.file_id]?(0,ey.jsxs)("div",{children:[(0,ey.jsx)("img",{src:a[e.file_id],alt:e.filename||"Generated chart",className:"max-w-full",style:{maxHeight:"400px"}}),(0,ey.jsxs)("div",{className:"flex items-center justify-between px-3 py-2 bg-gray-50 border-t border-gray-200",children:[(0,ey.jsxs)("span",{className:"text-xs text-gray-500 flex items-center gap-1",children:[(0,ey.jsx)(aq,{})," ",e.filename]}),(0,ey.jsxs)("button",{onClick:()=>c(e),className:"text-xs text-blue-500 hover:text-blue-700 flex items-center gap-1",children:[(0,ey.jsx)(aB.DownloadOutlined,{})," Download"]})]})]}):(0,ey.jsx)("div",{className:"flex items-center justify-center p-4 bg-gray-50",children:(0,ey.jsx)("span",{className:"text-sm text-gray-400",children:"Image not available"})})},e.file_id)),u.length>0&&(0,ey.jsx)("div",{className:"flex flex-wrap gap-2",children:u.map(e=>(0,ey.jsxs)("button",{onClick:()=>c(e),className:"flex items-center gap-2 px-3 py-2 bg-gray-50 border border-gray-200 rounded-lg hover:bg-gray-100 transition-colors",children:[(0,ey.jsx)(aP.FileTextOutlined,{className:"text-blue-500"}),(0,ey.jsx)("span",{className:"text-sm",children:e.filename}),(0,ey.jsx)(aB.DownloadOutlined,{className:"text-gray-400"})]},e.file_id))})]}):null};var az=e.i(499569),aF=e.i(936772),aH=e.i(285903);let aV=async(e,t)=>{let s=await new Promise((e,s)=>{let r=new FileReader;r.onload=()=>{e(r.result.split(",")[1])},r.onerror=s,r.readAsDataURL(t)}),r=t.type||(t.name.toLowerCase().endsWith(".pdf")?"application/pdf":"image/jpeg");return{role:"user",content:[{type:"input_text",text:e},{type:"input_image",image_url:`data:${r};base64,${s}`}]}},aJ=(e,t,s,r)=>{let a="";t&&r&&(a=r.toLowerCase().endsWith(".pdf")?"[PDF attached]":"[Image attached]");let n={role:"user",content:t?`${e} ${a}`:e};return t&&s&&(n.imagePreviewUrl=s),n},aG=({message:e})=>{if(!("user"===e.role&&"string"==typeof e.content&&(e.content.includes("[Image attached]")||e.content.includes("[PDF attached]"))&&e.imagePreviewUrl))return null;let t="string"==typeof e.content&&e.content.includes("[PDF attached]");return(0,ey.jsx)("div",{className:"mb-2",children:t?(0,ey.jsx)("div",{className:"w-64 h-32 rounded-md border border-gray-200 bg-red-50 flex items-center justify-center",children:(0,ey.jsx)(aj.FilePdfOutlined,{style:{fontSize:"48px",color:"#dc2626"}})}):(0,ey.jsx)("img",{src:e.imagePreviewUrl,alt:"User uploaded image",className:"max-w-64 rounded-md border border-gray-200 shadow-xs",style:{maxHeight:"200px"}})})};function aK({searchResults:e}){let[t,s]=(0,eb.useState)(!0),[r,a]=(0,eb.useState)({});if(!e||0===e.length)return null;let n=e.reduce((e,t)=>e+t.data.length,0);return(0,ey.jsxs)("div",{className:"search-results-content mt-1 mb-2",children:[(0,ey.jsxs)(eC.Button,{type:"text",className:"flex items-center text-xs text-gray-500 hover:text-gray-700",onClick:()=>s(!t),icon:(0,ey.jsx)(tb.DatabaseOutlined,{}),children:[t?"Hide sources":`Show sources (${n})`,t?(0,ey.jsx)(aE.DownOutlined,{className:"ml-1"}):(0,ey.jsx)(aA.RightOutlined,{className:"ml-1"})]}),t&&(0,ey.jsx)("div",{className:"mt-2 p-3 bg-gray-50 border border-gray-200 rounded-md text-sm",children:(0,ey.jsx)("div",{className:"space-y-3",children:e.map((e,t)=>(0,ey.jsxs)("div",{children:[(0,ey.jsxs)("div",{className:"text-xs text-gray-600 mb-2 flex items-center gap-2",children:[(0,ey.jsx)("span",{className:"font-medium",children:"Query:"}),(0,ey.jsxs)("span",{className:"italic",children:['"',e.search_query,'"']}),(0,ey.jsx)("span",{className:"text-gray-400",children:"•"}),(0,ey.jsxs)("span",{className:"text-gray-500",children:[e.data.length," result",1!==e.data.length?"s":""]})]}),(0,ey.jsx)("div",{className:"space-y-2",children:e.data.map((e,s)=>{let n=r[`${t}-${s}`]||!1;return(0,ey.jsxs)("div",{className:"border border-gray-200 rounded-md overflow-hidden bg-white",children:[(0,ey.jsx)("div",{className:"flex items-center justify-between p-2 cursor-pointer hover:bg-gray-50 transition-colors",onClick:()=>{let e;return e=`${t}-${s}`,void a(t=>({...t,[e]:!t[e]}))},children:(0,ey.jsxs)("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:[(0,ey.jsx)("svg",{className:`w-4 h-4 text-gray-400 transition-transform shrink-0 ${n?"transform rotate-90":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,ey.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})}),(0,ey.jsx)(aP.FileTextOutlined,{className:"text-gray-400 shrink-0",style:{fontSize:"12px"}}),(0,ey.jsx)("span",{className:"text-xs font-medium text-gray-700 truncate",children:e.filename||e.file_id||`Result ${s+1}`}),(0,ey.jsx)("span",{className:"text-xs px-2 py-0.5 rounded-sm bg-blue-100 text-blue-700 font-mono shrink-0",children:e.score.toFixed(3)})]})}),n&&(0,ey.jsx)("div",{className:"border-t border-gray-200 bg-white",children:(0,ey.jsxs)("div",{className:"p-3 space-y-2",children:[e.content.map((e,t)=>(0,ey.jsx)("div",{children:(0,ey.jsx)("div",{className:"text-xs font-mono bg-gray-50 p-2 rounded-sm text-gray-800 whitespace-pre-wrap wrap-break-word",children:e.text})},t)),e.attributes&&Object.keys(e.attributes).length>0&&(0,ey.jsxs)("div",{className:"mt-2 pt-2 border-t border-gray-100",children:[(0,ey.jsx)("div",{className:"text-xs text-gray-500 mb-1 font-medium",children:"Metadata:"}),(0,ey.jsx)("div",{className:"space-y-1",children:Object.entries(e.attributes).map(([e,t])=>(0,ey.jsxs)("div",{className:"text-xs flex gap-2",children:[(0,ey.jsxs)("span",{className:"text-gray-500 font-medium",children:[e,":"]}),(0,ey.jsx)("span",{className:"text-gray-700 font-mono break-all",children:String(t)})]},e))})]})]})})]},s)})})]},t))})})]})}let aX=function({message:e,isLastMessage:t,endpointType:s,mcpEvents:r,codeInterpreterResult:a,accessToken:n}){let i="user"===e.role;return(0,ey.jsx)("div",{className:`mb-4 ${i?"text-right":"text-left"}`,children:(0,ey.jsxs)("div",{className:"inline-block max-w-[80%] rounded-lg shadow-xs p-3.5 px-4",style:{backgroundColor:i?"#f0f8ff":"#ffffff",border:i?"1px solid #e6f0fa":"1px solid #f0f0f0",textAlign:"left"},children:[(0,ey.jsxs)("div",{className:"flex items-center gap-2 mb-1.5",children:[(0,ey.jsx)("div",{className:"flex items-center justify-center w-6 h-6 rounded-full mr-1",style:{backgroundColor:i?"#e6f0fa":"#f5f5f5"},children:i?(0,ey.jsx)(aN.UserOutlined,{style:{fontSize:"12px",color:"#2563eb"}}):(0,ey.jsx)(eS.RobotOutlined,{style:{fontSize:"12px",color:"#4b5563"}})}),(0,ey.jsx)("strong",{className:"text-sm capitalize",children:e.role}),"assistant"===e.role&&e.model&&(0,ey.jsx)("span",{className:"text-xs px-2 py-0.5 rounded-sm bg-gray-100 text-gray-600 font-normal",children:e.model})]}),e.reasoningContent&&(0,ey.jsx)(aF.default,{reasoningContent:e.reasoningContent}),"assistant"===e.role&&t&&r.length>0&&(s===al.EndpointType.RESPONSES||s===al.EndpointType.CHAT)&&(0,ey.jsx)("div",{className:"mb-3",children:(0,ey.jsx)(az.default,{events:r})}),"assistant"===e.role&&e.searchResults&&(0,ey.jsx)(aK,{searchResults:e.searchResults}),"assistant"===e.role&&t&&a&&s===al.EndpointType.RESPONSES&&(0,ey.jsx)(aW,{code:a.code,containerId:a.containerId,annotations:a.annotations,accessToken:n}),(0,ey.jsxs)("div",{className:"whitespace-pre-wrap wrap-break-word max-w-full message-content",style:{wordWrap:"break-word",overflowWrap:"break-word",wordBreak:"break-word",hyphens:"auto"},children:[e.isImage?(0,ey.jsx)("img",{src:"string"==typeof e.content?e.content:"",alt:"Generated image",className:"max-w-full rounded-md border border-gray-200 shadow-xs",style:{maxHeight:"500px"}}):e.isAudio?(0,ey.jsx)(aM,{message:e}):(0,ey.jsxs)(ey.Fragment,{children:[s===al.EndpointType.RESPONSES&&(0,ey.jsx)(aG,{message:e}),s===al.EndpointType.CHAT&&(0,ey.jsx)(aL,{message:e}),(0,ey.jsx)(aS.default,{components:{code({node:e,inline:t,className:s,children:r,...a}){let n=/language-(\w+)/.exec(s||"");return!t&&n?(0,ey.jsx)(tq.Prism,{style:tW.coy,language:n[1],PreTag:"div",className:"rounded-md my-2",wrapLines:!0,wrapLongLines:!0,...a,children:String(r).replace(/\n$/,"")}):(0,ey.jsx)("code",{className:`${s} px-1.5 py-0.5 rounded-sm bg-gray-100 text-sm font-mono`,style:{wordBreak:"break-word"},...a,children:r})},pre:({node:e,...t})=>(0,ey.jsx)("pre",{style:{overflowX:"auto",maxWidth:"100%"},...t})},children:"string"==typeof e.content?e.content:""}),e.image&&(0,ey.jsx)("div",{className:"mt-3",children:(0,ey.jsx)("img",{src:e.image.url,alt:"Generated image",className:"max-w-full rounded-md border border-gray-200 shadow-xs",style:{maxHeight:"500px"}})})]}),"assistant"===e.role&&(e.timeToFirstToken||e.totalLatency||e.usage)&&!e.a2aMetadata&&(0,ey.jsx)(aH.default,{timeToFirstToken:e.timeToFirstToken,totalLatency:e.totalLatency,usage:e.usage,toolName:e.toolName}),"assistant"===e.role&&e.a2aMetadata&&(0,ey.jsx)(aI,{a2aMetadata:e.a2aMetadata,timeToFirstToken:e.timeToFirstToken,totalLatency:e.totalLatency})]})]})})};var au=au;let{Dragger:aY}=tD.Upload,aQ=({responsesUploadedImage:e,responsesImagePreviewUrl:t,onImageUpload:s,onRemoveImage:r})=>(0,ey.jsx)(ey.Fragment,{children:!e&&(0,ey.jsx)(aY,{beforeUpload:s,accept:"image/*,.pdf",showUploadList:!1,className:"inline-block",style:{padding:0,border:"none",background:"none"},children:(0,ey.jsx)(tU.Tooltip,{title:"Attach image or PDF",children:(0,ey.jsx)("button",{type:"button",className:"flex items-center justify-center w-8 h-8 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-md transition-colors",children:(0,ey.jsx)(au.default,{style:{fontSize:"16px"}})})})})}),aZ=({endpointType:e,responsesSessionId:t,useApiSessionManagement:s,onToggleSessionManagement:r})=>e!==al.EndpointType.RESPONSES?null:(0,ey.jsxs)("div",{className:"mb-4",children:[(0,ey.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,ey.jsxs)("div",{className:"flex items-center gap-2",children:[(0,ey.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Session Management"}),(0,ey.jsx)(tU.Tooltip,{title:"Choose between LiteLLM API session management (using previous_response_id) or UI-based session management (using chat history)",children:(0,ey.jsx)(tv.InfoCircleOutlined,{className:"text-gray-400",style:{fontSize:"12px"}})})]}),(0,ey.jsx)(af.Switch,{checked:s,onChange:r,checkedChildren:"API",unCheckedChildren:"UI",size:"small"})]}),(0,ey.jsxs)("div",{className:`text-xs p-2 rounded-md ${t?"bg-green-50 text-green-700 border border-green-200":"bg-blue-50 text-blue-700 border border-blue-200"}`,children:[(0,ey.jsxs)("div",{className:"flex items-center justify-between",children:[(0,ey.jsxs)("div",{className:"flex items-center gap-1",children:[(0,ey.jsx)(tv.InfoCircleOutlined,{style:{fontSize:"12px"}}),(()=>{if(!t)return s?"API Session: Ready":"UI Session: Ready";let e=s?"Response ID":"UI Session",r=t.slice(0,10);return`${e}: ${r}...`})()]}),t&&(0,ey.jsx)(tU.Tooltip,{title:(0,ey.jsxs)("div",{className:"text-xs",children:[(0,ey.jsx)("div",{className:"mb-1",children:"Copy response ID to continue session:"}),(0,ey.jsx)("div",{className:"bg-gray-800 text-gray-100 p-2 rounded-sm font-mono text-xs whitespace-pre-wrap",children:`curl -X POST "your-proxy-url/v1/responses" \\ + -H "Authorization: Bearer your-api-key" \\ + -H "Content-Type: application/json" \\ + -d '{ + "model": "your-model", + "input": [{"role": "user", "content": "your message", "type": "message"}], + "previous_response_id": "${t}", + "stream": true + }'`})]}),overlayStyle:{maxWidth:"500px"},children:(0,ey.jsx)("button",{onClick:()=>{t&&(navigator.clipboard.writeText(t),eI.default.success("Response ID copied to clipboard!"))},className:"ml-2 p-1 hover:bg-green-100 rounded-sm transition-colors",children:(0,ey.jsx)(aT.CopyOutlined,{style:{fontSize:"12px"}})})})]}),(0,ey.jsx)("div",{className:"text-xs opacity-75 mt-1",children:t?s?"LiteLLM API session active - context maintained server-side":"UI session active - context maintained client-side":s?"LiteLLM will manage session using previous_response_id":"UI will manage session using chat history"})]})]});var a0={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"defs",attrs:{},children:[{tag:"style",attrs:{}}]},{tag:"path",attrs:{d:"M682 455V311l-76 76v68c-.1 50.7-42 92.1-94 92a95.8 95.8 0 01-52-15l-54 55c29.1 22.4 65.9 36 106 36 93.8 0 170-75.1 170-168z"}},{tag:"path",attrs:{d:"M833 446h-60c-4.4 0-8 3.6-8 8 0 140.3-113.7 254-254 254-63 0-120.7-23-165-61l-54 54a334.01 334.01 0 00179 81v102H326c-13.9 0-24.9 14.3-25 32v36c.1 4.4 2.9 8 6 8h408c3.2 0 6-3.6 6-8v-36c0-17.7-11-32-25-32H547V782c165.3-17.9 294-157.9 294-328 0-4.4-3.6-8-8-8zm13.1-377.7l-43.5-41.9a8 8 0 00-11.2.1l-129 129C634.3 101.2 577 64 511 64c-93.9 0-170 75.3-170 168v224c0 6.7.4 13.3 1.2 19.8l-68 68A252.33 252.33 0 01258 454c-.2-4.4-3.8-8-8-8h-60c-4.4 0-8 3.6-8 8 0 53 12.5 103 34.6 147.4l-137 137a8.03 8.03 0 000 11.3l42.7 42.7c3.1 3.1 8.2 3.1 11.3 0L846.2 79.8l.1-.1c3.1-3.2 3-8.3-.2-11.4zM417 401V232c0-50.6 41.9-92 94-92 46 0 84.1 32.3 92.3 74.7L417 401z"}}]},name:"audio-muted",theme:"outlined"},a1=eb.forwardRef(function(e,t){return eb.createElement(tS.default,(0,t_.default)({},e,{ref:t,icon:a0}))}),a2=e.i(793916),a5=e.i(518617),a4=e.i(84899);let{Text:a3}=tB.Typography,a6=({accessToken:e,selectedModel:t,customProxyBaseUrl:s,selectedGuardrails:r})=>{let[a,n]=(0,eb.useState)([]),[i,l]=(0,eb.useState)(""),[o,c]=(0,eb.useState)(!1),[d,u]=(0,eb.useState)(!1),[m,h]=(0,eb.useState)(!1),[p,g]=(0,eb.useState)("alloy"),f=(0,eb.useRef)(null),x=(0,eb.useRef)(null),y=(0,eb.useRef)(null),b=(0,eb.useRef)(null);(0,eb.useRef)([]),(0,eb.useRef)(!1);let v=(0,eb.useRef)(null),w=(0,eb.useRef)(0),j=(0,eb.useCallback)(()=>{v.current?.scrollIntoView({behavior:"smooth"})},[]);(0,eb.useEffect)(()=>{j()},[a,j]);let _=(0,eb.useCallback)((e,t)=>{n(s=>[...s,{role:e,content:t,timestamp:new Date}])},[]),N=(0,eb.useCallback)(e=>{n(t=>{let s=t[t.length-1];return s&&"assistant"===s.role?[...t.slice(0,-1),{...s,content:s.content+e}]:[...t,{role:"assistant",content:e,timestamp:new Date}]})},[]),S=(0,eb.useCallback)(e=>{let t=atob(e),s=new Uint8Array(t.length);for(let e=0;e{if(!f.current){if(!t)return void _("status","Please select a model first");u(!0);try{x.current=new AudioContext({sampleRate:24e3});let a=(s||(0,eM.getProxyBaseUrl)()).replace(/^http/,"ws"),i=`${a}/v1/realtime?model=${encodeURIComponent(t)}`;r&&r.length>0&&(i+=`&guardrails=${encodeURIComponent(r.join(","))}`);let l=new WebSocket(i,["realtime",`openai-insecure-api-key.${e}`]);l.onopen=()=>{c(!0),u(!1),_("status","Connected to realtime API")},l.onmessage=async e=>{try{let t=e.data;t instanceof Blob?t=await t.text():t instanceof ArrayBuffer&&(t=new TextDecoder().decode(t));let s=JSON.parse(t),r=s.type;"session.created"===r?l.send(JSON.stringify({type:"session.update",session:{type:"realtime",modalities:["text","audio"],voice:p,input_audio_format:"pcm16",output_audio_format:"pcm16",input_audio_transcription:{model:"gpt-4o-mini-transcribe"},turn_detection:null}})):"session.updated"===r||("response.output_audio.delta"===r||"response.audio.delta"===r?s.delta&&S(s.delta):"response.output_text.delta"===r||"response.output_audio_transcript.delta"===r||"response.audio_transcript.delta"===r||"response.text.delta"===r?s.delta&&N(s.delta):"conversation.item.input_audio_transcription.completed"===r?s.transcript&&_("user",s.transcript):"response.done"===r?n(e=>{let t=e[e.length-1];if(t&&"assistant"===t.role&&t.content)return e;let r=s.response?.output||[],a=[];for(let e of r)for(let t of e.content||[]){let e=t.text||t.transcript;e&&a.push(e)}return a.length>0?[...e,{role:"assistant",content:a.join(""),timestamp:new Date}]:e}):"error"===r&&_("status",`Error: ${s.error?.message||JSON.stringify(s.error)}`))}catch{}},l.onerror=()=>{_("status","WebSocket error"),c(!1),u(!1)},l.onclose=()=>{_("status","Disconnected"),c(!1),u(!1),f.current=null},f.current=l}catch(e){_("status",`Connection failed: ${e.message}`),u(!1)}}},[e,t,p,s,r,_,N,S]),C=(0,eb.useCallback)(()=>{E(),f.current?.close(),f.current=null,x.current?.close(),x.current=null,w.current=0,A.current=!1,c(!1)},[]),T=(0,eb.useCallback)(async()=>{if(f.current&&f.current.readyState===WebSocket.OPEN){f.current.send(JSON.stringify({type:"session.update",session:{type:"realtime",modalities:["text","audio"],voice:p,input_audio_format:"pcm16",output_audio_format:"pcm16",input_audio_transcription:{model:"gpt-4o-mini-transcribe"},turn_detection:{type:"server_vad"}}}));try{let e=await navigator.mediaDevices.getUserMedia({audio:!0});y.current=e;let t=x.current||new AudioContext({sampleRate:24e3});x.current=t;let s=t.createMediaStreamSource(e),r=t.createScriptProcessor(4096,1,1);b.current=r,r.onaudioprocess=e=>{let s;if(!f.current||f.current.readyState!==WebSocket.OPEN)return;let r=e.inputBuffer.getChannelData(0),a=t.sampleRate;if(24e3!==a){let e=a/24e3,t=Math.round(r.length/e);s=new Float32Array(t);for(let a=0;a{b.current?.disconnect(),b.current=null,y.current?.getTracks().forEach(e=>e.stop()),y.current=null,h(!1)},[]),A=(0,eb.useRef)(!1),P=(0,eb.useCallback)(()=>{!f.current||f.current.readyState!==WebSocket.OPEN||A.current||(A.current=!0,f.current.send(JSON.stringify({type:"session.update",session:{type:"realtime",modalities:["text","audio"],voice:p,input_audio_format:"pcm16",output_audio_format:"pcm16",input_audio_transcription:{model:"gpt-4o-mini-transcribe"},turn_detection:null}})))},[p]),R=(0,eb.useCallback)(()=>{if(!i.trim()||!f.current||f.current.readyState!==WebSocket.OPEN)return;let e=i.trim();_("user",e),l(""),f.current.send(JSON.stringify({type:"conversation.item.create",item:{type:"message",role:"user",content:[{type:"input_text",text:e}]}})),f.current.send(JSON.stringify({type:"response.create"}))},[i,_,P]);return(0,eb.useEffect)(()=>()=>{f.current?.close(),x.current?.close(),y.current?.getTracks().forEach(e=>e.stop())},[]),(0,ey.jsxs)("div",{className:"flex flex-col h-full",children:[(0,ey.jsxs)("div",{className:"flex items-center justify-between px-4 py-3 border-b border-gray-200 bg-gray-50",children:[(0,ey.jsxs)("div",{className:"flex items-center gap-3",children:[(0,ey.jsx)(tE.SoundOutlined,{className:"text-lg text-blue-500"}),(0,ey.jsx)(a3,{className:"font-semibold text-gray-800",children:"Realtime Voice Chat"}),(0,ey.jsx)("span",{className:`inline-block w-2 h-2 rounded-full ${o?"bg-green-500":"bg-gray-300"}`}),(0,ey.jsx)(a3,{className:"text-xs text-gray-500",children:o?"Connected":d?"Connecting...":"Disconnected"})]}),(0,ey.jsxs)("div",{className:"flex items-center gap-2",children:[(0,ey.jsx)(eA.Select,{size:"small",value:p,onChange:g,options:ac,style:{width:220},disabled:o}),o?(0,ey.jsx)(eC.Button,{danger:!0,onClick:C,size:"small",icon:(0,ey.jsx)(a5.CloseCircleOutlined,{}),children:"Disconnect"}):(0,ey.jsx)(eC.Button,{type:"primary",onClick:k,loading:d,size:"small",children:"Connect"})]})]}),(0,ey.jsxs)("div",{className:"flex-1 overflow-y-auto p-4 space-y-3",children:[0===a.length&&!o&&(0,ey.jsxs)("div",{className:"flex flex-col items-center justify-center h-full text-gray-400 gap-3",children:[(0,ey.jsx)(tE.SoundOutlined,{style:{fontSize:48}}),(0,ey.jsx)(a3,{className:"text-lg text-gray-500",children:"Realtime Voice Playground"}),(0,ey.jsxs)(a3,{className:"text-sm text-gray-400 text-center max-w-md",children:["Click ",(0,ey.jsx)("b",{children:"Connect"})," to start a realtime session. You can speak using your microphone or type messages. The AI will respond with voice and text."]})]}),a.map((e,t)=>(0,ey.jsx)("div",{className:`flex ${"user"===e.role?"justify-end":"status"===e.role?"justify-center":"justify-start"}`,children:"status"===e.role?(0,ey.jsx)("div",{className:"text-xs text-gray-400 italic px-3 py-1",children:e.content}):(0,ey.jsxs)("div",{className:`max-w-[75%] rounded-2xl px-4 py-2.5 ${"user"===e.role?"bg-blue-500 text-white rounded-br-md":"bg-gray-100 text-gray-800 rounded-bl-md"}`,children:[(0,ey.jsx)("div",{className:"text-xs font-medium mb-0.5 opacity-70",children:"user"===e.role?"You":"AI"}),(0,ey.jsx)("div",{className:"text-sm whitespace-pre-wrap",children:e.content})]})},t)),(0,ey.jsx)("div",{ref:v})]}),o&&(0,ey.jsxs)("div",{className:"border-t border-gray-200 p-3 bg-white",children:[(0,ey.jsxs)("div",{className:"flex items-center gap-2",children:[(0,ey.jsx)(eC.Button,{shape:"circle",size:"large",type:m?"primary":"default",danger:m,icon:m?(0,ey.jsx)(a1,{}):(0,ey.jsx)(a2.AudioOutlined,{}),onClick:m?E:T,title:m?"Stop recording":"Start recording",className:m?"animate-pulse":""}),(0,ey.jsx)(eT.Input,{placeholder:"Type a message or use the mic...",value:i,onChange:e=>l(e.target.value),onPressEnter:R,className:"flex-1",size:"large"}),(0,ey.jsx)(eC.Button,{type:"primary",icon:(0,ey.jsx)(a4.SendOutlined,{}),onClick:R,disabled:!i.trim(),size:"large"})]}),m&&(0,ey.jsxs)("div",{className:"mt-2 flex items-center gap-2 text-red-500 text-xs",children:[(0,ey.jsx)("span",{className:"inline-block w-2 h-2 rounded-full bg-red-500 animate-pulse"}),"Listening — speak into your microphone. Server VAD will detect when you stop."]})]})]})};var a8=e.i(122550),a7=e.i(434166);let{TextArea:a9}=eT.Input,{Dragger:ne}=tD.Upload,nt=new Set([al.EndpointType.CHAT,al.EndpointType.RESPONSES,al.EndpointType.MCP]),ns=({accessToken:e,token:t,userRole:s,userID:r,disabledPersonalKeyCreation:a,proxySettings:n,simplified:i=!1,fixedModel:l})=>{let[o,c]=(0,eb.useState)([]),[d,u]=(0,eb.useState)([]),[m,h]=(0,eb.useState)(!1),[p,g]=(0,eb.useState)(null),[f,x]=(0,eb.useState)(()=>{let e=sessionStorage.getItem("selectedMCPServers");try{return e?JSON.parse(e):[]}catch(e){return console.error("Error parsing selectedMCPServers from sessionStorage",e),[]}}),[y,b]=(0,eb.useState)(!1),[v,w]=(0,eb.useState)({}),[j,_]=(0,eb.useState)(void 0),N=(0,eb.useRef)(null),[S,k]=(0,eb.useState)(()=>{let e=sessionStorage.getItem("mcpServerToolRestrictions");try{return e?JSON.parse(e):{}}catch(e){return console.error("Error parsing mcpServerToolRestrictions from sessionStorage",e),{}}}),{chatHistory:C,setChatHistory:T,mcpEvents:E,setMCPEvents:A,messageTraceId:P,setMessageTraceId:R,responsesSessionId:O,setResponsesSessionId:I,useApiSessionManagement:M,setUseApiSessionManagement:$,updateTextUI:L,updateReasoningContent:U,updateTimingData:B,updateUsageData:D,updateA2AMetadata:q,updateTotalLatency:W,updateSearchResults:z,handleResponseId:F,handleToggleSessionManagement:H,handleMCPEvent:V,updateImageUI:J,updateEmbeddingsUI:G,updateAudioUI:K,updateChatImageUI:X,clearChatHistory:Y,clearMCPEvents:Q}=function({simplified:e}){let[t,s]=(0,eb.useState)(()=>{if(e)return[];try{let e=sessionStorage.getItem("chatHistory");return e?JSON.parse(e):[]}catch(e){return console.error("Error parsing chatHistory from sessionStorage",e),[]}}),[r,a]=(0,eb.useState)([]),[n,i]=(0,eb.useState)(()=>e?null:sessionStorage.getItem("messageTraceId")||null),[l,o]=(0,eb.useState)(()=>e?null:sessionStorage.getItem("responsesSessionId")||null),[c,d]=(0,eb.useState)(()=>{if(e)return!0;let t=sessionStorage.getItem("useApiSessionManagement");return!t||JSON.parse(t)});return(0,eb.useEffect)(()=>{if(e||0===t.length)return;let s=setTimeout(()=>{sessionStorage.setItem("chatHistory",JSON.stringify(t))},500);return()=>{clearTimeout(s)}},[t,e]),(0,eb.useEffect)(()=>{e||(n?sessionStorage.setItem("messageTraceId",n):sessionStorage.removeItem("messageTraceId"),l?sessionStorage.setItem("responsesSessionId",l):sessionStorage.removeItem("responsesSessionId"),sessionStorage.setItem("useApiSessionManagement",JSON.stringify(c)))},[n,l,c,e]),{chatHistory:t,setChatHistory:s,mcpEvents:r,setMCPEvents:a,messageTraceId:n,setMessageTraceId:i,responsesSessionId:l,setResponsesSessionId:o,useApiSessionManagement:c,setUseApiSessionManagement:d,updateTextUI:(e,t,r)=>{s(s=>{let a=s[s.length-1];if(!a||a.role!==e||a.isImage||a.isAudio)return[...s,{role:e,content:t,model:r}];{let e={...a,content:a.content+t,model:a.model??r};return[...s.slice(0,-1),e]}})},updateReasoningContent:e=>{s(t=>{let s=t[t.length-1];return!s||"assistant"!==s.role||s.isImage||s.isAudio?t.length>0&&"user"===t[t.length-1].role?[...t,{role:"assistant",content:"",reasoningContent:e}]:t:[...t.slice(0,t.length-1),{...s,reasoningContent:(s.reasoningContent||"")+e}]})},updateTimingData:e=>{s(t=>{let s=t[t.length-1];return s&&"assistant"===s.role?[...t.slice(0,t.length-1),{...s,timeToFirstToken:e}]:s&&"user"===s.role?[...t,{role:"assistant",content:"",timeToFirstToken:e}]:t})},updateUsageData:(e,t)=>{s(s=>{let r=s[s.length-1];if(r&&"assistant"===r.role){let a={...r,usage:e,toolName:t};return[...s.slice(0,s.length-1),a]}return s})},updateA2AMetadata:e=>{s(t=>{let s=t[t.length-1];if(s&&"assistant"===s.role){let r={...s,a2aMetadata:e};return[...t.slice(0,t.length-1),r]}return t})},updateTotalLatency:e=>{s(t=>{let s=t[t.length-1];return s&&"assistant"===s.role?[...t.slice(0,t.length-1),{...s,totalLatency:e}]:t})},updateSearchResults:e=>{s(t=>{let s=t[t.length-1];if(s&&"assistant"===s.role){let r={...s,searchResults:e};return[...t.slice(0,t.length-1),r]}return t})},handleResponseId:e=>{c&&o(e)},handleToggleSessionManagement:e=>{d(e),e||o(null)},handleMCPEvent:e=>{a(t=>e.item_id&&t.some(t=>t.item_id===e.item_id&&t.type===e.type&&(t.sequence_number===e.sequence_number||void 0===t.sequence_number&&void 0===e.sequence_number))?t:[...t,e])},updateImageUI:(e,t)=>{s(s=>[...s,{role:"assistant",content:e,model:t,isImage:!0}])},updateEmbeddingsUI:(e,t)=>{s(s=>[...s,{role:"assistant",content:(0,a8.truncateString)(e,100),model:t,isEmbeddings:!0}])},updateAudioUI:(e,t)=>{s(s=>[...s,{role:"assistant",content:e,model:t,isAudio:!0}])},updateChatImageUI:(e,t)=>{s(s=>{let r=s[s.length-1];if(!r||"assistant"!==r.role||r.isImage||r.isAudio)return[...s,{role:"assistant",content:"",model:t,image:{url:e,detail:"auto"}}];{let a={...r,image:{url:e,detail:"auto"},model:r.model??t};return[...s.slice(0,-1),a]}})},clearChatHistory:()=>{s(e=>(e.forEach(e=>{e.isAudio&&"string"==typeof e.content&&URL.revokeObjectURL(e.content)}),[])),i(null),o(null),a([]),e||(sessionStorage.removeItem("chatHistory"),sessionStorage.removeItem("messageTraceId"),sessionStorage.removeItem("responsesSessionId"))},clearMCPEvents:()=>{a([])}}}({simplified:i}),[Z,ee]=(0,eb.useState)(()=>{let e=(0,a7.getSecureItem)("apiKeySource");if(e)try{return JSON.parse(e)}catch(e){console.error("Error parsing apiKeySource from sessionStorage",e)}return a?"custom":"session"}),[et,es]=(0,eb.useState)(()=>(0,a7.getSecureItem)("apiKey")||""),[er,ea]=(0,eb.useState)(()=>sessionStorage.getItem("customProxyBaseUrl")||""),[en,ei]=(0,eb.useState)(""),[el,eo]=(0,eb.useState)(i?l:void 0),[ec,ed]=(0,eb.useState)(!1),[eu,em]=(0,eb.useState)([]),[eh,ep]=(0,eb.useState)([]),[eg,ef]=(0,eb.useState)(void 0),ex=(0,eb.useRef)(null),[ev,ej]=(0,eb.useState)(()=>sessionStorage.getItem("endpointType")||al.EndpointType.CHAT),[eN,ek]=(0,eb.useState)(!1),eT=(0,eb.useRef)(null),[eR,eO]=(0,eb.useState)(()=>{let e=sessionStorage.getItem("selectedTags");try{return e?JSON.parse(e):[]}catch(e){return console.error("Error parsing selectedTags from sessionStorage",e),[]}}),[eL,eB]=(0,eb.useState)(()=>{let e=sessionStorage.getItem("selectedVoice");if(!e)return"alloy";try{return JSON.parse(e)}catch{return e}}),[eq,ez]=(0,eb.useState)(()=>{let e=sessionStorage.getItem("selectedVectorStores");try{return e?JSON.parse(e):[]}catch(e){return console.error("Error parsing selectedVectorStores from sessionStorage",e),[]}}),[eF,eH]=(0,eb.useState)(()=>{let e=sessionStorage.getItem("selectedGuardrails");try{return e?JSON.parse(e):[]}catch(e){return console.error("Error parsing selectedGuardrails from sessionStorage",e),[]}}),[eV,eJ]=(0,eb.useState)(()=>{let e=sessionStorage.getItem("selectedPolicies");try{return e?JSON.parse(e):[]}catch(e){return console.error("Error parsing selectedPolicies from sessionStorage",e),[]}}),[eG,eK]=(0,eb.useState)([]),[eX,eY]=(0,eb.useState)([]),[eQ,eZ]=(0,eb.useState)(null),[e0,e1]=(0,eb.useState)(null),[e2,e5]=(0,eb.useState)(null),[e4,e3]=(0,eb.useState)(null),[e6,e8]=(0,eb.useState)(null),[e7,e9]=(0,eb.useState)(!1),[te,tt]=(0,eb.useState)(""),[ts,tr]=(0,eb.useState)("openai"),[ta,tn]=(0,eb.useState)(1),[ti,tl]=(0,eb.useState)(2048),[to,tc]=(0,eb.useState)(!1),[td,tu]=(0,eb.useState)(!1),tm=function(){let[e,t]=(0,eb.useState)(()=>{let e=sessionStorage.getItem("codeInterpreterEnabled");return!!e&&JSON.parse(e)}),[s,r]=(0,eb.useState)(null),a=(0,eb.useCallback)(e=>{t(e),sessionStorage.setItem("codeInterpreterEnabled",JSON.stringify(e))},[]),n=(0,eb.useCallback)(()=>{r(null)},[]),i=(0,eb.useCallback)(()=>{a(!e)},[e,a]);return{enabled:e,result:s,setEnabled:a,setResult:r,clearResult:n,toggle:i}}(),th=(0,eb.useRef)(null),tp=async()=>{let t="session"===Z?e:et;if(t){b(!0);try{let[e,s]=await Promise.all([(0,eM.fetchMCPServers)(t),(0,eM.fetchMCPToolsets)(t).catch(()=>[])]);c(Array.isArray(e)?e:e.data||[]),u(Array.isArray(s)?s:[])}catch(e){console.error("Error fetching MCP servers:",e)}finally{b(!1)}}};(0,eb.useEffect)(()=>{i&&l&&(eo(l),ej(al.EndpointType.CHAT))},[i,l]);let t_=async t=>{let s="session"===Z?e:et;if(s&&!v[t])try{let e=await (0,eM.listMCPTools)(s,t);w(s=>({...s,[t]:e.tools||[]}))}catch(e){console.error(`Error fetching tools for server ${t}:`,e)}};(0,eb.useEffect)(()=>{if(e7){let t=(0,av.generateCodeSnippet)({apiKeySource:Z,accessToken:e,apiKey:et,inputMessage:en,chatHistory:C,selectedTags:eR,selectedVectorStores:eq,selectedGuardrails:eF,selectedPolicies:eV,selectedMCPServers:f,mcpServers:o,mcpServerToolRestrictions:S,endpointType:ev,selectedModel:el,selectedSdk:ts,selectedVoice:eL,proxySettings:n});tt(t)}},[e7,ts,Z,e,et,en,C,eR,eq,eF,eV,f,o,S,ev,el,n]),(0,eb.useEffect)(()=>{try{(0,a7.setSecureItem)("apiKeySource",JSON.stringify(Z)),(0,a7.setSecureItem)("apiKey",et)}catch{}sessionStorage.setItem("endpointType",ev),sessionStorage.setItem("selectedTags",JSON.stringify(eR)),sessionStorage.setItem("selectedVectorStores",JSON.stringify(eq)),sessionStorage.setItem("selectedGuardrails",JSON.stringify(eF)),sessionStorage.setItem("selectedPolicies",JSON.stringify(eV)),sessionStorage.setItem("selectedMCPServers",JSON.stringify(f)),sessionStorage.setItem("mcpServerToolRestrictions",JSON.stringify(S)),sessionStorage.setItem("selectedVoice",eL),sessionStorage.removeItem("selectedMCPTools"),i||(el?sessionStorage.setItem("selectedModel",el):sessionStorage.removeItem("selectedModel"))},[i,Z,et,el,ev,eR,eq,eF,eV,f,S,eL]),(0,eb.useEffect)(()=>{let a="session"===Z?e:et;if(!a||!t||!s||!r)return;let n=async()=>{try{if(!a)return;let e=await (0,eU.fetchAvailableModels)(a);em(e);let t=e.some(e=>e.model_group===el);e.length&&t||eo(void 0)}catch(e){console.error("Error fetching model info:",e)}};i||n(),tp()},[e,r,s,Z,et,t,i]),(0,eb.useEffect)(()=>{if(ev===al.EndpointType.MCP&&1===f.length&&"__all__"!==f[0]){let e=f[0];if(e.startsWith("toolset:")){let t=e.slice(8),s=d.find(e=>e.toolset_id===t);s&&[...new Set(s.tools.map(e=>e.server_id))].forEach(e=>{v[e]||t_(e)})}else v[e]||t_(e)}},[ev,f,v,d]),(0,eb.useEffect)(()=>{let t="session"===Z?e:et;t&&ev===al.EndpointType.A2A_AGENTS&&(async()=>{try{let e=await e$(t,er||void 0);ep(e),eg&&!e.some(e=>e.agent_name===eg)&&ef(void 0)}catch(e){console.error("Error fetching agents:",e)}})()},[e,Z,et,ev,er,eg]),(0,eb.useEffect)(()=>{th.current&&setTimeout(()=>{th.current?.scrollIntoView({behavior:"smooth",block:"end"})},100)},[C]);let tN=e=>{eK(t=>[...t,e]);let t=URL.createObjectURL(e),s=t.startsWith("blob:")?t:"";return eY(e=>[...e,s]),!1},tS=()=>{eX.forEach(e=>{URL.revokeObjectURL(e)}),eK([]),eY([])},tD=()=>{e0&&URL.revokeObjectURL(e0),eZ(null),e1(null)},tz=()=>{e4&&URL.revokeObjectURL(e4),e5(null),e3(null)},tF=()=>{e8(null)},tJ=async()=>{let a;if(""===en.trim()&&ev!==al.EndpointType.TRANSCRIPTION&&ev!==al.EndpointType.MCP)return;if(ev===al.EndpointType.IMAGE_EDITS&&0===eG.length)return void eI.default.fromBackend("Please upload at least one image for editing");if(ev===al.EndpointType.TRANSCRIPTION&&!e6)return void eI.default.fromBackend("Please upload an audio file for transcription");if(ev===al.EndpointType.A2A_AGENTS&&!eg)return void eI.default.fromBackend("Please select an agent to send a message");let l={};if(ev===al.EndpointType.MCP){let e=1===f.length&&"__all__"!==f[0]?f[0]:null;if(!e)return void eI.default.fromBackend("Please select an MCP server to test");if(e.startsWith("toolset:"),!j)return void eI.default.fromBackend("Please select an MCP tool to call");let t=e.startsWith("toolset:")?d.find(t=>t.toolset_id===e.slice(8)):null,s=[];if(t?[...new Set(t.tools.map(e=>e.server_id))].forEach(e=>{s=s.concat(v[e]||[])}):s=v[e]||[],!s.find(e=>e.name===j))return void eI.default.fromBackend("Please wait for tool schema to load");try{l=await N.current?.getSubmitValues()??{}}catch(e){eI.default.fromBackend(e instanceof Error?e.message:"Please fill in all required parameters");return}}if([al.EndpointType.CHAT,al.EndpointType.IMAGE,al.EndpointType.SPEECH,al.EndpointType.IMAGE_EDITS,al.EndpointType.RESPONSES,al.EndpointType.ANTHROPIC_MESSAGES,al.EndpointType.EMBEDDINGS,al.EndpointType.TRANSCRIPTION,al.EndpointType.INTERACTIONS].includes(ev)&&!el)return void eI.default.fromBackend("Please select a model before sending a request");if(!t||!s||!r)return;let c=i||"session"===Z?e:et;if(!c)return void eI.default.fromBackend("Please provide a Virtual Key or select Current UI Session");eT.current=new AbortController;let u=eT.current.signal;if(ev===al.EndpointType.RESPONSES&&eQ)try{a=await aV(en,eQ)}catch(e){eI.default.fromBackend("Failed to process image. Please try again.");return}else if(ev===al.EndpointType.CHAT&&e2)try{a=await ap(en,e2)}catch(e){eI.default.fromBackend("Failed to process image. Please try again.");return}else a={role:"user",content:en};let m=P||tH();P||R(m),T([...C,ev===al.EndpointType.RESPONSES&&eQ?aJ(en,!0,e0||void 0,eQ.name):ev===al.EndpointType.CHAT&&e2?ag(en,!0,e4||void 0,e2.name):ev===al.EndpointType.TRANSCRIPTION&&e6?aJ(en?`🎵 Audio file: ${e6.name} +Prompt: ${en}`:`🎵 Audio file: ${e6.name}`,!1):ev===al.EndpointType.MCP&&j?aJ(`🔧 MCP Tool: ${j} +Arguments: ${JSON.stringify(l,null,2)}`,!1):aJ(en,!1)]),Q(),tm.clearResult(),ek(!0);try{if(el)if(ev===al.EndpointType.CHAT){let e=[...C.filter(e=>!e.isImage&&!e.isAudio).map(({role:e,content:t})=>({role:e,content:"string"==typeof t?t:""})),a],t=i&&n?n.LITELLM_UI_API_DOC_BASE_URL??n.PROXY_BASE_URL??void 0:er||void 0;await eW(e,(e,t)=>L("assistant",e,t),el,c,eR,u,U,B,D,m,eq.length>0?eq:void 0,eF.length>0?eF:void 0,eV.length>0?eV:void 0,f,X,z,to?ta:void 0,to?ti:void 0,W,t,o,S,V,td,d)}else if(ev===al.EndpointType.IMAGE)await at(en,(e,t)=>J(e,t),el,c,eR,u,er||void 0);else if(ev===al.EndpointType.SPEECH)await r8(en,eL,(e,t)=>K(e,t),el||"",c,eR,u,void 0,void 0,er||void 0);else if(ev===al.EndpointType.IMAGE_EDITS)eG.length>0&&await ae(1===eG.length?eG[0]:eG,en,(e,t)=>J(e,t),el,c,eR,u,er||void 0);else if(ev===al.EndpointType.RESPONSES){let e;e=M&&O?[a]:[...C.filter(e=>!e.isImage&&!e.isAudio).map(({role:e,content:t})=>({role:e,content:t})),a],await (0,as.makeOpenAIResponsesRequest)(e,(e,t,s)=>L(e,t,s),el,c,eR,u,U,B,D,m,eq.length>0?eq:void 0,eF.length>0?eF:void 0,eV.length>0?eV:void 0,f,M?O:null,F,V,tm.enabled,tm.setResult,er||void 0,o,S,d)}else if(ev===al.EndpointType.ANTHROPIC_MESSAGES){let e=[...C.filter(e=>!e.isImage&&!e.isAudio).map(({role:e,content:t})=>({role:e,content:t})),a];await r6(e,(e,t,s)=>L(e,t,s),el,c,eR,u,U,B,D,m,eq.length>0?eq:void 0,eF.length>0?eF:void 0,eV.length>0?eV:void 0,f,er||void 0)}else ev===al.EndpointType.EMBEDDINGS?await r9(en,(e,t)=>G(e,t),el,c,eR,er||void 0):ev===al.EndpointType.TRANSCRIPTION?e6&&await r7(e6,(e,t)=>L("assistant",e,t),el,c,eR,u,void 0,void 0,void 0,void 0,er||void 0):ev===al.EndpointType.INTERACTIONS&&await ar(en,(e,t)=>L("assistant",e,t),el,c,eR,u,er||void 0);if(ev===al.EndpointType.MCP){let e=1===f.length&&"__all__"!==f[0]?f[0]:null,t=e;if(e?.startsWith("toolset:")){let s=e.slice(8),r=d.find(e=>e.toolset_id===s),a=r?.tools.find(e=>e.tool_name===j);t=a?.server_id??e}if(t&&!t.startsWith("toolset:")&&j){let e=await (0,eM.callMCPTool)(c,t,j,l,eF.length>0?{guardrails:eF}:void 0),s=e?.content?.length>0?JSON.stringify(e.content.map(e=>"text"===e.type?e.text:e).filter(Boolean),null,2):JSON.stringify(e,null,2);L("assistant",s||"Tool executed successfully.")}}ev===al.EndpointType.A2A_AGENTS&&eg&&await t5(eg,en,(e,t)=>L("assistant",e,t),c,u,B,W,q,er||void 0,eF.length>0?eF:void 0)}catch(e){u.aborted||(console.error("Error fetching response",e),L("assistant","Error fetching response:"+e))}finally{ek(!1),eT.current=null,ev===al.EndpointType.IMAGE_EDITS&&tS(),ev===al.EndpointType.RESPONSES&&eQ&&tD(),ev===al.EndpointType.CHAT&&e2&&tz(),ev===al.EndpointType.TRANSCRIPTION&&e6&&tF()}ei("")};if(s&&"Admin Viewer"===s){let{Title:e,Paragraph:t}=tB.Typography;return(0,ey.jsxs)("div",{children:[(0,ey.jsx)(e,{level:1,children:"Access Denied"}),(0,ey.jsx)(t,{children:"Ask your proxy admin for access to test models"})]})}let tG=(0,ey.jsx)(tj.LoadingOutlined,{style:{fontSize:24},spin:!0});return(0,ey.jsxs)("div",{className:`w-full bg-white ${i?"h-full flex flex-col":"p-4 pb-0"}`,children:[(0,ey.jsx)(tR.Card,{className:`w-full rounded-xl shadow-md overflow-hidden ${i?"h-full flex flex-col":""}`,children:(0,ey.jsxs)("div",{className:`flex w-full gap-4 ${i?"h-full":"h-[80vh]"}`,children:[!i&&(0,ey.jsxs)("div",{className:"w-1/4 p-4 bg-gray-50 overflow-y-auto",children:[(0,ey.jsx)(tM.Title,{className:"text-xl font-semibold mb-6 mt-2",children:"Configurations"}),(0,ey.jsxs)("div",{className:"space-y-4",children:[(0,ey.jsxs)("div",{children:[(0,ey.jsxs)(tO.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,ey.jsx)(tw.KeyOutlined,{className:"mr-2"})," Virtual Key Source"]}),(0,ey.jsx)(eA.Select,{disabled:a,value:Z,style:{width:"100%"},onChange:e=>{ee(e)},options:[{value:"session",label:"Current UI Session"},{value:"custom",label:"Virtual Key"}],className:"rounded-md"}),"custom"===Z&&(0,ey.jsx)(tI.TextInput,{className:"mt-2",placeholder:"Enter custom Virtual Key",type:"password",onValueChange:es,value:et,icon:tw.KeyOutlined})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,ey.jsxs)(tO.Text,{className:"font-medium block text-gray-700 flex items-center",children:[(0,ey.jsx)(tT.SettingOutlined,{className:"mr-2"})," Custom Proxy Base URL"]}),n?.LITELLM_UI_API_DOC_BASE_URL&&!er&&(0,ey.jsx)(eC.Button,{type:"link",size:"small",icon:(0,ey.jsx)(e_.LinkOutlined,{}),onClick:()=>{ea(n.LITELLM_UI_API_DOC_BASE_URL||""),sessionStorage.setItem("customProxyBaseUrl",n.LITELLM_UI_API_DOC_BASE_URL||"")},className:"text-gray-500 hover:text-gray-700",children:"Fill"}),er&&(0,ey.jsx)(eC.Button,{type:"link",size:"small",icon:(0,ey.jsx)(tx.ClearOutlined,{}),onClick:()=>{ea(""),sessionStorage.removeItem("customProxyBaseUrl")},className:"text-gray-500 hover:text-gray-700",children:"Clear"})]}),(0,ey.jsx)(tI.TextInput,{placeholder:"Optional: Enter custom proxy URL (e.g., http://localhost:5000)",onValueChange:e=>{ea(e),sessionStorage.setItem("customProxyBaseUrl",e)},value:er,icon:tg.ApiOutlined}),er&&(0,ey.jsxs)(tO.Text,{className:"text-xs text-gray-500 mt-1",children:["API calls will be sent to: ",er]})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsxs)(tO.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,ey.jsx)(tg.ApiOutlined,{className:"mr-2"})," Endpoint Type"]}),(0,ey.jsx)(aw,{endpointType:ev,onEndpointChange:e=>{ej(e),eo(void 0),ef(void 0),ed(!1),_(void 0),e===al.EndpointType.MCP&&x(e=>1===e.length&&"__all__"!==e[0]?e:[]);try{sessionStorage.removeItem("selectedModel"),sessionStorage.removeItem("selectedAgent")}catch{}},className:"mb-4"}),ev===al.EndpointType.SPEECH&&(0,ey.jsxs)("div",{className:"mb-4",children:[(0,ey.jsxs)(tO.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,ey.jsx)(tE.SoundOutlined,{className:"mr-2"}),"Voice"]}),(0,ey.jsx)(eA.Select,{value:eL,onChange:e=>{eB(e),sessionStorage.setItem("selectedVoice",e)},style:{width:"100%"},className:"rounded-md",options:ac})]}),(0,ey.jsx)(aZ,{endpointType:ev,responsesSessionId:O,useApiSessionManagement:M,onToggleSessionManagement:H})]}),ev!==al.EndpointType.A2A_AGENTS&&ev!==al.EndpointType.MCP&&(0,ey.jsxs)("div",{children:[(0,ey.jsxs)(tO.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center justify-between",children:[(0,ey.jsxs)("span",{className:"flex items-center",children:[(0,ey.jsx)(eS.RobotOutlined,{className:"mr-2"})," Select Model"]}),(()=>{if(!el||"custom"===el)return!1;let e=eu.find(e=>e.model_group===el);return!!e&&(!e.mode||"chat"===e.mode)})()?(0,ey.jsx)(tL.Popover,{content:(0,ey.jsx)(ai,{temperature:ta,maxTokens:ti,useAdvancedParams:to,onTemperatureChange:tn,onMaxTokensChange:tl,onUseAdvancedParamsChange:tc,mockTestFallbacks:td,onMockTestFallbacksChange:tu}),title:"Model Settings",trigger:"click",placement:"right",children:(0,ey.jsx)(eC.Button,{type:"text",size:"small",icon:(0,ey.jsx)(tT.SettingOutlined,{}),className:"text-gray-500 hover:text-gray-700","aria-label":"Model Settings","data-testid":"model-settings-button"})}):(0,ey.jsx)(tU.Tooltip,{title:"Advanced parameters are only supported for chat models currently",children:(0,ey.jsx)(eC.Button,{type:"text",size:"small",icon:(0,ey.jsx)(tT.SettingOutlined,{}),className:"text-gray-300 cursor-not-allowed",disabled:!0})})]}),(0,ey.jsx)(eA.Select,{value:el,placeholder:"Select a Model",onChange:e=>{eo(e),ed("custom"===e)},options:[{value:"custom",label:"Enter custom model",key:"custom"},...Array.from(new Set(eu.filter(e=>{if(!e.mode)return!0;let t=(0,al.getEndpointType)(e.mode);return ev===al.EndpointType.RESPONSES||ev===al.EndpointType.ANTHROPIC_MESSAGES||ev===al.EndpointType.INTERACTIONS?t===ev||t===al.EndpointType.CHAT:ev===al.EndpointType.IMAGE_EDITS?t===ev||t===al.EndpointType.IMAGE:t===ev}).map(e=>e.model_group))).map((e,t)=>({value:e,label:e,key:t}))],style:{width:"100%"},showSearch:!0,className:"rounded-md"}),ec&&(0,ey.jsx)(tI.TextInput,{className:"mt-2",placeholder:"Enter custom model name",onValueChange:e=>{ex.current&&clearTimeout(ex.current),ex.current=setTimeout(()=>{eo(e)},500)}})]}),ev===al.EndpointType.A2A_AGENTS&&(0,ey.jsxs)("div",{children:[(0,ey.jsxs)(tO.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,ey.jsx)(eS.RobotOutlined,{className:"mr-2"})," Select Agent"]}),(0,ey.jsx)(eA.Select,{value:eg,placeholder:"Select an Agent",onChange:e=>ef(e),options:eh.map(e=>({value:e.agent_name,label:e.agent_name||e.agent_id,key:e.agent_id})),style:{width:"100%"},showSearch:!0,className:"rounded-md",optionLabelProp:"label",children:eh.map(e=>(0,ey.jsx)(eA.Select.Option,{value:e.agent_name,label:e.agent_name||e.agent_id,children:(0,ey.jsxs)("div",{className:"flex flex-col py-1",children:[(0,ey.jsx)("span",{className:"font-medium",children:e.agent_name||e.agent_id}),e.agent_card_params?.description&&(0,ey.jsx)("span",{className:"text-xs text-gray-500 mt-1",children:e.agent_card_params.description})]})},e.agent_id))}),0===eh.length&&(0,ey.jsx)(tO.Text,{className:"text-xs text-gray-500 mt-2 block",children:"No agents found. Create agents via /v1/agents endpoint."})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsxs)(tO.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,ey.jsx)(tA.TagsOutlined,{className:"mr-2"})," Tags"]}),(0,ey.jsx)(t0,{value:eR,onChange:eO,className:"mb-4",accessToken:e||""})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsxs)(tO.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,ey.jsx)(tP.ToolOutlined,{className:"mr-2"}),ev===al.EndpointType.MCP?"MCP Server":"MCP Servers",(0,ey.jsx)(tU.Tooltip,{className:"ml-1",title:ev===al.EndpointType.MCP?"Select an MCP server or toolset to test tools directly.":"Select MCP servers or toolsets to use in your conversation.",children:(0,ey.jsx)(tv.InfoCircleOutlined,{className:"cursor-pointer",onClick:()=>h(!0)})})]}),(0,ey.jsxs)(eA.Select,{mode:ev===al.EndpointType.MCP?void 0:"multiple",style:{width:"100%"},placeholder:ev===al.EndpointType.MCP?"Select MCP server":"Select MCP servers",value:ev===al.EndpointType.MCP?"__all__"!==f[0]&&1===f.length?f[0]:void 0:f,onChange:e=>{ev===al.EndpointType.MCP?(x(e?[e]:[]),_(void 0),e&&!v[e]&&t_(e)):e.includes("__all__")?(x(["__all__"]),k({})):(x(e),k(t=>{let s={...t};return Object.keys(s).forEach(t=>{e.includes(t)||delete s[t]}),s}),e.forEach(e=>{v[e]||t_(e)}))},loading:y,className:"mb-2",allowClear:!0,showSearch:!0,optionLabelProp:"label",disabled:!nt.has(ev),maxTagCount:ev===al.EndpointType.MCP?1:"responsive",filterOption:(e,t)=>{if(t?.value==="__all__")return"all mcp servers".includes(e.toLowerCase());let s=t?.value;if(s?.startsWith("toolset:")){let t=s.slice(8),r=d.find(e=>e.toolset_id===t);return!!r&&[r.toolset_name,r.description].filter(Boolean).join(" ").toLowerCase().includes(e.toLowerCase())}let r=o.find(e=>e.server_id===s);return!!r&&[r.server_name,r.alias,r.server_id,r.description].filter(Boolean).join(" ").toLowerCase().includes(e.toLowerCase())},children:[ev!==al.EndpointType.MCP&&(0,ey.jsx)(eA.Select.Option,{value:"__all__",label:"All MCP Servers",children:(0,ey.jsxs)("div",{className:"flex flex-col py-1",children:[(0,ey.jsx)("span",{className:"font-medium",children:"All MCP Servers"}),(0,ey.jsx)("span",{className:"text-xs text-gray-500 mt-1",children:"Use all available MCP servers"})]})},"__all__"),d.length>0&&(0,ey.jsx)(eA.Select.OptGroup,{label:"Toolsets",children:d.map(e=>(0,ey.jsx)(eA.Select.Option,{value:`toolset:${e.toolset_id}`,label:e.toolset_name,disabled:ev!==al.EndpointType.MCP&&f.includes("__all__"),children:(0,ey.jsxs)("div",{className:"flex flex-col py-1",children:[(0,ey.jsxs)("div",{className:"flex items-center gap-1",children:[(0,ey.jsx)("span",{className:"font-medium",children:e.toolset_name}),(0,ey.jsx)("span",{className:"text-xs px-1 rounded-sm",style:{background:"#ede9fe",color:"#7c3aed"},children:"Toolset"}),(0,ey.jsxs)("span",{className:"text-xs text-gray-500",children:["(",e.tools.length," tools)"]})]}),e.description&&(0,ey.jsx)("span",{className:"text-xs text-gray-500 mt-1",children:e.description})]})},`toolset:${e.toolset_id}`))}),o.length>0&&(0,ey.jsx)(eA.Select.OptGroup,{label:"Servers",children:o.map(e=>(0,ey.jsx)(eA.Select.Option,{value:e.server_id,label:e.alias||e.server_name||e.server_id,disabled:ev!==al.EndpointType.MCP&&f.includes("__all__"),children:(0,ey.jsxs)("div",{className:"flex flex-col py-1",children:[(0,ey.jsx)("span",{className:"font-medium",children:e.alias||e.server_name||e.server_id}),e.description&&(0,ey.jsx)("span",{className:"text-xs text-gray-500 mt-1",children:e.description})]})},e.server_id))})]}),ev===al.EndpointType.MCP&&1===f.length&&"__all__"!==f[0]&&(()=>{let e=f[0],t=e.startsWith("toolset:"),s=[];if(t){let t=e.slice(8),r=d.find(e=>e.toolset_id===t);r&&(s=r.tools.map(e=>({value:e.tool_name,label:e.tool_name})))}else s=(v[e]||[]).map(e=>({value:e.name,label:e.name}));return(0,ey.jsxs)("div",{className:"mt-3",children:[(0,ey.jsx)(tO.Text,{className:"text-xs text-gray-600 mb-1 block",children:"Select Tool"}),(0,ey.jsx)(eA.Select,{style:{width:"100%"},placeholder:"Select a tool to call",value:j,onChange:e=>_(e),options:s,allowClear:!0,className:"rounded-md"})]})})(),f.length>0&&!f.includes("__all__")&&ev!==al.EndpointType.MCP&&nt.has(ev)&&(0,ey.jsx)("div",{className:"mt-3 space-y-2",children:f.map(e=>{let t=o.find(t=>t.server_id===e),s=v[e]||[];return 0===s.length?null:(0,ey.jsxs)("div",{className:"border rounded-sm p-2",children:[(0,ey.jsxs)(tO.Text,{className:"text-xs text-gray-600 mb-1",children:["Limit tools for ",t?.alias||t?.server_name||e,":"]}),(0,ey.jsx)(eA.Select,{mode:"multiple",size:"small",style:{width:"100%"},placeholder:"All tools (default)",value:S[e]||[],onChange:t=>{k(s=>({...s,[e]:t}))},options:s.map(e=>({value:e.name,label:e.name})),maxTagCount:2})]},e)})}),f.length>0&&!f.includes("__all__")&&f.some(e=>{let t=o.find(t=>t.server_id===e);return t?.is_byok})&&(0,ey.jsx)("div",{className:"mt-3 space-y-2",children:f.map(e=>{let t=o.find(t=>t.server_id===e);if(!t?.is_byok)return null;let s=t.alias||t.server_name||e;return(0,ey.jsxs)("div",{className:"border border-blue-100 rounded-sm p-2 bg-blue-50 flex items-center justify-between",children:[(0,ey.jsxs)(tO.Text,{className:"text-xs text-blue-700",children:[s," requires your API key"]}),t.has_user_credential?(0,ey.jsxs)("div",{className:"flex items-center gap-2",children:[(0,ey.jsxs)("span",{className:"text-green-600 text-xs font-medium flex items-center gap-1",children:[(0,ey.jsx)(tw.KeyOutlined,{})," Connected"]}),(0,ey.jsx)("button",{className:"text-xs text-gray-400 hover:text-blue-500 underline",onClick:()=>g(t),children:"Reconnect"})]}):(0,ey.jsx)("button",{className:"text-xs bg-blue-500 hover:bg-blue-600 text-white px-3 py-1 rounded-lg font-medium",onClick:()=>g(t),children:"Connect"})]},e)})})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsxs)(tO.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,ey.jsx)(tb.DatabaseOutlined,{className:"mr-2"})," Vector Store",(0,ey.jsx)(tU.Tooltip,{className:"ml-1",title:(0,ey.jsxs)("span",{children:["Select vector store(s) to use for this LLM API call. You can set up your vector store"," ",(0,ey.jsx)("a",{href:"?page=vector-stores",style:{color:"#1890ff"},children:"here"}),"."]}),children:(0,ey.jsx)(tv.InfoCircleOutlined,{})})]}),(0,ey.jsx)(t1.default,{value:eq,onChange:ez,className:"mb-4",accessToken:e||""})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsxs)(tO.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,ey.jsx)(tC.SafetyOutlined,{className:"mr-2"})," Guardrails",(0,ey.jsx)(tU.Tooltip,{className:"ml-1",title:(0,ey.jsxs)("span",{children:["Select guardrail(s) to use for this LLM API call. You can set up your guardrails"," ",(0,ey.jsx)("a",{href:"?page=guardrails",style:{color:"#1890ff"},children:"here"}),"."]}),children:(0,ey.jsx)(tv.InfoCircleOutlined,{})})]}),(0,ey.jsx)(tV.default,{value:eF,onChange:eH,className:"mb-4",accessToken:e||""})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsxs)(tO.Text,{className:"font-medium block mb-2 text-gray-700 flex items-center",children:[(0,ey.jsx)(tC.SafetyOutlined,{className:"mr-2"})," Policies",(0,ey.jsx)(tU.Tooltip,{className:"ml-1",title:(0,ey.jsxs)("span",{children:["Select policy/policies to apply to this LLM API call. Policies define which guardrails are applied based on conditions. You can set up your policies"," ",(0,ey.jsx)("a",{href:"?page=policies",style:{color:"#1890ff"},children:"here"}),"."]}),children:(0,ey.jsx)(tv.InfoCircleOutlined,{})})]}),(0,ey.jsx)(eD.default,{value:eV,onChange:eJ,className:"mb-4",accessToken:e||""})]}),ev===al.EndpointType.RESPONSES&&(0,ey.jsx)("div",{children:(0,ey.jsx)(ab,{accessToken:"session"===Z?e||"":et,enabled:tm.enabled,onEnabledChange:tm.setEnabled,selectedContainerId:null,onContainerChange:()=>{},selectedModel:el||""})})]})]}),(0,ey.jsx)("div",{className:`flex flex-col bg-white ${i?"flex-1 w-full":"w-3/4"}`,children:ev===al.EndpointType.REALTIME?(0,ey.jsx)(a6,{accessToken:"session"===Z?e||"":et,selectedModel:el||"",customProxyBaseUrl:er||void 0,selectedGuardrails:eF.length>0?eF:void 0}):(0,ey.jsxs)(ey.Fragment,{children:[(0,ey.jsxs)("div",{className:"p-4 border-b border-gray-200 flex justify-between items-center",children:[(0,ey.jsx)(tM.Title,{className:"text-xl font-semibold mb-0",children:i?"Chat":"Test Key"}),(0,ey.jsxs)("div",{className:"flex gap-2",children:[(0,ey.jsx)(t$.Button,{onClick:()=>{Y(),tS(),tD(),tz(),tF(),eI.default.success("Chat history cleared.")},className:"bg-gray-100 hover:bg-gray-200 text-gray-700 border-gray-300",icon:tx.ClearOutlined,children:"Clear Chat"}),!i&&(0,ey.jsx)(t$.Button,{onClick:()=>e9(!0),className:"bg-gray-100 hover:bg-gray-200 text-gray-700 border-gray-300",icon:ty.CodeOutlined,children:"Get Code"})]})]}),(0,ey.jsxs)("div",{className:"flex-1 overflow-auto p-4 pb-0",children:[0===C.length&&(0,ey.jsxs)("div",{className:"h-full flex flex-col items-center justify-center text-gray-400",children:[(0,ey.jsx)(eS.RobotOutlined,{style:{fontSize:"48px",marginBottom:"16px"}}),(0,ey.jsx)(tO.Text,{children:"Start a conversation, generate an image, or handle audio"})]}),C.map((t,s)=>(0,ey.jsx)("div",{children:(0,ey.jsx)(aX,{message:t,isLastMessage:s===C.length-1,endpointType:ev,mcpEvents:E,codeInterpreterResult:tm.result,accessToken:"session"===Z?e||"":et})},s)),eN&&E.length>0&&(ev===al.EndpointType.RESPONSES||ev===al.EndpointType.CHAT)&&C.length>0&&"user"===C[C.length-1].role&&(0,ey.jsx)("div",{className:"text-left mb-4",children:(0,ey.jsxs)("div",{className:"inline-block max-w-[80%] rounded-lg shadow-xs p-3.5 px-4",style:{backgroundColor:"#ffffff",border:"1px solid #f0f0f0",textAlign:"left"},children:[(0,ey.jsxs)("div",{className:"flex items-center gap-2 mb-1.5",children:[(0,ey.jsx)("div",{className:"flex items-center justify-center w-6 h-6 rounded-full mr-1",style:{backgroundColor:"#f5f5f5"},children:(0,ey.jsx)(eS.RobotOutlined,{style:{fontSize:"12px",color:"#4b5563"}})}),(0,ey.jsx)("strong",{className:"text-sm capitalize",children:"Assistant"})]}),(0,ey.jsx)(az.default,{events:E})]})}),eN&&(0,ey.jsx)("div",{className:"flex justify-center items-center my-4",children:(0,ey.jsx)(eP.Spin,{indicator:tG})}),(0,ey.jsx)("div",{ref:th,style:{height:"1px"}})]}),(0,ey.jsxs)("div",{className:"p-4 border-t border-gray-200 bg-white",children:[ev===al.EndpointType.IMAGE_EDITS&&(0,ey.jsx)("div",{className:"mb-4",children:0===eG.length?(0,ey.jsxs)(ne,{beforeUpload:tN,accept:"image/*",showUploadList:!1,children:[(0,ey.jsx)("p",{className:"ant-upload-drag-icon",children:(0,ey.jsx)(tk,{style:{fontSize:"24px",color:"#666"}})}),(0,ey.jsx)("p",{className:"ant-upload-text text-sm",children:"Click or drag images to upload"}),(0,ey.jsx)("p",{className:"ant-upload-hint text-xs text-gray-500",children:"Support for PNG, JPG, JPEG formats. Multiple images supported."})]}):(0,ey.jsxs)("div",{className:"flex flex-wrap gap-2",children:[eG.map((e,t)=>(0,ey.jsxs)("div",{className:"relative inline-block",children:[(0,ey.jsx)("img",{src:(()=>{let e=eX[t];if(!e)return"";try{let t=new URL(e);return"blob:"===t.protocol?t.href:""}catch{return""}})(),alt:`Upload preview ${t+1}`,className:"max-w-32 max-h-32 rounded-md border border-gray-200 object-cover"}),(0,ey.jsx)("button",{className:"absolute top-1 right-1 bg-white shadow-xs border border-gray-200 rounded-sm px-1 py-1 text-red-500 hover:bg-red-50 text-xs",onClick:()=>{eX[t]&&URL.revokeObjectURL(eX[t]),eK(e=>e.filter((e,s)=>s!==t)),eY(e=>e.filter((e,s)=>s!==t))},children:(0,ey.jsx)(ew.DeleteOutlined,{})})]},t)),(0,ey.jsxs)("div",{className:"flex items-center justify-center w-32 h-32 border-2 border-dashed border-gray-300 rounded-md hover:border-gray-400 cursor-pointer",onClick:()=>document.getElementById("additional-image-upload")?.click(),children:[(0,ey.jsxs)("div",{className:"text-center",children:[(0,ey.jsx)(tk,{style:{fontSize:"24px",color:"#666"}}),(0,ey.jsx)("p",{className:"text-xs text-gray-500 mt-1",children:"Add more"})]}),(0,ey.jsx)("input",{id:"additional-image-upload",type:"file",accept:"image/*",multiple:!0,style:{display:"none"},onChange:e=>{Array.from(e.target.files||[]).forEach(e=>tN(e))}})]})]})}),ev===al.EndpointType.TRANSCRIPTION&&(0,ey.jsx)("div",{className:"mb-4",children:e6?(0,ey.jsxs)("div",{className:"flex items-center gap-3 p-3 bg-gray-50 rounded-lg border border-gray-200",children:[(0,ey.jsxs)("div",{className:"flex items-center gap-2 flex-1",children:[(0,ey.jsx)(tE.SoundOutlined,{style:{fontSize:"20px",color:"#666"}}),(0,ey.jsx)("span",{className:"text-sm font-medium",children:e6.name}),(0,ey.jsxs)("span",{className:"text-xs text-gray-500",children:["(",(e6.size/1024/1024).toFixed(2)," MB)"]})]}),(0,ey.jsxs)("button",{className:"bg-white shadow-xs border border-gray-200 rounded-sm px-2 py-1 text-red-500 hover:bg-red-50 text-xs",onClick:tF,children:[(0,ey.jsx)(ew.DeleteOutlined,{})," Remove"]})]}):(0,ey.jsxs)(ne,{beforeUpload:e=>(e8(e),!1),accept:"audio/*,.mp3,.mp4,.mpeg,.mpga,.m4a,.wav,.webm",showUploadList:!1,children:[(0,ey.jsx)("p",{className:"ant-upload-drag-icon",children:(0,ey.jsx)(tE.SoundOutlined,{style:{fontSize:"24px",color:"#666"}})}),(0,ey.jsx)("p",{className:"ant-upload-text text-sm",children:"Click or drag audio file to upload"}),(0,ey.jsx)("p",{className:"ant-upload-hint text-xs text-gray-500",children:"Support for MP3, MP4, MPEG, MPGA, M4A, WAV, WEBM formats. Max file size: 25 MB."})]})}),ev===al.EndpointType.RESPONSES&&eQ&&(0,ey.jsx)(a_,{file:eQ,previewUrl:e0,onRemove:tD}),ev===al.EndpointType.CHAT&&e2&&(0,ey.jsx)(a_,{file:e2,previewUrl:e4,onRemove:tz}),ev===al.EndpointType.RESPONSES&&tm.enabled&&(0,ey.jsxs)("div",{className:"mb-2 space-y-2",children:[(0,ey.jsxs)("div",{className:"px-3 py-2 bg-linear-to-r from-blue-50 to-purple-50 rounded-lg border border-blue-200 flex items-center justify-between",children:[(0,ey.jsx)("div",{className:"flex items-center gap-2",children:eN?(0,ey.jsxs)(ey.Fragment,{children:[(0,ey.jsx)(tj.LoadingOutlined,{className:"text-blue-500",spin:!0}),(0,ey.jsx)("span",{className:"text-sm text-blue-700 font-medium",children:"Running Python code..."})]}):(0,ey.jsxs)(ey.Fragment,{children:[(0,ey.jsx)(ty.CodeOutlined,{className:"text-blue-500"}),(0,ey.jsx)("span",{className:"text-sm text-blue-700 font-medium",children:"Code Interpreter Active"})]})}),(0,ey.jsx)("button",{className:"text-xs text-blue-500 hover:text-blue-700",onClick:()=>tm.setEnabled(!1),children:"Disable"})]}),!eN&&(0,ey.jsx)("div",{className:"flex flex-wrap gap-2",children:["Generate sample sales data CSV and create a chart","Create a PNG bar chart comparing AI gateway providers including LiteLLM","Generate a CSV of LLM pricing data and visualize it as a line chart"].map((e,t)=>(0,ey.jsx)("button",{className:"text-xs px-3 py-1.5 bg-white border border-gray-200 rounded-full hover:bg-blue-50 hover:border-blue-300 hover:text-blue-600 transition-colors",onClick:()=>ei(e),children:e},t))})]}),0===C.length&&!eN&&ev!==al.EndpointType.MCP&&(0,ey.jsx)("div",{className:"flex items-center gap-2 mb-3 overflow-x-auto",children:(ev===al.EndpointType.A2A_AGENTS?["What can you help me with?","Tell me about yourself","What tasks can you perform?"]:["Write me a poem","Explain quantum computing","Draft a polite email requesting a meeting"]).map(e=>(0,ey.jsx)("button",{type:"button",className:"shrink-0 rounded-full border border-gray-200 px-3 py-1 text-xs font-medium text-gray-600 transition-colors hover:bg-blue-50 hover:border-blue-300 hover:text-blue-600 cursor-pointer",onClick:()=>ei(e),children:e},e))}),(0,ey.jsxs)("div",{className:"flex items-center gap-2",children:[(0,ey.jsxs)("div",{className:"flex items-center flex-1 bg-white border border-gray-300 rounded-xl px-3 py-1 min-h-[44px]",children:[(0,ey.jsxs)("div",{className:"shrink-0 mr-2 flex items-center gap-1",children:[ev===al.EndpointType.RESPONSES&&!eQ&&(0,ey.jsx)(aQ,{responsesUploadedImage:eQ,responsesImagePreviewUrl:e0,onImageUpload:e=>(eZ(e),e1(URL.createObjectURL(e)),!1),onRemoveImage:tD}),ev===al.EndpointType.CHAT&&!e2&&(0,ey.jsx)(ah,{chatUploadedImage:e2,chatImagePreviewUrl:e4,onImageUpload:e=>(e5(e),e3(URL.createObjectURL(e)),!1),onRemoveImage:tz}),ev===al.EndpointType.RESPONSES&&(0,ey.jsx)(tU.Tooltip,{title:tm.enabled?"Code Interpreter enabled (click to disable)":"Enable Code Interpreter",children:(0,ey.jsx)("button",{className:`p-1.5 rounded-md transition-colors ${tm.enabled?"bg-blue-100 text-blue-600":"text-gray-400 hover:text-gray-600 hover:bg-gray-100"}`,onClick:()=>{tm.toggle(),tm.enabled||eI.default.success("Code Interpreter enabled!")},children:(0,ey.jsx)(ty.CodeOutlined,{style:{fontSize:"16px"}})})})]}),ev===al.EndpointType.MCP&&1===f.length&&"__all__"!==f[0]&&j?(0,ey.jsx)("div",{className:"flex-1 overflow-y-auto max-h-48 min-h-[44px] p-2 border border-gray-200 rounded-lg bg-gray-50/50",children:(()=>{let e=f[0],t=[];if(e.startsWith("toolset:")){let s=e.slice(8),r=d.find(e=>e.toolset_id===s);r&&[...new Set(r.tools.map(e=>e.server_id))].forEach(e=>{t=t.concat(v[e]||[])})}else t=v[e]||[];let s=t.find(e=>e.name===j);return s?(0,ey.jsx)(tQ,{ref:N,tool:s,className:"space-y-2"}):(0,ey.jsx)("div",{className:"flex items-center justify-center h-10 text-sm text-gray-500",children:"Loading tool schema..."})})()}):(0,ey.jsx)(a9,{value:en,onChange:e=>ei(e.target.value),onKeyDown:e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),tJ())},placeholder:ev===al.EndpointType.CHAT||ev===al.EndpointType.EMBEDDINGS||ev===al.EndpointType.RESPONSES||ev===al.EndpointType.ANTHROPIC_MESSAGES||ev===al.EndpointType.INTERACTIONS?"Type your message... (Shift+Enter for new line)":ev===al.EndpointType.A2A_AGENTS?"Send a message to the A2A agent...":ev===al.EndpointType.IMAGE_EDITS?"Describe how you want to edit the image...":ev===al.EndpointType.SPEECH?"Enter text to convert to speech...":ev===al.EndpointType.TRANSCRIPTION?"Optional: Add context or prompt for transcription...":"Describe the image you want to generate...",disabled:eN,className:"flex-1",autoSize:{minRows:1,maxRows:4},style:{resize:"none",border:"none",boxShadow:"none",background:"transparent",padding:"4px 0",fontSize:"14px",lineHeight:"20px"}}),(0,ey.jsx)(t$.Button,{onClick:tJ,disabled:eN||(ev===al.EndpointType.MCP?!(1===f.length&&"__all__"!==f[0]&&j):ev===al.EndpointType.TRANSCRIPTION?!e6:!en.trim()),className:"shrink-0 ml-2 w-8! h-8! min-w-8! p-0! rounded-full! bg-blue-600! hover:bg-blue-700! disabled:bg-gray-300! border-none! text-white! disabled:text-gray-500! flex! items-center! justify-center!",children:(0,ey.jsx)(tf.ArrowUpOutlined,{style:{fontSize:"14px"}})})]}),eN&&(0,ey.jsx)(t$.Button,{onClick:()=>{eT.current&&(eT.current.abort(),eT.current=null,ek(!1),eI.default.info("Request cancelled"))},className:"bg-red-50 hover:bg-red-100 text-red-600 border-red-200",icon:ew.DeleteOutlined,children:"Cancel"})]})]})]})})]})}),(0,ey.jsxs)(eE.Modal,{title:"Generated Code",open:e7,onCancel:()=>e9(!1),footer:null,width:800,children:[(0,ey.jsxs)("div",{className:"flex justify-between items-end my-4",children:[(0,ey.jsxs)("div",{children:[(0,ey.jsx)(tO.Text,{className:"font-medium block mb-1 text-gray-700",children:"SDK Type"}),(0,ey.jsx)(eA.Select,{value:ts,onChange:e=>tr(e),style:{width:150},options:[{value:"openai",label:"OpenAI SDK"},{value:"azure",label:"Azure SDK"}]})]}),(0,ey.jsx)(eC.Button,{onClick:()=>{navigator.clipboard.writeText(te),eI.default.success("Copied to clipboard!")},children:"Copy to Clipboard"})]}),(0,ey.jsx)(tq.Prism,{language:"python",style:tW.coy,wrapLines:!0,wrapLongLines:!0,className:"rounded-md",customStyle:{maxHeight:"60vh",overflowY:"auto"},children:te})]}),p&&(0,ey.jsx)(tZ.ByokCredentialModal,{server:p,open:!!p,onClose:()=>g(null),onSuccess:e=>{tp(),g(null)},accessToken:e||""}),(0,ey.jsx)(eE.Modal,{title:"How Toolsets Work",open:m,onCancel:()=>h(!1),footer:[(0,ey.jsx)(eC.Button,{onClick:()=>h(!1),children:"Close"},"close")],width:600,children:(0,ey.jsxs)("div",{className:"space-y-4 py-2",children:[(0,ey.jsxs)("p",{className:"text-gray-700",children:[(0,ey.jsx)("strong",{children:"Toolsets"})," are named collections of specific tools from one or more MCP servers. Instead of exposing all tools from a server, a toolset gives an agent exactly the tools it needs."]}),(0,ey.jsxs)("div",{children:[(0,ey.jsx)("h4",{className:"font-semibold text-gray-800 mb-2",children:"How to use a toolset:"}),(0,ey.jsxs)("ol",{className:"list-decimal list-inside space-y-2 text-gray-700",children:[(0,ey.jsxs)("li",{children:["Select a ",(0,ey.jsx)("span",{style:{color:"#7c3aed",fontWeight:600},children:"Toolset"})," (purple badge) from the MCP Servers dropdown."]}),(0,ey.jsx)("li",{children:"The tool picker will show only the tools included in that toolset."}),(0,ey.jsx)("li",{children:"Select a tool and fill in its parameters, then send."}),(0,ey.jsx)("li",{children:"The tool call is routed to the correct underlying MCP server automatically."})]})]}),(0,ey.jsx)("div",{className:"bg-purple-50 border border-purple-200 rounded-sm p-3",children:(0,ey.jsxs)("p",{className:"text-sm text-purple-800",children:[(0,ey.jsx)("strong",{children:"Example:"}),' A "GitHub Read-only" toolset might include only'," ",(0,ey.jsx)("code",{children:"list_repos"})," and ",(0,ey.jsx)("code",{children:"get_file"})," from a GitHub MCP server — preventing agents from making writes."]})}),(0,ey.jsxs)("div",{children:[(0,ey.jsx)("h4",{className:"font-semibold text-gray-800 mb-1",children:"Creating toolsets:"}),(0,ey.jsxs)("p",{className:"text-sm text-gray-600",children:["Admins can create and manage toolsets from the ",(0,ey.jsx)("strong",{children:"MCP"})," page → ",(0,ey.jsx)("strong",{children:"Toolsets"})," tab. Toolsets can then be assigned to keys and teams to scope their tool access."]})]})]})})]})},{TextArea:nr}=eT.Input,na="__new__";function nn({agentName:e,proxySettings:t,customProxyBaseUrl:s,disabledPersonalKeyCreation:r,creatingKey:a,createdKeyValue:n,onCreateKey:i}){let l,o=eM.proxyBaseUrl??((l=t?.LITELLM_UI_API_DOC_BASE_URL)&&l.trim()?l:t?.PROXY_BASE_URL?t.PROXY_BASE_URL:s?.trim()?s:""),c=n?n.startsWith("Bearer ")?n:`Bearer ${n}`:"Bearer sk-1234",d=`curl -L -X POST '${o}/v1/chat/completions' \\ +-H 'x-litellm-api-key: ${c}' \\ +-d '{ + "model": "${e}", + "stream": true, + "stream_options": { + "include_usage": true + }, + "messages": [ + { + "role": "user", + "content": "hey" + } + ] +}'`;return(0,ey.jsxs)("div",{className:"mx-auto max-w-3xl space-y-6",children:[(0,ey.jsxs)("div",{children:[(0,ey.jsx)("h3",{className:"text-sm font-semibold text-gray-900 mb-1",children:"Proxy base URL"}),(0,ey.jsx)("p",{className:"text-sm text-gray-600 font-mono bg-gray-50 px-2 py-1.5 rounded-sm border border-gray-200 break-all",children:o})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsx)("h3",{className:"text-sm font-semibold text-gray-900 mb-2",children:"Call your agent (cURL)"}),(0,ey.jsx)(eO.default,{code:d,language:"bash"})]}),(0,ey.jsxs)("div",{className:"rounded-lg border border-gray-200 bg-gray-50 p-4",children:[(0,ey.jsx)("h3",{className:"text-sm font-semibold text-gray-900 mb-2",children:"Create a key for this agent"}),(0,ey.jsxs)("p",{className:"text-sm text-gray-600 mb-3",children:["Create a virtual key that can only call this agent. The key will be scoped to you (user_id) and restricted to the model ",(0,ey.jsx)("span",{className:"font-mono text-gray-800",children:e}),"."]}),(0,ey.jsx)(eC.Button,{type:"primary",onClick:i,loading:a,disabled:r,children:"Create key for this agent"}),r&&(0,ey.jsx)("p",{className:"text-xs text-amber-600 mt-2",children:"Key creation is disabled for your account."}),n&&(0,ey.jsx)("p",{className:"text-xs text-green-700 mt-2",children:"Key created. It is shown in the cURL example above — copy the snippet to use it."})]})]})}function ni(e){let t=e.model_info;return t?.id??null}function nl(e){return ni(e)??e.model_name}let no="litellm_proxy/mcp/";function nc({accessToken:e,token:t,userID:s,userRole:r,disabledPersonalKeyCreation:a=!1,proxySettings:n,apiKey:i,customProxyBaseUrl:l}){let[o,c]=(0,eb.useState)([]),[d,u]=(0,eb.useState)([]),[m,h]=(0,eb.useState)(!0),[p,g]=(0,eb.useState)(null),[f,x]=(0,eb.useState)("configure"),[y,b]=(0,eb.useState)(!1),[v,w]=(0,eb.useState)(null),[j,_]=(0,eb.useState)(""),[N,S]=(0,eb.useState)(""),[k,C]=(0,eb.useState)(void 0),[T,E]=(0,eb.useState)(.7),[A,P]=(0,eb.useState)(4096),[R,O]=(0,eb.useState)([]),[I,M]=(0,eb.useState)([]),[$,L]=(0,eb.useState)(!1),[U,B]=(0,eb.useState)(!1),[D,q]=(0,eb.useState)(!1),W=i||e||"",z=p===na?null:o.find(e=>nl(e)===p)??null,F=p===na,H=z?ni(z):null,V=(0,eb.useCallback)(async()=>{if(!e||!s||!r)return[];h(!0);try{let t=await eL(e,s,r);return c(t),p&&(p===na||t.some(e=>nl(e)===p))||g(t.length>0?nl(t[0]):null),t}catch(e){return console.error(e),eI.default.fromBackend("Failed to load agents"),[]}finally{h(!1)}},[e,s,r]),J=(0,eb.useCallback)(async()=>{if(W)try{let e=await (0,eU.fetchAvailableModels)(W);u(e),!k&&e.length>0&&C(e[0].model_group)}catch(e){console.error(e)}},[W]);(0,eb.useEffect)(()=>{V()},[V]),(0,eb.useEffect)(()=>{J()},[J]);let G=(0,eb.useCallback)(async()=>{if(W){L(!0);try{let e=await (0,eM.fetchMCPServers)(W);M(Array.isArray(e)?e:e?.data??[])}catch(e){console.error("Error fetching MCP servers:",e)}finally{L(!1)}}},[W]);(0,eb.useEffect)(()=>{G()},[G]),(0,eb.useEffect)(()=>{w(null)},[p]),(0,eb.useEffect)(()=>{if(z&&!F){_(z.model_name),S(z.litellm_params?.litellm_system_prompt??""),C(function(e){if(e&&e.startsWith("litellm_agent/"))return e.slice(14)||void 0}(z.litellm_params?.model)??d[0]?.model_group);let e=z.litellm_params;E("number"==typeof e?.temperature?e.temperature:.7),P("number"==typeof e?.max_tokens?e.max_tokens:4096);let t=z.litellm_params?.tools;O(Array.isArray(t)?t.filter(e=>e&&"object"==typeof e&&"mcp"===e.type&&"string"==typeof e.server_url):[])}},[p,F,z?.model_name,z?.litellm_params?.tools]);let K=R.filter(e=>"mcp"===e.type&&e.server_url?.startsWith(no)).map(e=>{let t=e.server_url.slice(no.length),s=I.find(e=>(e.alias||e.server_name||e.server_id)===t);return s?.server_id}).filter(e=>null!=e),X=()=>{g(na),_(""),S("You are a helpful assistant."),C(d[0]?.model_group),E(.7),P(4096),O([]),x("configure")},Y=async()=>{if(!e||!j?.trim()||!k)return void eI.default.fromBackend("Name and underlying model are required");B(!0);try{let t=await (0,eM.modelCreateCall)(e,{model_name:j.trim(),litellm_params:{model:`litellm_agent/${k}`,litellm_system_prompt:N.trim()||void 0,temperature:T,max_tokens:A,tools:R},model_info:{}}),s=t?.model_id??t?.model_info?.id??null,r=await V(),a=s?r.find(e=>ni(e)===s)??r.find(e=>e.model_name===j.trim()):r.find(e=>e.model_name===j.trim());g(a?nl(a):r[0]?nl(r[0]):null),x("chat")}catch(e){eI.default.fromBackend("Failed to save agent")}finally{B(!1)}},Q=async()=>{if(!e||!z||!H||!j?.trim()||!k)return void eI.default.fromBackend("Name and underlying model are required");B(!0);try{await (0,eM.modelPatchUpdateCall)(e,{model_name:j.trim(),litellm_params:{model:`litellm_agent/${k}`,litellm_system_prompt:N.trim()||void 0,temperature:T,max_tokens:A,tools:R},model_info:z.model_info??{}},H),eI.default.success("Agent updated successfully");let t=await V(),s=t.find(e=>ni(e)===H)??t[0];g(s?nl(s):null)}catch(e){eI.default.fromBackend("Failed to update agent")}finally{B(!1)}},Z=async()=>{if(e&&s&&z){b(!0),w(null);try{let t=await (0,eM.keyCreateCall)(e,s,{models:[z.model_name],key_alias:`Agent: ${z.model_name}`}),r=t?.key??null;r?(w(r),eI.default.success("Virtual key created. Use it in the curl example below.")):eI.default.fromBackend("Key created but value not returned")}catch(e){eI.default.fromBackend("Failed to create key for agent")}finally{b(!1)}}};return e&&s&&r?(0,ey.jsxs)("div",{className:"flex h-full flex-col bg-white text-gray-900",children:[(0,ey.jsxs)("div",{className:"flex shrink-0 flex-col border-b border-gray-200",children:[(0,ey.jsxs)("div",{className:"flex h-12 items-center justify-between px-4",children:[(0,ey.jsx)("span",{className:"text-sm font-medium text-gray-900",children:"Agent Builder"}),F?(0,ey.jsx)(eC.Button,{type:"primary",icon:(0,ey.jsx)(ek.SaveOutlined,{}),onClick:Y,loading:U,disabled:!j?.trim()||!k,children:"Save Agent"}):(0,ey.jsx)("span",{className:"text-xs text-gray-500",children:"Build Agents that pass your compliance requirements."})]}),(0,ey.jsxs)("div",{className:"flex items-center gap-2 border-t border-amber-200 bg-amber-50 px-4 py-2 text-xs text-amber-800",children:[(0,ey.jsx)(ej.ExperimentOutlined,{className:"shrink-0 text-amber-600"}),(0,ey.jsxs)("span",{children:["Agent Builder is experimental and may change or be removed without notice. We’d love your feedback—email us at"," ",(0,ey.jsx)("a",{href:"mailto:product@berri.ai",className:"font-medium text-amber-900 underline hover:text-amber-700",children:"product@berri.ai"}),"."]})]})]}),(0,ey.jsxs)("div",{className:"flex flex-1 overflow-hidden",children:[(0,ey.jsxs)("div",{className:"w-60 shrink-0 border-r border-gray-200 bg-white flex flex-col",children:[(0,ey.jsxs)("div",{className:"flex items-center justify-between border-b border-gray-200 p-3",children:[(0,ey.jsx)("span",{className:"text-xs font-semibold uppercase tracking-wide text-gray-500",children:"Agents"}),(0,ey.jsx)(eC.Button,{type:"text",size:"small",icon:(0,ey.jsx)(eN.PlusOutlined,{}),onClick:X,"aria-label":"Add agent"})]}),(0,ey.jsx)("div",{className:"flex-1 overflow-y-auto p-2",children:m?(0,ey.jsx)("div",{className:"flex justify-center py-4",children:(0,ey.jsx)(eP.Spin,{size:"small"})}):(0,ey.jsxs)(ey.Fragment,{children:[o.map(e=>{let t=nl(e);return(0,ey.jsxs)("button",{type:"button",onClick:()=>g(t),className:`mb-1 w-full rounded-md border-l-2 px-3 py-2 text-left text-sm transition-colors ${p===t?"border-blue-500 bg-blue-50 text-blue-800":"border-transparent hover:bg-gray-50"}`,children:[(0,ey.jsx)("div",{className:"font-medium truncate",children:e.model_name}),(0,ey.jsx)("div",{className:"text-[10px] text-gray-500 truncate",children:"litellm_agent"})]},t)}),(0,ey.jsxs)("button",{type:"button",onClick:X,className:"mb-1 w-full rounded-md border border-dashed border-gray-300 px-3 py-2 text-left text-sm text-gray-500 hover:border-blue-400 hover:bg-blue-50/50 hover:text-gray-700",children:[(0,ey.jsx)(eN.PlusOutlined,{className:"mr-1"})," New agent"]})]})})]}),(0,ey.jsxs)("div",{className:"flex flex-1 flex-col overflow-hidden",children:[null===p&&!F&&0===o.length&&!m&&(0,ey.jsx)("div",{className:"flex flex-1 items-center justify-center p-8 text-gray-500",children:"No agents yet. Add an agent to get started."}),(null!==p||F)&&(0,ey.jsx)(ey.Fragment,{children:(0,ey.jsx)(eR.Tabs,{activeKey:f,onChange:e=>x(e),className:"flex-1 overflow-hidden [&_.ant-tabs-content]:h-full [&_.ant-tabs-tabpane]:h-full [&_.ant-tabs-nav]:pl-4",items:[{key:"configure",label:(0,ey.jsxs)("span",{children:[(0,ey.jsx)(eS.RobotOutlined,{className:"mr-1"})," Configure"]}),children:(0,ey.jsx)("div",{className:"h-full overflow-y-auto p-6",children:F||z?(0,ey.jsxs)("div",{className:"mx-auto max-w-xl space-y-4",children:[!H&&z&&(0,ey.jsx)("div",{className:"rounded-sm border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800",children:"This agent cannot be updated or deleted here (missing model id). Manage it from Models & Endpoints."}),(0,ey.jsxs)("div",{children:[(0,ey.jsx)("label",{className:"mb-1 block text-sm font-medium text-gray-700",children:"Agent name"}),(0,ey.jsx)(eT.Input,{value:j,onChange:e=>_(e.target.value),placeholder:"My Agent"})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsx)("label",{className:"mb-1 block text-sm font-medium text-gray-700",children:"System prompt"}),(0,ey.jsx)(nr,{value:N,onChange:e=>S(e.target.value),placeholder:"You are a helpful assistant...",rows:6})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsx)("label",{className:"mb-1 block text-sm font-medium text-gray-700",children:"Underlying LLM"}),(0,ey.jsx)(eA.Select,{value:k,onChange:C,className:"w-full",options:d.map(e=>({value:e.model_group,label:e.model_group})),placeholder:"Select model"})]}),(0,ey.jsxs)("div",{className:"grid grid-cols-2 gap-4",children:[(0,ey.jsxs)("div",{children:[(0,ey.jsx)("label",{className:"mb-1 block text-sm font-medium text-gray-700",children:"Temperature"}),(0,ey.jsx)(eT.Input,{type:"number",min:0,max:2,step:.1,value:T,onChange:e=>E(Number(e.target.value))})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsx)("label",{className:"mb-1 block text-sm font-medium text-gray-700",children:"Max tokens"}),(0,ey.jsx)(eT.Input,{type:"number",min:1,value:A,onChange:e=>P(Number(e.target.value))})]})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsx)("label",{className:"mb-1 block text-sm font-medium text-gray-700",children:"MCP servers"}),(0,ey.jsx)(eA.Select,{mode:"multiple",placeholder:"Select MCP servers to attach (same format as chat completions API)",value:K,onChange:e=>{O(e.map(e=>{let t=I.find(t=>t.server_id===e),s=t?.alias||t?.server_name||e;return{type:"mcp",server_label:"litellm",server_url:`${no}${s}`,require_approval:"never"}}))},loading:$,className:"w-full",allowClear:!0,showSearch:!0,optionFilterProp:"label",options:I.map(e=>({value:e.server_id,label:e.alias||e.server_name||e.server_id}))}),z&&R.length>0&&(0,ey.jsxs)("p",{className:"mt-1 text-xs text-gray-500",children:[R.length," MCP server",1!==R.length?"s":""," saved. Use the same"," ",(0,ey.jsx)("code",{className:"rounded-sm bg-gray-100 px-1",children:"tools"})," array in chat completions when calling this agent."]})]}),z&&(0,ey.jsxs)("div",{className:"flex flex-wrap items-center gap-2 pt-2",children:[H&&(0,ey.jsxs)(ey.Fragment,{children:[(0,ey.jsx)(eC.Button,{type:"primary",icon:(0,ey.jsx)(ek.SaveOutlined,{}),onClick:Q,loading:U,disabled:!j?.trim()||!k,children:"Update Agent"}),(0,ey.jsx)(eC.Button,{type:"default",danger:!0,icon:(0,ey.jsx)(ew.DeleteOutlined,{}),onClick:()=>{z&&H&&e&&eE.Modal.confirm({title:"Delete agent",content:`Are you sure you want to delete "${z.model_name}"? This cannot be undone.`,okText:"Delete",okType:"danger",cancelText:"Cancel",onOk:async()=>{q(!0);try{await (0,eM.modelDeleteCall)(e,H),eI.default.success("Agent deleted");let t=(await V()).filter(e=>ni(e)!==H);g(t.length>0?nl(t[0]):null)}catch(e){eI.default.fromBackend("Failed to delete agent")}finally{q(!1)}}})},loading:D,children:"Delete"})]}),(0,ey.jsx)(eC.Button,{type:"primary",icon:(0,ey.jsx)(ev.CommentOutlined,{}),onClick:()=>x("chat"),children:"Test in Chat"})]})]}):null})},{key:"chat",label:(0,ey.jsxs)("span",{children:[(0,ey.jsx)(ev.CommentOutlined,{className:"mr-1"})," Chat"]}),disabled:F,children:(0,ey.jsx)("div",{className:"flex h-full flex-col min-h-0",children:z?(0,ey.jsx)(ns,{simplified:!0,fixedModel:z.model_name,accessToken:e,token:t,userRole:r,userID:s,disabledPersonalKeyCreation:a,proxySettings:n},z.model_name):(0,ey.jsx)("div",{className:"flex flex-1 items-center justify-center text-gray-500",children:"Save an agent first to test in Chat."})})},{key:"test",label:(0,ey.jsxs)("span",{children:[(0,ey.jsx)(ej.ExperimentOutlined,{className:"mr-1"})," Batch Test"]}),disabled:F,children:(0,ey.jsx)("div",{className:"flex h-full flex-col min-h-0",children:z?(0,ey.jsx)(tp,{accessToken:e,disabledPersonalKeyCreation:a,backendMode:"chat_completions",fixedModel:z.model_name,proxySettings:n}):(0,ey.jsx)("div",{className:"flex flex-1 items-center justify-center text-gray-500",children:"Select an agent to run batch tests."})})},{key:"connect",label:(0,ey.jsxs)("span",{children:[(0,ey.jsx)(e_.LinkOutlined,{className:"mr-1"})," Connect"]}),disabled:F,children:(0,ey.jsx)("div",{className:"h-full overflow-y-auto p-6",children:z?(0,ey.jsx)(nn,{agentName:z.model_name,proxySettings:n,customProxyBaseUrl:l,accessToken:e,userID:s,disabledPersonalKeyCreation:a,creatingKey:y,createdKeyValue:v,onCreateKey:Z}):(0,ey.jsx)("div",{className:"flex flex-1 items-center justify-center text-gray-500",children:"Select an agent to see how to connect."})})}]})})]})]})]}):(0,ey.jsx)("div",{className:"flex h-full items-center justify-center p-8 text-gray-500",children:"Sign in to use Agent Builder."})}var nd=e.i(903446),nd=nd;let nu=(0,eV.default)("user-round",[["circle",{cx:"12",cy:"8",r:"5",key:"1hypcn"}],["path",{d:"M20 21a8 8 0 0 0-16 0",key:"rfgkzh"}]]);function nm({messages:e,isLoading:t}){if(0===e.length)return(0,ey.jsx)("div",{className:"h-full"});let s=[],r=0;for(;r(0,ey.jsxs)("div",{className:"whitespace-pre-wrap wrap-break-word",style:{wordWrap:"break-word",overflowWrap:"break-word",wordBreak:"break-word",hyphens:"auto"},children:[(0,ey.jsx)(aL,{message:e}),(0,ey.jsx)(aS.default,{components:{code({node:e,inline:t,className:s,children:r,...a}){let n=/language-(\w+)/.exec(s||"");return!t&&n?(0,ey.jsx)(tq.Prism,{style:tW.coy,language:n[1],PreTag:"div",className:"rounded-md my-2",wrapLines:!0,wrapLongLines:!0,...a,children:String(r).replace(/\n$/,"")}):(0,ey.jsx)("code",{className:`${s} px-1.5 py-0.5 rounded-sm bg-gray-100 text-sm font-mono`,...a,children:r})},pre:({node:e,...t})=>(0,ey.jsx)("pre",{style:{overflowX:"auto",maxWidth:"100%"},...t})},children:"string"==typeof e.content?e.content:""})]});return(0,ey.jsxs)("div",{className:"flex flex-col gap-6 min-w-0 w-full p-4",children:[s.map((e,r)=>{let n=e.assistant,i=n?.model||"Assistant";return(0,ey.jsxs)("div",{className:"space-y-4",children:[e.user&&(0,ey.jsxs)("div",{className:"space-y-2 min-w-0",children:[(0,ey.jsxs)("div",{className:"flex items-center gap-3",children:[(0,ey.jsx)("div",{className:"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-blue-100 text-blue-600",children:(0,ey.jsx)(nu,{size:16})}),(0,ey.jsx)("div",{className:"text-sm font-semibold text-gray-700",children:"You"})]}),a(e.user)]}),(0,ey.jsx)("div",{className:"border-t border-gray-200"}),n?(0,ey.jsxs)("div",{className:"space-y-3 min-w-0",children:[(0,ey.jsxs)("div",{className:"flex items-center gap-3",children:[(0,ey.jsx)("div",{className:"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-gray-100 text-gray-600",children:(0,ey.jsx)(eH.Bot,{size:16})}),(0,ey.jsxs)("div",{className:"flex items-center gap-2",children:[(0,ey.jsx)("span",{className:"text-sm font-semibold text-gray-700",children:i}),n.toolName&&(0,ey.jsx)("span",{className:"rounded-sm bg-gray-100 px-2 py-0.5 text-xs text-gray-600",children:n.toolName})]})]}),n.reasoningContent&&(0,ey.jsx)(aF.default,{reasoningContent:n.reasoningContent}),n.searchResults&&(0,ey.jsx)(aK,{searchResults:n.searchResults}),a(n),(n.timeToFirstToken||n.totalLatency||n.usage)&&(0,ey.jsx)(aH.default,{timeToFirstToken:n.timeToFirstToken,totalLatency:n.totalLatency,usage:n.usage,toolName:n.toolName})]}):t&&r===s.length-1?(0,ey.jsxs)("div",{className:"flex items-center gap-2 text-sm text-gray-500",children:[(0,ey.jsx)(e4.Loader2,{size:18,className:"animate-spin"}),(0,ey.jsx)("span",{children:"Generating response..."})]}):(0,ey.jsx)("div",{className:"text-sm text-gray-500",children:"Waiting for a response..."})]},r)}),t&&0===s.length&&(0,ey.jsxs)("div",{className:"flex items-center gap-2 text-gray-500",children:[(0,ey.jsx)(e4.Loader2,{size:18,className:"animate-spin"}),(0,ey.jsx)("span",{children:"Generating response..."})]})]})}function nh({value:e,options:t,loading:s,config:r,onChange:a}){return(0,ey.jsx)(eA.Select,{value:e||void 0,placeholder:s?`Loading ${r.selectorLabel.toLowerCase()}s...`:r.selectorPlaceholder,onChange:a,loading:s,showSearch:!0,filterOption:(e,t)=>(t?.label??"").toLowerCase().includes(e.toLowerCase()),options:t,className:"w-48 md:w-64 lg:w-72",notFoundContent:s?(0,ey.jsx)("div",{className:"flex items-center justify-center py-2",children:(0,ey.jsx)(eP.Spin,{size:"small"})}):`No ${r.selectorLabel.toLowerCase()}s available`})}var np=e.i(312361);let ng="/v1/chat/completions",nf="/a2a",nx={[ng]:{id:ng,label:"/v1/chat/completions",selectorType:"model",selectorLabel:"Model",selectorPlaceholder:"Select a model",inputPlaceholder:"Send a prompt to compare models",loadingMessage:"Gathering responses from all models...",validationMessage:"Select a model before sending a message."},[nf]:{id:nf,label:"/a2a (Agents)",selectorType:"agent",selectorLabel:"Agent",selectorPlaceholder:"Select an agent",inputPlaceholder:"Send a message to compare agents",loadingMessage:"Gathering responses from all agents...",validationMessage:"Select an agent before sending a message."}},ny=e=>"agent"===nx[e].selectorType,nb=(e,t)=>ny(t)?e.agent:e.model;function nv({comparison:e,onUpdate:t,onRemove:s,canRemove:r,selectorOptions:a,isLoadingOptions:n,endpointConfig:i,apiKey:l}){let o=ny(i.id),c=nb(e,i.id),[d,u]=(0,eb.useState)(!1),m=(s,r)=>{t({[s]:r},e.applyAcrossModels?{applyToAll:!0,keysToApply:[s]}:void 0)},h=e.useAdvancedParams?1:.4,p=e.useAdvancedParams?"text-gray-700":"text-gray-400",g=(0,ey.jsxs)("div",{className:"w-[300px] max-h-[65vh] overflow-y-auto relative",children:[(0,ey.jsx)("button",{onClick:()=>{u(!1)},className:"absolute top-0 right-0 p-1 hover:bg-gray-100 rounded-sm transition-colors text-gray-500 hover:text-gray-700 z-10",children:(0,ey.jsx)(td.X,{size:14})}),(0,ey.jsxs)("div",{className:"space-y-2",children:[(0,ey.jsx)("div",{className:"flex items-center gap-2",children:(0,ey.jsx)(aa.Checkbox,{checked:e.applyAcrossModels,onChange:s=>{s.target.checked?t({applyAcrossModels:!0,temperature:e.temperature,maxTokens:e.maxTokens,tags:[...e.tags],vectorStores:[...e.vectorStores],guardrails:[...e.guardrails],useAdvancedParams:e.useAdvancedParams},{applyToAll:!0,keysToApply:["temperature","maxTokens","tags","vectorStores","guardrails","useAdvancedParams"]}):t({applyAcrossModels:!1})},children:(0,ey.jsx)("span",{className:"text-xs font-medium",children:"Sync Settings Across Models"})})}),(0,ey.jsx)(np.Divider,{className:"border-gray-200"}),(0,ey.jsxs)("div",{children:[(0,ey.jsx)("h4",{className:"text-xs font-semibold text-gray-700 mb-1.5 uppercase tracking-wide",children:"General Settings"}),(0,ey.jsxs)("div",{className:"space-y-2",children:[(0,ey.jsxs)("div",{children:[(0,ey.jsx)("label",{className:"text-xs font-medium text-gray-600 block mb-0.5",children:"Tags"}),(0,ey.jsx)(t0,{value:e.tags,onChange:e=>m("tags",e),accessToken:l})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsx)("label",{className:"text-xs font-medium text-gray-600 block mb-0.5",children:"Vector Stores"}),(0,ey.jsx)(t1.default,{value:e.vectorStores,onChange:e=>m("vectorStores",e),accessToken:l})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsx)("label",{className:"text-xs font-medium text-gray-600 block mb-0.5",children:"Guardrails"}),(0,ey.jsx)(tV.default,{value:e.guardrails,onChange:e=>m("guardrails",e),accessToken:l})]})]})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsx)("h4",{className:"text-xs font-semibold text-gray-700 mb-1.5 uppercase tracking-wide",children:"Advanced Settings"}),(0,ey.jsxs)("div",{className:"space-y-2",children:[(0,ey.jsx)("div",{className:"flex items-center gap-2 pb-1",children:(0,ey.jsx)(aa.Checkbox,{checked:e.useAdvancedParams,onChange:s=>{t({useAdvancedParams:s.target.checked},e.applyAcrossModels?{applyToAll:!0,keysToApply:["useAdvancedParams"]}:void 0)},children:(0,ey.jsx)("span",{className:"text-sm font-medium",children:"Use Advanced Parameters"})})}),(0,ey.jsxs)("div",{className:"space-y-2 transition-opacity duration-200",style:{opacity:h},children:[(0,ey.jsxs)("div",{children:[(0,ey.jsxs)("div",{className:"flex items-center justify-between mb-1",children:[(0,ey.jsx)("label",{className:`text-xs font-medium ${p}`,children:"Temperature"}),(0,ey.jsx)("span",{className:`text-xs ${p}`,children:e.temperature.toFixed(2)})]}),(0,ey.jsx)(an.Slider,{min:0,max:2,step:.01,value:e.temperature,onChange:e=>{m("temperature",Math.min(2,Math.max(0,Number((Array.isArray(e)?e[0]:e).toFixed(2)))))},disabled:!e.useAdvancedParams})]}),(0,ey.jsxs)("div",{children:[(0,ey.jsxs)("div",{className:"flex items-center justify-between mb-1",children:[(0,ey.jsx)("label",{className:`text-xs font-medium ${p}`,children:"Max Tokens"}),(0,ey.jsx)("span",{className:`text-xs ${p}`,children:e.maxTokens})]}),(0,ey.jsx)(an.Slider,{min:1,max:32768,step:1,value:e.maxTokens,onChange:e=>{m("maxTokens",Math.min(32768,Math.max(1,Math.round(Array.isArray(e)?e[0]:e))))},disabled:!e.useAdvancedParams})]})]})]})]})]})]});return(0,ey.jsxs)("div",{className:"bg-white first:border-l-0 border-l border-gray-200 flex flex-col min-h-0",children:[(0,ey.jsxs)("div",{className:"border-b flex items-center justify-between gap-3 px-4 py-3",children:[(0,ey.jsxs)("div",{className:"flex items-center gap-3 flex-1",children:[(0,ey.jsx)(nh,{value:c,options:a,loading:n,config:i,onChange:e=>t(o?{agent:e}:{model:e})}),(0,ey.jsx)("div",{className:"flex items-center gap-2",children:(0,ey.jsx)(tL.Popover,{content:g,trigger:[],open:d,onOpenChange:()=>{},placement:"bottomRight",destroyTooltipOnHide:!1,children:(0,ey.jsx)("button",{onClick:e=>{e.stopPropagation(),u(e=>!e)},className:`p-2 rounded-lg transition-colors ${d?"bg-gray-200 text-gray-700":"hover:bg-gray-100 text-gray-600"}`,children:(0,ey.jsx)(nd.default,{size:18})})})})]}),r&&(0,ey.jsx)("button",{onClick:e=>{e.stopPropagation(),s()},className:"p-2 hover:bg-red-50 text-red-600 rounded-lg transition-colors",children:(0,ey.jsx)(td.X,{size:18})})]}),(0,ey.jsx)("div",{className:"relative flex-1 flex flex-col min-h-0",children:(0,ey.jsx)("div",{className:"flex-1 max-h-[calc(100vh-385px)] overflow-auto rounded-b-2xl",children:(0,ey.jsx)(nm,{messages:e.messages,isLoading:e.isLoading})})})]})}let{TextArea:nw}=eT.Input;function nj({value:e,onChange:t,onSend:s,disabled:r,hasAttachment:a,uploadComponent:n}){let i=!r&&(e.trim().length>0||!!a);return(0,ey.jsx)("div",{className:"flex items-center gap-2",children:(0,ey.jsxs)("div",{className:"flex items-center flex-1 bg-white border border-gray-300 rounded-xl px-3 py-1 min-h-[44px]",children:[n&&(0,ey.jsx)("div",{className:"shrink-0 mr-2",children:n}),(0,ey.jsx)(nw,{value:e,onChange:e=>t(e.target.value),onKeyDown:e=>{"Enter"===e.key&&!e.shiftKey&&(e.preventDefault(),i&&s())},placeholder:"Type your message... (Shift+Enter for new line)",disabled:r,className:"flex-1",autoSize:{minRows:1,maxRows:4},style:{resize:"none",border:"none",boxShadow:"none",background:"transparent",padding:"4px 0",fontSize:"14px",lineHeight:"20px"}}),(0,ey.jsx)(eC.Button,{onClick:s,disabled:!i,icon:(0,ey.jsx)(tf.ArrowUpOutlined,{}),shape:"circle"})]})})}let n_=["Can you summarize the key points?","What assumptions did you make?","What are the next steps?"],nN=["Write me a poem","Explain quantum computing","Draft a polite email requesting a meeting"];function nS({accessToken:e,disabledPersonalKeyCreation:t}){let[s,r]=(0,eb.useState)([{id:"1",model:"",agent:"",messages:[],isLoading:!1,tags:[],mcpTools:[],vectorStores:[],guardrails:[],temperature:1,maxTokens:2048,applyAcrossModels:!1,useAdvancedParams:!1},{id:"2",model:"",agent:"",messages:[],isLoading:!1,tags:[],mcpTools:[],vectorStores:[],guardrails:[],temperature:1,maxTokens:2048,applyAcrossModels:!1,useAdvancedParams:!1}]),[a,n]=(0,eb.useState)([]),[i,l]=(0,eb.useState)([]),[o,c]=(0,eb.useState)(!1),[d,u]=(0,eb.useState)(!1),[m,h]=(0,eb.useState)(ng),p=nx[m],g=ny(m),f=g?i.map(e=>({value:e.agent_name,label:e.agent_name||e.agent_id})):a.map(e=>({value:e,label:e})),x=g?d:o,[y,b]=(0,eb.useState)(""),[v,w]=(0,eb.useState)(null),[j,_]=(0,eb.useState)(null),[N,S]=(0,eb.useState)(t?"custom":"session"),[k,C]=(0,eb.useState)(""),[T,E]=(0,eb.useState)(""),[A]=(0,eb.useState)(()=>sessionStorage.getItem("customProxyBaseUrl")||"");(0,eb.useEffect)(()=>{let e=setTimeout(()=>{E(k)},300);return()=>clearTimeout(e)},[k]),(0,eb.useEffect)(()=>()=>{j&&URL.revokeObjectURL(j)},[j]);let P=(0,eb.useMemo)(()=>"session"===N?e||"":T.trim(),[N,e,T]),R=(0,eb.useMemo)(()=>s.length>0&&s.every(e=>!e.isLoading&&e.messages.some(e=>"assistant"===e.role)),[s]);(0,eb.useEffect)(()=>{let e=!0;return(async()=>{if(!P)return n([]);c(!0);try{let t=await (0,eU.fetchAvailableModels)(P);if(!e)return;let s=Array.from(new Set(t.map(e=>e.model_group)));n(s)}catch(t){console.error("CompareUI: failed to fetch models",t),e&&n([])}finally{e&&c(!1)}})(),()=>{e=!1}},[P]),(0,eb.useEffect)(()=>{let e=!0;return(async()=>{if(!P||!g)return l([]);u(!0);try{let t=await e$(P,A||void 0);if(!e)return;l(t)}catch(t){console.error("CompareUI: failed to fetch agents",t),e&&l([])}finally{e&&u(!1)}})(),()=>{e=!1}},[P,g]),(0,eb.useEffect)(()=>{0!==a.length&&r(e=>e.map((e,t)=>({...e,temperature:e.temperature??1,maxTokens:e.maxTokens??2048,applyAcrossModels:e.applyAcrossModels??!1,useAdvancedParams:e.useAdvancedParams??!1,...e.model?{}:{model:a[t%a.length]??""}})))},[a]);let O=()=>{j&&URL.revokeObjectURL(j),w(null),_(null)},I=(e,t)=>{r(s=>s.map(s=>{if(s.id!==e)return s;let r=[...s.messages],a=r[r.length-1];return a&&"assistant"===a.role?r[r.length-1]={...a,timeToFirstToken:t}:a&&"user"===a.role&&r.push({role:"assistant",content:"",timeToFirstToken:t}),{...s,messages:r}}))},M=(e,t)=>{r(s=>s.map(s=>{if(s.id!==e)return s;let r=[...s.messages],a=r[r.length-1];return a&&"assistant"===a.role?r[r.length-1]={...a,totalLatency:t}:a&&"user"===a.role&&r.push({role:"assistant",content:"",totalLatency:t}),{...s,messages:r}}))},$=!!e,L=async e=>{let t=e.trim(),a=!!v;if(!t&&!a)return;if(!P)return void eI.default.fromBackend("Please provide a Virtual Key or select Current UI Session");if(0===s.length)return;if(s.some(e=>{let t;return!((t=nb(e,m))&&t.trim())}))return void eI.default.fromBackend(p.validationMessage);let n=a?await ap(t,v):{role:"user",content:t},i=ag(t,a,j||void 0,v?.name),l=new Map;s.forEach(e=>{let s=e.traceId??tH(),r=[...e.messages.map(({role:e,content:t})=>({role:e,content:Array.isArray(t)||"string"==typeof t?t:""})),n];l.set(e.id,{id:e.id,model:e.model,agent:e.agent,inputMessage:t,traceId:s,tags:e.tags,vectorStores:e.vectorStores,guardrails:e.guardrails,temperature:e.temperature,maxTokens:e.maxTokens,displayMessages:[...e.messages,i],apiChatHistory:r})}),0!==l.size&&(r(e=>e.map(e=>{let t=l.get(e.id);return t?{...e,traceId:t.traceId,messages:t.displayMessages,isLoading:!0}:e})),b(""),O(),l.forEach(e=>{let t=e.tags.length>0?e.tags:void 0,a=e.vectorStores.length>0?e.vectorStores:void 0,n=e.guardrails.length>0?e.guardrails:void 0,i=s.find(t=>t.id===e.id),l=i?.useAdvancedParams??!1;(g?t4(e.agent,e.inputMessage,(t,s)=>{r(r=>r.map(r=>{if(r.id!==e.id)return r;let a=[...r.messages],n=a[a.length-1];return n&&"assistant"===n.role?a[a.length-1]={...n,content:t,model:n.model??s}:a.push({role:"assistant",content:t,model:s}),{...r,messages:a}}))},P,void 0,t=>I(e.id,t),t=>M(e.id,t),void 0,A||void 0):eW(e.apiChatHistory,(t,s)=>{var a;return a=e.id,void(t&&r(e=>e.map(e=>{if(e.id!==a)return e;let r=[...e.messages],n=r[r.length-1];if(n&&"assistant"===n.role){let e="string"==typeof n.content?n.content:"";r[r.length-1]={...n,content:e+t,model:n.model??s}}else r.push({role:"assistant",content:t,model:s});return{...e,messages:r}})))},e.model,P,t,void 0,t=>{var s;return s=e.id,void(t&&r(e=>e.map(e=>{if(e.id!==s)return e;let r=[...e.messages],a=r[r.length-1];return a&&"assistant"===a.role?r[r.length-1]={...a,reasoningContent:(a.reasoningContent||"")+t}:a&&"user"===a.role&&r.push({role:"assistant",content:"",reasoningContent:t}),{...e,messages:r}})))},t=>I(e.id,t),t=>{var s,a;return s=e.id,void r(e=>e.map(e=>{if(e.id!==s)return e;let r=[...e.messages],n=r[r.length-1];return n&&"assistant"===n.role&&(r[r.length-1]={...n,usage:t,toolName:a}),{...e,messages:r}}))},e.traceId,a,n,void 0,void 0,void 0,t=>{var s;return s=e.id,void(t&&r(e=>e.map(e=>{if(e.id!==s)return e;let r=[...e.messages],a=r[r.length-1];return a&&"assistant"===a.role&&(r[r.length-1]={...a,searchResults:t}),{...e,messages:r}})))},l?e.temperature:void 0,l?e.maxTokens:void 0,t=>M(e.id,t),A||void 0)).catch(t=>{let s=t instanceof Error?t.message:String(t);console.error("CompareUI: failed to fetch response",t),eI.default.fromBackend(s),r(t=>t.map(t=>{if(t.id!==e.id)return t;let r=[...t.messages],a=r[r.length-1],n=a&&"assistant"===a.role&&"string"==typeof a.content?a.content:"";return a&&"assistant"===a.role?r[r.length-1]={...a,content:n?`${n} +Error fetching response: ${s}`:`Error fetching response: ${s}`}:r.push({role:"assistant",content:`Error fetching response: ${s}`}),{...t,messages:r}}))}).finally(()=>{r(t=>t.map(t=>t.id===e.id?{...t,isLoading:!1}:t))})}))},U=e=>{b(e)},B=s.some(e=>e.messages.length>0),D=s.some(e=>e.isLoading),q=!!v,W=!!v?.name.toLowerCase().endsWith(".pdf"),z=!B&&!D&&!q;return(0,ey.jsx)("div",{className:"w-full h-full p-4 bg-white",children:(0,ey.jsxs)("div",{className:"rounded-2xl border border-gray-200 bg-white shadow-xs min-h-[calc(100vh-160px)] flex flex-col",children:[(0,ey.jsx)("div",{className:"border-b px-4 py-2",children:(0,ey.jsxs)("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[(0,ey.jsxs)("div",{className:"flex items-center gap-2",children:[(0,ey.jsx)("span",{className:"text-sm font-medium text-gray-600",children:"Virtual Key Source"}),(0,ey.jsxs)(eA.Select,{value:N,onChange:e=>S(e),disabled:t,className:"w-48",children:[(0,ey.jsx)(eA.Select.Option,{value:"session",disabled:!$,children:"Current UI Session"}),(0,ey.jsx)(eA.Select.Option,{value:"custom",children:"Virtual Key"})]}),"custom"===N&&(0,ey.jsx)(eT.Input.Password,{value:k,onChange:e=>C(e.target.value),placeholder:"Enter Virtual Key",className:"w-56"})]}),(0,ey.jsxs)("div",{className:"flex items-center gap-2",children:[(0,ey.jsx)("span",{className:"text-sm font-medium text-gray-600",children:"Endpoint"}),(0,ey.jsx)(eA.Select,{value:m,onChange:e=>h(e),className:"w-56",children:Object.values(nx).map(e=>({value:e.id,label:e.label})).map(e=>(0,ey.jsx)(eA.Select.Option,{value:e.value,children:e.label},e.value))})]}),(0,ey.jsxs)("div",{className:"flex items-center gap-3",children:[(0,ey.jsx)(eC.Button,{onClick:()=>{r(e=>e.map(e=>({...e,messages:[],traceId:void 0,isLoading:!1}))),b(""),O()},disabled:!B,icon:(0,ey.jsx)(tx.ClearOutlined,{}),children:"Clear All Chats"}),(0,ey.jsx)(tU.Tooltip,{title:s.length>=3?"Compare up to 3 models at a time":"Add another comparison",children:(0,ey.jsx)(eC.Button,{onClick:()=>{if(s.length>=3)return;let e=a[s.length%(a.length||1)]??"",t=i[s.length%(i.length||1)]?.agent_name??"",n={id:Date.now().toString(),model:e,agent:t,messages:[],isLoading:!1,tags:[],mcpTools:[],vectorStores:[],guardrails:[],temperature:1,maxTokens:2048,applyAcrossModels:!1,useAdvancedParams:!1};r(e=>[...e,n])},disabled:s.length>=3,icon:(0,ey.jsx)(eN.PlusOutlined,{}),children:"Add Comparison"})})]})]})}),(0,ey.jsx)("div",{className:"grid flex-1 min-h-0 auto-rows-fr",style:{gridTemplateColumns:`repeat(${s.length}, minmax(0, 1fr))`},children:s.map(e=>(0,ey.jsx)(nv,{comparison:e,onUpdate:(t,s)=>{var a;return a=e.id,void r(e=>{if(s?.applyToAll&&s.keysToApply?.length){let r={};s.keysToApply.forEach(e=>{let s=t[e];void 0!==s&&(r[e]=Array.isArray(s)?[...s]:s)});let n=Object.keys(r).length>0;return e.map(e=>e.id===a?{...e,...t}:n?{...e,...r}:e)}return e.map(e=>e.id===a?{...e,...t}:e)})},onRemove:()=>{var t;return t=e.id,void(s.length>1&&r(e=>e.filter(e=>e.id!==t)))},canRemove:s.length>1,selectorOptions:f,isLoadingOptions:x,endpointConfig:p,apiKey:P},e.id))}),(0,ey.jsx)("div",{className:"flex justify-center pb-4",children:(0,ey.jsx)("div",{className:"w-full max-w-3xl px-4",children:(0,ey.jsxs)("div",{className:"border border-gray-200 shadow-lg rounded-xl bg-white p-4",children:[(0,ey.jsx)("div",{className:"flex items-center justify-between gap-4 mb-3 min-h-8",children:q?(0,ey.jsx)("span",{className:"text-sm text-gray-500",children:"Attachment ready to send"}):z?(0,ey.jsx)("div",{className:"flex items-center gap-2 overflow-x-auto",children:nN.map(e=>(0,ey.jsx)("button",{type:"button",onClick:()=>U(e),className:"shrink-0 rounded-full border border-gray-200 px-3 py-1 text-xs font-medium text-gray-600 transition-colors hover:bg-gray-100 cursor-pointer",children:e},e))}):R&&!q?(0,ey.jsx)("div",{className:"flex items-center gap-2 overflow-x-auto",children:n_.map(e=>(0,ey.jsx)("button",{type:"button",onClick:()=>U(e),className:"shrink-0 rounded-full border border-gray-200 px-3 py-1 text-xs font-medium text-gray-600 transition-colors hover:bg-gray-100 cursor-pointer",children:e},e))}):D?(0,ey.jsxs)("span",{className:"flex items-center gap-2 text-sm text-gray-500",children:[(0,ey.jsx)("span",{className:"h-2 w-2 rounded-full bg-blue-500 animate-pulse","aria-hidden":!0}),p.loadingMessage]}):(0,ey.jsx)("span",{className:"text-sm text-gray-500",children:p.inputPlaceholder})}),v&&(0,ey.jsx)("div",{className:"mb-3",children:(0,ey.jsxs)("div",{className:"flex items-center gap-3 p-3 bg-gray-50 rounded-lg border border-gray-200",children:[(0,ey.jsx)("div",{className:"relative inline-block",children:W?(0,ey.jsx)("div",{className:"w-10 h-10 rounded-md bg-red-500 flex items-center justify-center",children:(0,ey.jsx)(aj.FilePdfOutlined,{style:{fontSize:"16px",color:"white"}})}):(0,ey.jsx)("img",{src:j||"",alt:"Upload preview",className:"w-10 h-10 rounded-md border border-gray-200 object-cover"})}),(0,ey.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,ey.jsx)("div",{className:"text-sm font-medium text-gray-900 truncate",children:v.name}),(0,ey.jsx)("div",{className:"text-xs text-gray-500",children:W?"PDF":"Image"})]}),(0,ey.jsx)("button",{className:"flex items-center justify-center w-6 h-6 text-gray-400 hover:text-gray-600 hover:bg-gray-200 rounded-full transition-colors",onClick:O,children:(0,ey.jsx)(ew.DeleteOutlined,{style:{fontSize:"12px"}})})]})}),(0,ey.jsx)(nj,{value:y,onChange:e=>{b(e)},onSend:()=>{L(y)},disabled:0===s.length||s.every(e=>e.isLoading),hasAttachment:q,uploadComponent:(0,ey.jsx)(ah,{chatUploadedImage:v,chatImagePreviewUrl:j,onImageUpload:e=>(j&&URL.revokeObjectURL(j),w(e),_(URL.createObjectURL(e)),!1),onRemoveImage:O})})]})})})]})})}var nk=e.i(653824),nC=e.i(881073),nT=e.i(197647),nE=e.i(723731),nA=e.i(404206),nP=e.i(135214),nR=e.i(62478);e.s(["default",0,function(){let{accessToken:e,userRole:t,userId:s,disabledPersonalKeyCreation:r,token:a}=(0,nP.default)(),[n,i]=(0,eb.useState)(void 0);return(0,eb.useEffect)(()=>{(async()=>{if(e){let t=await (0,nR.fetchProxySettings)(e);t&&i({PROXY_BASE_URL:t.PROXY_BASE_URL,LITELLM_UI_API_DOC_BASE_URL:t.LITELLM_UI_API_DOC_BASE_URL})}})()},[e]),(0,ey.jsx)("div",{className:"h-full w-full flex flex-col",children:(0,ey.jsxs)(nk.TabGroup,{className:"w-full",style:{flex:1,minHeight:0,display:"flex",flexDirection:"column"},children:[(0,ey.jsxs)(nC.TabList,{className:"mb-0",children:[(0,ey.jsx)(nT.Tab,{children:"Chat"}),(0,ey.jsx)(nT.Tab,{children:"Compare"}),(0,ey.jsx)(nT.Tab,{children:"Compliance"}),(0,ey.jsx)(nT.Tab,{children:"Agent Builder (Experimental)"})]}),(0,ey.jsxs)(nE.TabPanels,{className:"h-full",children:[(0,ey.jsx)(nA.TabPanel,{className:"h-full",children:(0,ey.jsx)(ns,{accessToken:e,token:a,userRole:t,userID:s,disabledPersonalKeyCreation:r,proxySettings:n})}),(0,ey.jsx)(nA.TabPanel,{className:"h-full",children:(0,ey.jsx)(nS,{accessToken:e,disabledPersonalKeyCreation:r})}),(0,ey.jsx)(nA.TabPanel,{className:"h-full",children:(0,ey.jsx)(tp,{accessToken:e,disabledPersonalKeyCreation:r})}),(0,ey.jsx)(nA.TabPanel,{className:"h-full",children:(0,ey.jsx)(nc,{accessToken:e,token:a,userID:s,userRole:t,disabledPersonalKeyCreation:r,proxySettings:n,customProxyBaseUrl:n?.LITELLM_UI_API_DOC_BASE_URL??n?.PROXY_BASE_URL})})]})]})})}],213970)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0pu3ltw1cci2~.js b/litellm/proxy/_experimental/out/_next/static/chunks/0pu3ltw1cci2~.js new file mode 100644 index 00000000000..481b9e60300 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/0pu3ltw1cci2~.js @@ -0,0 +1,35 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,629569,e=>{"use strict";var t=e.i(290571),r=e.i(95779),s=e.i(444755),o=e.i(673706),i=e.i(271645);let l=i.default.forwardRef((e,l)=>{let{color:a,children:n,className:d}=e,c=(0,t.__rest)(e,["color","children","className"]);return i.default.createElement("p",Object.assign({ref:l,className:(0,s.tremorTwMerge)("font-medium text-tremor-title",a?(0,o.getColorClassNames)(a,r.colorPalette.darkText).textColor:"text-tremor-content-strong dark:text-dark-tremor-content-strong",d)},c),n)});l.displayName="Title",e.s(["Title",0,l],629569)},166406,e=>{"use strict";var t=e.i(190144);e.s(["CopyOutlined",()=>t.default])},411929,e=>{"use strict";var t=e.i(843476),r=e.i(271645),s=e.i(464571),o=e.i(166406),i=e.i(629569),l=e.i(602869),a=e.i(727749);let n=({accessToken:e})=>{let[n,d]=(0,r.useState)(`{ + "model": "openai/gpt-4o", + "messages": [ + { + "role": "system", + "content": "You are a helpful assistant." + }, + { + "role": "user", + "content": "Explain quantum computing in simple terms" + } + ], + "temperature": 0.7, + "max_tokens": 500, + "stream": true +}`),[c,p]=(0,r.useState)(""),[u,m]=(0,r.useState)(!1),x=async()=>{m(!0);try{let o;try{o=JSON.parse(n)}catch(e){a.default.fromBackend("Invalid JSON in request body"),m(!1);return}let i={call_type:"completion",request_body:o};if(!e){a.default.fromBackend("No access token found"),m(!1);return}let d=await (0,l.transformRequestCall)(e,i);if(d.raw_request_api_base&&d.raw_request_body){var t,r,s;let e,o,i=(t=d.raw_request_api_base,r=d.raw_request_body,s=d.raw_request_headers||{},e=JSON.stringify(r,null,2).split("\n").map(e=>` ${e}`).join("\n"),o=Object.entries(s).map(([e,t])=>`-H '${e}: ${t}'`).join(" \\\n "),`curl -X POST \\ + ${t} \\ + ${o?`${o} \\ + `:""}-H 'Content-Type: application/json' \\ + -d '{ +${e} + }'`);p(i),a.default.success("Request transformed successfully")}else{let e="string"==typeof d?d:JSON.stringify(d);p(e),a.default.info("Transformed request received in unexpected format")}}catch(e){console.error("Error transforming request:",e),a.default.fromBackend("Failed to transform request")}finally{m(!1)}};return(0,t.jsxs)("div",{className:"w-full m-2",style:{overflow:"hidden"},children:[(0,t.jsx)(i.Title,{children:"Playground"}),(0,t.jsx)("p",{className:"text-sm text-gray-500",children:"See how LiteLLM transforms your request for the specified provider."}),(0,t.jsxs)("div",{style:{display:"flex",gap:"16px",width:"100%",minWidth:0,overflow:"hidden"},className:"mt-4",children:[(0,t.jsxs)("div",{style:{flex:"1 1 50%",display:"flex",flexDirection:"column",border:"1px solid #e8e8e8",borderRadius:"8px",padding:"24px",overflow:"hidden",maxHeight:"600px",minWidth:0},children:[(0,t.jsxs)("div",{style:{marginBottom:"24px"},children:[(0,t.jsx)("h2",{style:{fontSize:"24px",fontWeight:"bold",margin:"0 0 4px 0"},children:"Original Request"}),(0,t.jsx)("p",{style:{color:"#666",margin:0},children:"The request you would send to LiteLLM /chat/completions endpoint."})]}),(0,t.jsx)("textarea",{style:{flex:"1 1 auto",width:"100%",minHeight:"240px",padding:"16px",border:"1px solid #e8e8e8",borderRadius:"6px",fontFamily:"monospace",fontSize:"14px",resize:"none",marginBottom:"24px",overflow:"auto"},value:n,onChange:e=>d(e.target.value),onKeyDown:e=>{(e.metaKey||e.ctrlKey)&&"Enter"===e.key&&(e.preventDefault(),x())},placeholder:"Press Cmd/Ctrl + Enter to transform"}),(0,t.jsx)("div",{style:{display:"flex",justifyContent:"flex-end",marginTop:"auto"},children:(0,t.jsxs)(s.Button,{type:"primary",style:{backgroundColor:"#000",display:"flex",alignItems:"center",gap:"8px"},onClick:x,loading:u,children:[(0,t.jsx)("span",{children:"Transform"}),(0,t.jsx)("span",{children:"→"})]})})]}),(0,t.jsxs)("div",{style:{flex:"1 1 50%",display:"flex",flexDirection:"column",border:"1px solid #e8e8e8",borderRadius:"8px",padding:"24px",overflow:"hidden",maxHeight:"800px",minWidth:0},children:[(0,t.jsxs)("div",{style:{marginBottom:"24px"},children:[(0,t.jsx)("h2",{style:{fontSize:"24px",fontWeight:"bold",margin:"0 0 4px 0"},children:"Transformed Request"}),(0,t.jsx)("p",{style:{color:"#666",margin:0},children:"How LiteLLM transforms your request for the specified provider."}),(0,t.jsx)("br",{}),(0,t.jsx)("p",{style:{color:"#666",margin:0},className:"text-xs",children:"Note: Sensitive headers are not shown."})]}),(0,t.jsxs)("div",{style:{position:"relative",backgroundColor:"#f5f5f5",borderRadius:"6px",flex:"1 1 auto",display:"flex",flexDirection:"column",overflow:"hidden"},children:[(0,t.jsx)("pre",{style:{padding:"16px",fontFamily:"monospace",fontSize:"14px",margin:0,overflow:"auto",flex:"1 1 auto"},children:c||`curl -X POST \\ + https://api.openai.com/v1/chat/completions \\ + -H 'Authorization: Bearer sk-xxx' \\ + -H 'Content-Type: application/json' \\ + -d '{ + "model": "gpt-4", + "messages": [ + { + "role": "system", + "content": "You are a helpful assistant." + } + ], + "temperature": 0.7 + }'`}),(0,t.jsx)(s.Button,{type:"text",icon:(0,t.jsx)(o.CopyOutlined,{}),style:{position:"absolute",right:"8px",top:"8px"},size:"small",onClick:()=>{navigator.clipboard.writeText(c||""),a.default.success("Copied to clipboard")}})]})]})]}),(0,t.jsx)("div",{className:"mt-4 text-right w-full",children:(0,t.jsxs)("p",{className:"text-sm text-gray-500",children:["Found an error? File an issue"," ",(0,t.jsx)("a",{href:"https://github.com/BerriAI/litellm/issues",target:"_blank",rel:"noopener noreferrer",children:"here"}),"."]})})]})};var d=e.i(135214);e.s(["default",0,function(){let{accessToken:e}=(0,d.default)();return(0,t.jsx)(n,{accessToken:e})}],411929)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0putlgbpr_zks.js b/litellm/proxy/_experimental/out/_next/static/chunks/0putlgbpr_zks.js new file mode 100644 index 00000000000..35294f85fe7 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/0putlgbpr_zks.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,841947,e=>{"use strict";let t=(0,e.i(475254).default)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);e.s(["default",0,t])},603908,e=>{"use strict";let t=(0,e.i(475254).default)("plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]);e.s(["default",0,t])},361653,e=>{"use strict";let t=(0,e.i(475254).default)("circle-alert",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]]);e.s(["default",0,t])},409797,e=>{"use strict";var t=e.i(631171);e.s(["ChevronDownIcon",()=>t.default])},184163,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M505.7 661a8 8 0 0012.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"}}]},name:"download",theme:"outlined"};var o=e.i(9583),i=r.forwardRef(function(e,i){return r.createElement(o.default,(0,t.default)({},e,{ref:i,icon:n}))});e.s(["default",0,i],184163)},309821,e=>{"use strict";e.i(247167);var t=e.i(271645),r=e.i(135551),n=e.i(201072),o=e.i(121229),i=e.i(726289),a=e.i(864517),l=e.i(343794),s=e.i(529681),c=e.i(242064),u=e.i(931067),d=e.i(209428),p=e.i(703923),f={percent:0,prefixCls:"rc-progress",strokeColor:"#2db7f5",strokeLinecap:"round",strokeWidth:1,trailColor:"#D9D9D9",trailWidth:1,gapPosition:"bottom"},g=function(){var e=(0,t.useRef)([]),r=(0,t.useRef)(null);return(0,t.useEffect)(function(){var t=Date.now(),n=!1;e.current.forEach(function(e){if(e){n=!0;var o=e.style;o.transitionDuration=".3s, .3s, .3s, .06s",r.current&&t-r.current<100&&(o.transitionDuration="0s, 0s")}}),n&&(r.current=Date.now())}),e.current},m=e.i(410160),h=e.i(392221),b=e.i(654310),y=0,v=(0,b.default)();let x=function(e){var r=t.useState(),n=(0,h.default)(r,2),o=n[0],i=n[1];return t.useEffect(function(){var e;i("rc_progress_".concat((v?(e=y,y+=1):e="TEST_OR_SSR",e)))},[]),e||o};var k=function(e){var r=e.bg,n=e.children;return t.createElement("div",{style:{width:"100%",height:"100%",background:r}},n)};function $(e,t){return Object.keys(e).map(function(r){var n=parseFloat(r),o="".concat(Math.floor(n*t),"%");return"".concat(e[r]," ").concat(o)})}var C=t.forwardRef(function(e,r){var n=e.prefixCls,o=e.color,i=e.gradientId,a=e.radius,l=e.style,s=e.ptg,c=e.strokeLinecap,u=e.strokeWidth,d=e.size,p=e.gapDegree,f=o&&"object"===(0,m.default)(o),g=d/2,h=t.createElement("circle",{className:"".concat(n,"-circle-path"),r:a,cx:g,cy:g,stroke:f?"#FFF":void 0,strokeLinecap:c,strokeWidth:u,opacity:+(0!==s),style:l,ref:r});if(!f)return h;var b="".concat(i,"-conic"),y=$(o,(360-p)/360),v=$(o,1),x="conic-gradient(from ".concat(p?"".concat(180+p/2,"deg"):"0deg",", ").concat(y.join(", "),")"),C="linear-gradient(to ".concat(p?"bottom":"top",", ").concat(v.join(", "),")");return t.createElement(t.Fragment,null,t.createElement("mask",{id:b},h),t.createElement("foreignObject",{x:0,y:0,width:d,height:d,mask:"url(#".concat(b,")")},t.createElement(k,{bg:C},t.createElement(k,{bg:x}))))}),w=function(e,t,r,n,o,i,a,l,s,c){var u=arguments.length>10&&void 0!==arguments[10]?arguments[10]:0,d=(100-n)/100*t;return"round"===s&&100!==n&&(d+=c/2)>=t&&(d=t-.01),{stroke:"string"==typeof l?l:void 0,strokeDasharray:"".concat(t,"px ").concat(e),strokeDashoffset:d+u,transform:"rotate(".concat(o+r/100*360*((360-i)/360)+(0===i?0:({bottom:0,top:180,left:90,right:-90})[a]),"deg)"),transformOrigin:"".concat(50,"px ").concat(50,"px"),transition:"stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s",fillOpacity:0}},S=["id","prefixCls","steps","strokeWidth","trailWidth","gapDegree","gapPosition","trailColor","strokeLinecap","style","className","strokeColor","percent"];function E(e){var t=null!=e?e:[];return Array.isArray(t)?t:[t]}let O=function(e){var r,n,o,i,a=(0,d.default)((0,d.default)({},f),e),s=a.id,c=a.prefixCls,h=a.steps,b=a.strokeWidth,y=a.trailWidth,v=a.gapDegree,k=void 0===v?0:v,$=a.gapPosition,O=a.trailColor,j=a.strokeLinecap,_=a.style,N=a.className,I=a.strokeColor,D=a.percent,M=(0,p.default)(a,S),P=x(s),A="".concat(P,"-gradient"),T=50-b/2,W=2*Math.PI*T,R=k>0?90+k/2:-90,z=(360-k)/360*W,F="object"===(0,m.default)(h)?h:{count:h,gap:2},L=F.count,B=F.gap,X=E(D),H=E(I),V=H.find(function(e){return e&&"object"===(0,m.default)(e)}),U=V&&"object"===(0,m.default)(V)?"butt":j,K=w(W,z,0,100,R,k,$,O,U,b),q=g();return t.createElement("svg",(0,u.default)({className:(0,l.default)("".concat(c,"-circle"),N),viewBox:"0 0 ".concat(100," ").concat(100),style:_,id:s,role:"presentation"},M),!L&&t.createElement("circle",{className:"".concat(c,"-circle-trail"),r:T,cx:50,cy:50,stroke:O,strokeLinecap:U,strokeWidth:y||b,style:K}),L?(r=Math.round(L*(X[0]/100)),n=100/L,o=0,Array(L).fill(null).map(function(e,i){var a=i<=r-1?H[0]:O,l=a&&"object"===(0,m.default)(a)?"url(#".concat(A,")"):void 0,s=w(W,z,o,n,R,k,$,a,"butt",b,B);return o+=(z-s.strokeDashoffset+B)*100/z,t.createElement("circle",{key:i,className:"".concat(c,"-circle-path"),r:T,cx:50,cy:50,stroke:l,strokeWidth:b,opacity:1,style:s,ref:function(e){q[i]=e}})})):(i=0,X.map(function(e,r){var n=H[r]||H[H.length-1],o=w(W,z,i,e,R,k,$,n,U,b);return i+=e,t.createElement(C,{key:r,color:n,ptg:e,radius:T,prefixCls:c,gradientId:A,style:o,strokeLinecap:U,strokeWidth:b,gapDegree:k,ref:function(e){q[r]=e},size:100})}).reverse()))};var j=e.i(491816);e.i(765846);var _=e.i(896091);function N(e){return!e||e<0?0:e>100?100:e}function I({success:e,successPercent:t}){let r=t;return e&&"progress"in e&&(r=e.progress),e&&"percent"in e&&(r=e.percent),r}let D=(e,t,r)=>{var n,o,i,a;let l=-1,s=-1;if("step"===t){let t=r.steps,n=r.strokeWidth;"string"==typeof e||void 0===e?(l="small"===e?2:14,s=null!=n?n:8):"number"==typeof e?[l,s]=[e,e]:[l=14,s=8]=Array.isArray(e)?e:[e.width,e.height],l*=t}else if("line"===t){let t=null==r?void 0:r.strokeWidth;"string"==typeof e||void 0===e?s=t||("small"===e?6:8):"number"==typeof e?[l,s]=[e,e]:[l=-1,s=8]=Array.isArray(e)?e:[e.width,e.height]}else("circle"===t||"dashboard"===t)&&("string"==typeof e||void 0===e?[l,s]="small"===e?[60,60]:[120,120]:"number"==typeof e?[l,s]=[e,e]:Array.isArray(e)&&(l=null!=(o=null!=(n=e[0])?n:e[1])?o:120,s=null!=(a=null!=(i=e[0])?i:e[1])?a:120));return[l,s]},M=e=>{let{prefixCls:r,trailColor:n=null,strokeLinecap:o="round",gapPosition:i,gapDegree:a,width:s=120,type:c,children:u,success:d,size:p=s,steps:f}=e,[g,m]=D(p,"circle"),{strokeWidth:h}=e;void 0===h&&(h=Math.max(3/g*100,6));let b=t.useMemo(()=>a||0===a?a:"dashboard"===c?75:void 0,[a,c]),y=(({percent:e,success:t,successPercent:r})=>{let n=N(I({success:t,successPercent:r}));return[n,N(N(e)-n)]})(e),v="[object Object]"===Object.prototype.toString.call(e.strokeColor),x=(({success:e={},strokeColor:t})=>{let{strokeColor:r}=e;return[r||_.presetPrimaryColors.green,t||null]})({success:d,strokeColor:e.strokeColor}),k=(0,l.default)(`${r}-inner`,{[`${r}-circle-gradient`]:v}),$=t.createElement(O,{steps:f,percent:f?y[1]:y,strokeWidth:h,trailWidth:h,strokeColor:f?x[1]:x,strokeLinecap:o,trailColor:n,prefixCls:r,gapDegree:b,gapPosition:i||"dashboard"===c&&"bottom"||void 0}),C=g<=20,w=t.createElement("div",{className:k,style:{width:g,height:m,fontSize:.15*g+6}},$,!C&&u);return C?t.createElement(j.default,{title:u},w):w};e.i(296059);var P=e.i(694758),A=e.i(915654),T=e.i(183293),W=e.i(246422),R=e.i(838378);let z="--progress-line-stroke-color",F="--progress-percent",L=e=>{let t=e?"100%":"-100%";return new P.Keyframes(`antProgress${e?"RTL":"LTR"}Active`,{"0%":{transform:`translateX(${t}) scaleX(0)`,opacity:.1},"20%":{transform:`translateX(${t}) scaleX(0)`,opacity:.5},to:{transform:"translateX(0) scaleX(1)",opacity:0}})},B=(0,W.genStyleHooks)("Progress",e=>{let t=e.calc(e.marginXXS).div(2).equal(),r=(0,R.mergeToken)(e,{progressStepMarginInlineEnd:t,progressStepMinWidth:t,progressActiveMotionDuration:"2.4s"});return[(e=>{let{componentCls:t,iconCls:r}=e;return{[t]:Object.assign(Object.assign({},(0,T.resetComponent)(e)),{display:"inline-block","&-rtl":{direction:"rtl"},"&-line":{position:"relative",width:"100%",fontSize:e.fontSize},[`${t}-outer`]:{display:"inline-flex",alignItems:"center",width:"100%"},[`${t}-inner`]:{position:"relative",display:"inline-block",width:"100%",flex:1,overflow:"hidden",verticalAlign:"middle",backgroundColor:e.remainingColor,borderRadius:e.lineBorderRadius},[`${t}-inner:not(${t}-circle-gradient)`]:{[`${t}-circle-path`]:{stroke:e.defaultColor}},[`${t}-success-bg, ${t}-bg`]:{position:"relative",background:e.defaultColor,borderRadius:e.lineBorderRadius,transition:`all ${e.motionDurationSlow} ${e.motionEaseInOutCirc}`},[`${t}-layout-bottom`]:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",[`${t}-text`]:{width:"max-content",marginInlineStart:0,marginTop:e.marginXXS}},[`${t}-bg`]:{overflow:"hidden","&::after":{content:'""',background:{_multi_value_:!0,value:["inherit",`var(${z})`]},height:"100%",width:`calc(1 / var(${F}) * 100%)`,display:"block"},[`&${t}-bg-inner`]:{minWidth:"max-content","&::after":{content:"none"},[`${t}-text-inner`]:{color:e.colorWhite,[`&${t}-text-bright`]:{color:"rgba(0, 0, 0, 0.45)"}}}},[`${t}-success-bg`]:{position:"absolute",insetBlockStart:0,insetInlineStart:0,backgroundColor:e.colorSuccess},[`${t}-text`]:{display:"inline-block",marginInlineStart:e.marginXS,color:e.colorText,lineHeight:1,width:"2em",whiteSpace:"nowrap",textAlign:"start",verticalAlign:"middle",wordBreak:"normal",[r]:{fontSize:e.fontSize},[`&${t}-text-outer`]:{width:"max-content"},[`&${t}-text-outer${t}-text-start`]:{width:"max-content",marginInlineStart:0,marginInlineEnd:e.marginXS}},[`${t}-text-inner`]:{display:"flex",justifyContent:"center",alignItems:"center",width:"100%",height:"100%",marginInlineStart:0,padding:`0 ${(0,A.unit)(e.paddingXXS)}`,[`&${t}-text-start`]:{justifyContent:"start"},[`&${t}-text-end`]:{justifyContent:"end"}},[`&${t}-status-active`]:{[`${t}-bg::before`]:{position:"absolute",inset:0,backgroundColor:e.colorBgContainer,borderRadius:e.lineBorderRadius,opacity:0,animationName:L(),animationDuration:e.progressActiveMotionDuration,animationTimingFunction:e.motionEaseOutQuint,animationIterationCount:"infinite",content:'""'}},[`&${t}-rtl${t}-status-active`]:{[`${t}-bg::before`]:{animationName:L(!0)}},[`&${t}-status-exception`]:{[`${t}-bg`]:{backgroundColor:e.colorError},[`${t}-text`]:{color:e.colorError}},[`&${t}-status-exception ${t}-inner:not(${t}-circle-gradient)`]:{[`${t}-circle-path`]:{stroke:e.colorError}},[`&${t}-status-success`]:{[`${t}-bg`]:{backgroundColor:e.colorSuccess},[`${t}-text`]:{color:e.colorSuccess}},[`&${t}-status-success ${t}-inner:not(${t}-circle-gradient)`]:{[`${t}-circle-path`]:{stroke:e.colorSuccess}}})}})(r),(e=>{let{componentCls:t,iconCls:r}=e;return{[t]:{[`${t}-circle-trail`]:{stroke:e.remainingColor},[`&${t}-circle ${t}-inner`]:{position:"relative",lineHeight:1,backgroundColor:"transparent"},[`&${t}-circle ${t}-text`]:{position:"absolute",insetBlockStart:"50%",insetInlineStart:0,width:"100%",margin:0,padding:0,color:e.circleTextColor,fontSize:e.circleTextFontSize,lineHeight:1,whiteSpace:"normal",textAlign:"center",transform:"translateY(-50%)",[r]:{fontSize:e.circleIconFontSize}},[`${t}-circle&-status-exception`]:{[`${t}-text`]:{color:e.colorError}},[`${t}-circle&-status-success`]:{[`${t}-text`]:{color:e.colorSuccess}}},[`${t}-inline-circle`]:{lineHeight:1,[`${t}-inner`]:{verticalAlign:"bottom"}}}})(r),(e=>{let{componentCls:t}=e;return{[t]:{[`${t}-steps`]:{display:"inline-block","&-outer":{display:"flex",flexDirection:"row",alignItems:"center"},"&-item":{flexShrink:0,minWidth:e.progressStepMinWidth,marginInlineEnd:e.progressStepMarginInlineEnd,backgroundColor:e.remainingColor,transition:`all ${e.motionDurationSlow}`,"&-active":{backgroundColor:e.defaultColor}}}}}})(r),(e=>{let{componentCls:t,iconCls:r}=e;return{[t]:{[`${t}-small&-line, ${t}-small&-line ${t}-text ${r}`]:{fontSize:e.fontSizeSM}}}})(r)]},e=>({circleTextColor:e.colorText,defaultColor:e.colorInfo,remainingColor:e.colorFillSecondary,lineBorderRadius:100,circleTextFontSize:"1em",circleIconFontSize:`${e.fontSize/e.fontSizeSM}em`}));var X=function(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&0>t.indexOf(n)&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,n=Object.getOwnPropertySymbols(e);ot.indexOf(n[o])&&Object.prototype.propertyIsEnumerable.call(e,n[o])&&(r[n[o]]=e[n[o]]);return r};let H=e=>{let{prefixCls:r,direction:n,percent:o,size:i,strokeWidth:a,strokeColor:s,strokeLinecap:c="round",children:u,trailColor:d=null,percentPosition:p,success:f}=e,{align:g,type:m}=p,h=s&&"string"!=typeof s?((e,t)=>{let{from:r=_.presetPrimaryColors.blue,to:n=_.presetPrimaryColors.blue,direction:o="rtl"===t?"to left":"to right"}=e,i=X(e,["from","to","direction"]);if(0!==Object.keys(i).length){let e,t=(e=[],Object.keys(i).forEach(t=>{let r=Number.parseFloat(t.replace(/%/g,""));Number.isNaN(r)||e.push({key:r,value:i[t]})}),(e=e.sort((e,t)=>e.key-t.key)).map(({key:e,value:t})=>`${t} ${e}%`).join(", ")),r=`linear-gradient(${o}, ${t})`;return{background:r,[z]:r}}let a=`linear-gradient(${o}, ${r}, ${n})`;return{background:a,[z]:a}})(s,n):{[z]:s,background:s},b="square"===c||"butt"===c?0:void 0,[y,v]=D(null!=i?i:[-1,a||("small"===i?6:8)],"line",{strokeWidth:a}),x=Object.assign(Object.assign({width:`${N(o)}%`,height:v,borderRadius:b},h),{[F]:N(o)/100}),k=I(e),$={width:`${N(k)}%`,height:v,borderRadius:b,backgroundColor:null==f?void 0:f.strokeColor},C=t.createElement("div",{className:`${r}-inner`,style:{backgroundColor:d||void 0,borderRadius:b}},t.createElement("div",{className:(0,l.default)(`${r}-bg`,`${r}-bg-${m}`),style:x},"inner"===m&&u),void 0!==k&&t.createElement("div",{className:`${r}-success-bg`,style:$})),w="outer"===m&&"start"===g,S="outer"===m&&"end"===g;return"outer"===m&&"center"===g?t.createElement("div",{className:`${r}-layout-bottom`},C,u):t.createElement("div",{className:`${r}-outer`,style:{width:y<0?"100%":y}},w&&u,C,S&&u)},V=e=>{let{size:r,steps:n,rounding:o=Math.round,percent:i=0,strokeWidth:a=8,strokeColor:s,trailColor:c=null,prefixCls:u,children:d}=e,p=o(i/100*n),[f,g]=D(null!=r?r:["small"===r?2:14,a],"step",{steps:n,strokeWidth:a}),m=f/n,h=Array.from({length:n});for(let e=0;et.indexOf(n)&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,n=Object.getOwnPropertySymbols(e);ot.indexOf(n[o])&&Object.prototype.propertyIsEnumerable.call(e,n[o])&&(r[n[o]]=e[n[o]]);return r};let K=["normal","exception","active","success"],q=t.forwardRef((e,u)=>{let d,{prefixCls:p,className:f,rootClassName:g,steps:m,strokeColor:h,percent:b=0,size:y="default",showInfo:v=!0,type:x="line",status:k,format:$,style:C,percentPosition:w={}}=e,S=U(e,["prefixCls","className","rootClassName","steps","strokeColor","percent","size","showInfo","type","status","format","style","percentPosition"]),{align:E="end",type:O="outer"}=w,j=Array.isArray(h)?h[0]:h,_="string"==typeof h||Array.isArray(h)?h:void 0,P=t.useMemo(()=>{if(j){let e="string"==typeof j?j:Object.values(j)[0];return new r.FastColor(e).isLight()}return!1},[h]),A=t.useMemo(()=>{var t,r;let n=I(e);return Number.parseInt(void 0!==n?null==(t=null!=n?n:0)?void 0:t.toString():null==(r=null!=b?b:0)?void 0:r.toString(),10)},[b,e.success,e.successPercent]),T=t.useMemo(()=>!K.includes(k)&&A>=100?"success":k||"normal",[k,A]),{getPrefixCls:W,direction:R,progress:z}=t.useContext(c.ConfigContext),F=W("progress",p),[L,X,q]=B(F),Q="line"===x,Y=Q&&!m,G=t.useMemo(()=>{let r;if(!v)return null;let s=I(e),c=$||(e=>`${e}%`),u=Q&&P&&"inner"===O;return"inner"===O||$||"exception"!==T&&"success"!==T?r=c(N(b),N(s)):"exception"===T?r=Q?t.createElement(i.default,null):t.createElement(a.default,null):"success"===T&&(r=Q?t.createElement(n.default,null):t.createElement(o.default,null)),t.createElement("span",{className:(0,l.default)(`${F}-text`,{[`${F}-text-bright`]:u,[`${F}-text-${E}`]:Y,[`${F}-text-${O}`]:Y}),title:"string"==typeof r?r:void 0},r)},[v,b,A,T,x,F,$]);"line"===x?d=m?t.createElement(V,Object.assign({},e,{strokeColor:_,prefixCls:F,steps:"object"==typeof m?m.count:m}),G):t.createElement(H,Object.assign({},e,{strokeColor:j,prefixCls:F,direction:R,percentPosition:{align:E,type:O}}),G):("circle"===x||"dashboard"===x)&&(d=t.createElement(M,Object.assign({},e,{strokeColor:j,prefixCls:F,progressStatus:T}),G));let J=(0,l.default)(F,`${F}-status-${T}`,{[`${F}-${"dashboard"===x&&"circle"||x}`]:"line"!==x,[`${F}-inline-circle`]:"circle"===x&&D(y,"circle")[0]<=20,[`${F}-line`]:Y,[`${F}-line-align-${E}`]:Y,[`${F}-line-position-${O}`]:Y,[`${F}-steps`]:m,[`${F}-show-info`]:v,[`${F}-${y}`]:"string"==typeof y,[`${F}-rtl`]:"rtl"===R},null==z?void 0:z.className,f,g,X,q);return L(t.createElement("div",Object.assign({ref:u,style:Object.assign(Object.assign({},null==z?void 0:z.style),C),className:J,role:"progressbar","aria-valuenow":A,"aria-valuemin":0,"aria-valuemax":100},(0,s.default)(S,["trailColor","strokeWidth","width","gapDegree","gapPosition","strokeLinecap","success","successPercent"])),d))});e.s(["default",0,q],309821)},519756,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M400 317.7h73.9V656c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V317.7H624c6.7 0 10.4-7.7 6.3-12.9L518.3 163a8 8 0 00-12.6 0l-112 141.7c-4.1 5.3-.4 13 6.3 13zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"}}]},name:"upload",theme:"outlined"};var o=e.i(9583),i=r.forwardRef(function(e,i){return r.createElement(o.default,(0,t.default)({},e,{ref:i,icon:n}))});e.s(["UploadOutlined",0,i],519756)},663435,152473,e=>{"use strict";var t=e.i(843476),r=e.i(271645),n=e.i(199133),o=e.i(898586),i=e.i(56456);let a={enabled:!0,leading:!1,trailing:!0,wait:0,onExecute:()=>{}};class l{constructor(e,t){this.fn=e,this._canLeadingExecute=!0,this._isPending=!1,this._executionCount=0,this._options={...a,...t}}setOptions(e){return this._options={...this._options,...e},this._options.enabled||(this._isPending=!1),this._options}getOptions(){return this._options}maybeExecute(...e){this._options.leading&&this._canLeadingExecute&&(this.executeFunction(...e),this._canLeadingExecute=!1),(this._options.leading||this._options.trailing)&&(this._isPending=!0),this._timeoutId&&clearTimeout(this._timeoutId),this._timeoutId=setTimeout(()=>{this._canLeadingExecute=!0,this._isPending=!1,this._options.trailing&&this.executeFunction(...e)},this._options.wait)}executeFunction(...e){this._options.enabled&&(this.fn(...e),this._executionCount++,this._options.onExecute(this))}cancel(){this._timeoutId&&(clearTimeout(this._timeoutId),this._canLeadingExecute=!0,this._isPending=!1)}getExecutionCount(){return this._executionCount}getIsPending(){return this._options.enabled&&this._isPending}}function s(e,t){let[n,o]=(0,r.useState)(e),i=function(e,t){let[n]=(0,r.useState)(()=>{var r;return Object.getOwnPropertyNames(Object.getPrototypeOf(r=new l(e,t))).filter(e=>"function"==typeof r[e]).reduce((e,t)=>{let n=r[t];return"function"==typeof n&&(e[t]=n.bind(r)),e},{})});return n.setOptions(t),n}(o,t);return[n,i.maybeExecute,i]}e.s(["useDebouncedState",0,s],152473);var c=e.i(785242);let{Text:u}=o.Typography;e.s(["default",0,({value:e,onChange:o,onTeamSelect:a,disabled:l,organizationId:d,pageSize:p=20})=>{let[f,g]=(0,r.useState)(""),[m,h]=s("",{wait:300}),{data:b,fetchNextPage:y,hasNextPage:v,isFetchingNextPage:x,isLoading:k}=(0,c.useInfiniteTeams)(p,m||void 0,d),$=(0,r.useMemo)(()=>{if(!b?.pages)return[];let e=new Set,t=[];for(let r of b.pages)for(let n of r.teams)e.has(n.team_id)||(e.add(n.team_id),t.push(n));return t},[b]);return(0,t.jsx)(n.Select,{showSearch:!0,placeholder:"Search or select a team",value:e||void 0,onChange:e=>{o?.(e??""),a&&a(e?$.find(t=>t.team_id===e)??null:null)},disabled:l,allowClear:!0,filterOption:!1,onSearch:e=>{g(e),h(e)},searchValue:f,onPopupScroll:e=>{let t=e.currentTarget;(t.scrollTop+t.clientHeight)/t.scrollHeight>=.8&&v&&!x&&y()},loading:k,notFoundContent:k?(0,t.jsx)(i.LoadingOutlined,{spin:!0}):"No teams found","data-testid":"team-dropdown",popupRender:e=>(0,t.jsxs)(t.Fragment,{children:[e,x&&(0,t.jsx)("div",{style:{textAlign:"center",padding:8},children:(0,t.jsx)(i.LoadingOutlined,{spin:!0})})]}),children:$.map(e=>(0,t.jsxs)(n.Select.Option,{value:e.team_id,children:[(0,t.jsx)("span",{className:"font-medium",children:e.team_alias})," ",(0,t.jsxs)(u,{type:"secondary",children:["(",e.team_id,")"]})]},e.team_id))})}],663435)},435451,e=>{"use strict";var t=e.i(843476),r=e.i(290571),n=e.i(271645);let o=e=>{var t=(0,r.__rest)(e,[]);return n.default.createElement("svg",Object.assign({},t,{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:"2.5"}),n.default.createElement("path",{d:"M12 4v16m8-8H4"}))},i=e=>{var t=(0,r.__rest)(e,[]);return n.default.createElement("svg",Object.assign({},t,{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:"2.5"}),n.default.createElement("path",{d:"M20 12H4"}))};var a=e.i(444755),l=e.i(673706),s=e.i(677955);let c="flex mx-auto text-tremor-content-subtle dark:text-dark-tremor-content-subtle",u="cursor-pointer hover:text-tremor-content dark:hover:text-dark-tremor-content",d=n.default.forwardRef((e,t)=>{let{onSubmit:d,enableStepper:p=!0,disabled:f,onValueChange:g,onChange:m}=e,h=(0,r.__rest)(e,["onSubmit","enableStepper","disabled","onValueChange","onChange"]),b=(0,n.useRef)(null),[y,v]=n.default.useState(!1),x=n.default.useCallback(()=>{v(!0)},[]),k=n.default.useCallback(()=>{v(!1)},[]),[$,C]=n.default.useState(!1),w=n.default.useCallback(()=>{C(!0)},[]),S=n.default.useCallback(()=>{C(!1)},[]);return n.default.createElement(s.default,Object.assign({type:"number",ref:(0,l.mergeRefs)([b,t]),disabled:f,makeInputClassName:(0,l.makeClassName)("NumberInput"),onKeyDown:e=>{var t;if("Enter"===e.key&&!e.ctrlKey&&!e.altKey&&!e.shiftKey){let e=null==(t=b.current)?void 0:t.value;null==d||d(parseFloat(null!=e?e:""))}"ArrowDown"===e.key&&x(),"ArrowUp"===e.key&&w()},onKeyUp:e=>{"ArrowDown"===e.key&&k(),"ArrowUp"===e.key&&S()},onChange:e=>{f||(null==g||g(parseFloat(e.target.value)),null==m||m(e))},stepper:p?n.default.createElement("div",{className:(0,a.tremorTwMerge)("flex justify-center align-middle")},n.default.createElement("div",{tabIndex:-1,onClick:e=>e.preventDefault(),onMouseDown:e=>e.preventDefault(),onTouchStart:e=>{e.cancelable&&e.preventDefault()},onMouseUp:()=>{var e,t;f||(null==(e=b.current)||e.stepDown(),null==(t=b.current)||t.dispatchEvent(new Event("input",{bubbles:!0})))},className:(0,a.tremorTwMerge)(!f&&u,c,"group py-[10px] px-2.5 border-l border-tremor-border dark:border-dark-tremor-border")},n.default.createElement(i,{"data-testid":"step-down",className:(y?"scale-95":"")+" h-4 w-4 duration-75 transition group-active:scale-95"})),n.default.createElement("div",{tabIndex:-1,onClick:e=>e.preventDefault(),onMouseDown:e=>e.preventDefault(),onTouchStart:e=>{e.cancelable&&e.preventDefault()},onMouseUp:()=>{var e,t;f||(null==(e=b.current)||e.stepUp(),null==(t=b.current)||t.dispatchEvent(new Event("input",{bubbles:!0})))},className:(0,a.tremorTwMerge)(!f&&u,c,"group py-[10px] px-2.5 border-l border-tremor-border dark:border-dark-tremor-border")},n.default.createElement(o,{"data-testid":"step-up",className:($?"scale-95":"")+" h-4 w-4 duration-75 transition group-active:scale-95"}))):null},h))});d.displayName="NumberInput",e.s(["default",0,({step:e=.01,style:r={width:"100%"},placeholder:n="Enter a numerical value",min:o,max:i,onChange:a,...l})=>(0,t.jsx)(d,{onWheel:e=>e.currentTarget.blur(),step:e,style:r,placeholder:n,min:o,max:i,onChange:a,...l})],435451)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0q2og72gex34u.js b/litellm/proxy/_experimental/out/_next/static/chunks/0q2og72gex34u.js new file mode 100644 index 00000000000..d905a85b484 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/0q2og72gex34u.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,21548,e=>{"use strict";var t=e.i(616303);e.s(["Empty",()=>t.default])},608856,e=>{"use strict";e.i(247167);var t=e.i(271645),a=e.i(343794),n=e.i(209428),r=e.i(392221),l=e.i(951160),o=e.i(174428),i=t.createContext(null),s=t.createContext({}),d=e.i(211577),c=e.i(931067),u=e.i(361275),m=e.i(404948),p=e.i(244009),f=e.i(703923),y=e.i(611935),h=["prefixCls","className","containerRef"];let g=function(e){var n=e.prefixCls,r=e.className,l=e.containerRef,o=(0,f.default)(e,h),i=t.useContext(s).panel,d=(0,y.useComposeRef)(i,l);return t.createElement("div",(0,c.default)({className:(0,a.default)("".concat(n,"-content"),r),role:"dialog",ref:d},(0,p.default)(e,{aria:!0}),{"aria-modal":"true"},o))};var v=e.i(883110);function x(e){return"string"==typeof e&&String(Number(e))===e?((0,v.default)(!1,"Invalid value type of `width` or `height` which should be number type instead."),Number(e)):e}var b={width:0,height:0,overflow:"hidden",outline:"none",position:"absolute"},w=t.forwardRef(function(e,l){var o,s,f,y=e.prefixCls,h=e.open,v=e.placement,w=e.inline,k=e.push,j=e.forceRender,C=e.autoFocus,S=e.keyboard,O=e.classNames,$=e.rootClassName,E=e.rootStyle,N=e.zIndex,I=e.className,D=e.id,M=e.style,R=e.motion,_=e.width,z=e.height,F=e.children,T=e.mask,P=e.maskClosable,A=e.maskMotion,B=e.maskClassName,K=e.maskStyle,L=e.afterOpenChange,q=e.onClose,U=e.onMouseEnter,W=e.onMouseOver,H=e.onMouseLeave,V=e.onClick,J=e.onKeyDown,X=e.onKeyUp,Y=e.styles,Q=e.drawerRender,G=t.useRef(),Z=t.useRef(),ee=t.useRef();t.useImperativeHandle(l,function(){return G.current}),t.useEffect(function(){if(h&&C){var e;null==(e=G.current)||e.focus({preventScroll:!0})}},[h]);var et=t.useState(!1),ea=(0,r.default)(et,2),en=ea[0],er=ea[1],el=t.useContext(i),eo=null!=(o=null!=(s=null==(f="boolean"==typeof k?k?{}:{distance:0}:k||{})?void 0:f.distance)?s:null==el?void 0:el.pushDistance)?o:180,ei=t.useMemo(function(){return{pushDistance:eo,push:function(){er(!0)},pull:function(){er(!1)}}},[eo]);t.useEffect(function(){var e,t;h?null==el||null==(e=el.push)||e.call(el):null==el||null==(t=el.pull)||t.call(el)},[h]),t.useEffect(function(){return function(){var e;null==el||null==(e=el.pull)||e.call(el)}},[]);var es=t.createElement(u.default,(0,c.default)({key:"mask"},A,{visible:T&&h}),function(e,r){var l=e.className,o=e.style;return t.createElement("div",{className:(0,a.default)("".concat(y,"-mask"),l,null==O?void 0:O.mask,B),style:(0,n.default)((0,n.default)((0,n.default)({},o),K),null==Y?void 0:Y.mask),onClick:P&&h?q:void 0,ref:r})}),ed="function"==typeof R?R(v):R,ec={};if(en&&eo)switch(v){case"top":ec.transform="translateY(".concat(eo,"px)");break;case"bottom":ec.transform="translateY(".concat(-eo,"px)");break;case"left":ec.transform="translateX(".concat(eo,"px)");break;default:ec.transform="translateX(".concat(-eo,"px)")}"left"===v||"right"===v?ec.width=x(_):ec.height=x(z);var eu={onMouseEnter:U,onMouseOver:W,onMouseLeave:H,onClick:V,onKeyDown:J,onKeyUp:X},em=t.createElement(u.default,(0,c.default)({key:"panel"},ed,{visible:h,forceRender:j,onVisibleChanged:function(e){null==L||L(e)},removeOnLeave:!1,leavedClassName:"".concat(y,"-content-wrapper-hidden")}),function(r,l){var o=r.className,i=r.style,s=t.createElement(g,(0,c.default)({id:D,containerRef:l,prefixCls:y,className:(0,a.default)(I,null==O?void 0:O.content),style:(0,n.default)((0,n.default)({},M),null==Y?void 0:Y.content)},(0,p.default)(e,{aria:!0}),eu),F);return t.createElement("div",(0,c.default)({className:(0,a.default)("".concat(y,"-content-wrapper"),null==O?void 0:O.wrapper,o),style:(0,n.default)((0,n.default)((0,n.default)({},ec),i),null==Y?void 0:Y.wrapper)},(0,p.default)(e,{data:!0})),Q?Q(s):s)}),ep=(0,n.default)({},E);return N&&(ep.zIndex=N),t.createElement(i.Provider,{value:ei},t.createElement("div",{className:(0,a.default)(y,"".concat(y,"-").concat(v),$,(0,d.default)((0,d.default)({},"".concat(y,"-open"),h),"".concat(y,"-inline"),w)),style:ep,tabIndex:-1,ref:G,onKeyDown:function(e){var t,a,n=e.keyCode,r=e.shiftKey;switch(n){case m.default.TAB:n===m.default.TAB&&(r||document.activeElement!==ee.current?r&&document.activeElement===Z.current&&(null==(a=ee.current)||a.focus({preventScroll:!0})):null==(t=Z.current)||t.focus({preventScroll:!0}));break;case m.default.ESC:q&&S&&(e.stopPropagation(),q(e))}}},es,t.createElement("div",{tabIndex:0,ref:Z,style:b,"aria-hidden":"true","data-sentinel":"start"}),em,t.createElement("div",{tabIndex:0,ref:ee,style:b,"aria-hidden":"true","data-sentinel":"end"})))});let k=function(e){var a=e.open,i=e.prefixCls,d=e.placement,c=e.autoFocus,u=e.keyboard,m=e.width,p=e.mask,f=void 0===p||p,y=e.maskClosable,h=e.getContainer,g=e.forceRender,v=e.afterOpenChange,x=e.destroyOnClose,b=e.onMouseEnter,k=e.onMouseOver,j=e.onMouseLeave,C=e.onClick,S=e.onKeyDown,O=e.onKeyUp,$=e.panelRef,E=t.useState(!1),N=(0,r.default)(E,2),I=N[0],D=N[1],M=t.useState(!1),R=(0,r.default)(M,2),_=R[0],z=R[1];(0,o.default)(function(){z(!0)},[]);var F=!!_&&void 0!==a&&a,T=t.useRef(),P=t.useRef();(0,o.default)(function(){F&&(P.current=document.activeElement)},[F]);var A=t.useMemo(function(){return{panel:$}},[$]);if(!g&&!I&&!F&&x)return null;var B=(0,n.default)((0,n.default)({},e),{},{open:F,prefixCls:void 0===i?"rc-drawer":i,placement:void 0===d?"right":d,autoFocus:void 0===c||c,keyboard:void 0===u||u,width:void 0===m?378:m,mask:f,maskClosable:void 0===y||y,inline:!1===h,afterOpenChange:function(e){var t,a;D(e),null==v||v(e),e||!P.current||null!=(t=T.current)&&t.contains(P.current)||null==(a=P.current)||a.focus({preventScroll:!0})},ref:T},{onMouseEnter:b,onMouseOver:k,onMouseLeave:j,onClick:C,onKeyDown:S,onKeyUp:O});return t.createElement(s.Provider,{value:A},t.createElement(l.default,{open:F||g||I,autoDestroy:!1,getContainer:h,autoLock:f&&(F||I)},t.createElement(w,B)))};var j=e.i(981444),C=e.i(617206),S=e.i(122767),O=e.i(613541),$=e.i(340010),E=e.i(242064),N=e.i(922611),I=e.i(563113),D=e.i(185793);let M=e=>{var n,r,l,o;let i,{prefixCls:s,ariaId:d,title:c,footer:u,extra:m,closable:p,loading:f,onClose:y,headerStyle:h,bodyStyle:g,footerStyle:v,children:x,classNames:b,styles:w}=e,k=(0,E.useComponentConfig)("drawer");i=!1===p?void 0:void 0===p||!0===p?"start":(null==p?void 0:p.placement)==="end"?"end":"start";let j=t.useCallback(e=>t.createElement("button",{type:"button",onClick:y,className:(0,a.default)(`${s}-close`,{[`${s}-close-${i}`]:"end"===i})},e),[y,s,i]),[C,S]=(0,I.useClosable)((0,I.pickClosable)(e),(0,I.pickClosable)(k),{closable:!0,closeIconRender:j});return t.createElement(t.Fragment,null,c||C?t.createElement("div",{style:Object.assign(Object.assign(Object.assign({},null==(l=k.styles)?void 0:l.header),h),null==w?void 0:w.header),className:(0,a.default)(`${s}-header`,{[`${s}-header-close-only`]:C&&!c&&!m},null==(o=k.classNames)?void 0:o.header,null==b?void 0:b.header)},t.createElement("div",{className:`${s}-header-title`},"start"===i&&S,c&&t.createElement("div",{className:`${s}-title`,id:d},c)),m&&t.createElement("div",{className:`${s}-extra`},m),"end"===i&&S):null,t.createElement("div",{className:(0,a.default)(`${s}-body`,null==b?void 0:b.body,null==(n=k.classNames)?void 0:n.body),style:Object.assign(Object.assign(Object.assign({},null==(r=k.styles)?void 0:r.body),g),null==w?void 0:w.body)},f?t.createElement(D.default,{active:!0,title:!1,paragraph:{rows:5},className:`${s}-body-skeleton`}):x),(()=>{var e,n;if(!u)return null;let r=`${s}-footer`;return t.createElement("div",{className:(0,a.default)(r,null==(e=k.classNames)?void 0:e.footer,null==b?void 0:b.footer),style:Object.assign(Object.assign(Object.assign({},null==(n=k.styles)?void 0:n.footer),v),null==w?void 0:w.footer)},u)})())};e.i(296059);var R=e.i(915654),_=e.i(183293),z=e.i(246422),F=e.i(838378);let T=(e,t)=>({"&-enter, &-appear":Object.assign(Object.assign({},e),{"&-active":t}),"&-leave":Object.assign(Object.assign({},t),{"&-active":e})}),P=(e,t)=>Object.assign({"&-enter, &-appear, &-leave":{"&-start":{transition:"none"},"&-active":{transition:`all ${t}`}}},T({opacity:e},{opacity:1})),A=(0,z.genStyleHooks)("Drawer",e=>{let t=(0,F.mergeToken)(e,{});return[(e=>{let{borderRadiusSM:t,componentCls:a,zIndexPopup:n,colorBgMask:r,colorBgElevated:l,motionDurationSlow:o,motionDurationMid:i,paddingXS:s,padding:d,paddingLG:c,fontSizeLG:u,lineHeightLG:m,lineWidth:p,lineType:f,colorSplit:y,marginXS:h,colorIcon:g,colorIconHover:v,colorBgTextHover:x,colorBgTextActive:b,colorText:w,fontWeightStrong:k,footerPaddingBlock:j,footerPaddingInline:C,calc:S}=e,O=`${a}-content-wrapper`;return{[a]:{position:"fixed",inset:0,zIndex:n,pointerEvents:"none",color:w,"&-pure":{position:"relative",background:l,display:"flex",flexDirection:"column",[`&${a}-left`]:{boxShadow:e.boxShadowDrawerLeft},[`&${a}-right`]:{boxShadow:e.boxShadowDrawerRight},[`&${a}-top`]:{boxShadow:e.boxShadowDrawerUp},[`&${a}-bottom`]:{boxShadow:e.boxShadowDrawerDown}},"&-inline":{position:"absolute"},[`${a}-mask`]:{position:"absolute",inset:0,zIndex:n,background:r,pointerEvents:"auto"},[O]:{position:"absolute",zIndex:n,maxWidth:"100vw",transition:`all ${o}`,"&-hidden":{display:"none"}},[`&-left > ${O}`]:{top:0,bottom:0,left:{_skip_check_:!0,value:0},boxShadow:e.boxShadowDrawerLeft},[`&-right > ${O}`]:{top:0,right:{_skip_check_:!0,value:0},bottom:0,boxShadow:e.boxShadowDrawerRight},[`&-top > ${O}`]:{top:0,insetInline:0,boxShadow:e.boxShadowDrawerUp},[`&-bottom > ${O}`]:{bottom:0,insetInline:0,boxShadow:e.boxShadowDrawerDown},[`${a}-content`]:{display:"flex",flexDirection:"column",width:"100%",height:"100%",overflow:"auto",background:l,pointerEvents:"auto"},[`${a}-header`]:{display:"flex",flex:0,alignItems:"center",padding:`${(0,R.unit)(d)} ${(0,R.unit)(c)}`,fontSize:u,lineHeight:m,borderBottom:`${(0,R.unit)(p)} ${f} ${y}`,"&-title":{display:"flex",flex:1,alignItems:"center",minWidth:0,minHeight:0}},[`${a}-extra`]:{flex:"none"},[`${a}-close`]:Object.assign({display:"inline-flex",width:S(u).add(s).equal(),height:S(u).add(s).equal(),borderRadius:t,justifyContent:"center",alignItems:"center",color:g,fontWeight:k,fontSize:u,fontStyle:"normal",lineHeight:1,textAlign:"center",textTransform:"none",textDecoration:"none",background:"transparent",border:0,cursor:"pointer",transition:`all ${i}`,textRendering:"auto",[`&${a}-close-end`]:{marginInlineStart:h},[`&:not(${a}-close-end)`]:{marginInlineEnd:h},"&:hover":{color:v,backgroundColor:x,textDecoration:"none"},"&:active":{backgroundColor:b}},(0,_.genFocusStyle)(e)),[`${a}-title`]:{flex:1,margin:0,fontWeight:e.fontWeightStrong,fontSize:u,lineHeight:m},[`${a}-body`]:{flex:1,minWidth:0,minHeight:0,padding:c,overflow:"auto",[`${a}-body-skeleton`]:{width:"100%",height:"100%",display:"flex",justifyContent:"center"}},[`${a}-footer`]:{flexShrink:0,padding:`${(0,R.unit)(j)} ${(0,R.unit)(C)}`,borderTop:`${(0,R.unit)(p)} ${f} ${y}`},"&-rtl":{direction:"rtl"}}}})(t),(e=>{let{componentCls:t,motionDurationSlow:a}=e;return{[t]:{[`${t}-mask-motion`]:P(0,a),[`${t}-panel-motion`]:["left","right","top","bottom"].reduce((e,t)=>{let n;return Object.assign(Object.assign({},e),{[`&-${t}`]:[P(.7,a),T({transform:(n="100%",({left:`translateX(-${n})`,right:`translateX(${n})`,top:`translateY(-${n})`,bottom:`translateY(${n})`})[t])},{transform:"none"})]})},{})}}})(t)]},e=>({zIndexPopup:e.zIndexPopupBase,footerPaddingBlock:e.paddingXS,footerPaddingInline:e.padding}));var B=function(e,t){var a={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&0>t.indexOf(n)&&(a[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var r=0,n=Object.getOwnPropertySymbols(e);rt.indexOf(n[r])&&Object.prototype.propertyIsEnumerable.call(e,n[r])&&(a[n[r]]=e[n[r]]);return a};let K={distance:180},L=e=>{let{rootClassName:n,width:r,height:l,size:o="default",mask:i=!0,push:s=K,open:d,afterOpenChange:c,onClose:u,prefixCls:m,getContainer:p,panelRef:f=null,style:h,className:g,"aria-labelledby":v,visible:x,afterVisibleChange:b,maskStyle:w,drawerStyle:I,contentWrapperStyle:D,destroyOnClose:R,destroyOnHidden:_}=e,z=B(e,["rootClassName","width","height","size","mask","push","open","afterOpenChange","onClose","prefixCls","getContainer","panelRef","style","className","aria-labelledby","visible","afterVisibleChange","maskStyle","drawerStyle","contentWrapperStyle","destroyOnClose","destroyOnHidden"]),F=(0,j.default)(),T=z.title?F:void 0,{getPopupContainer:P,getPrefixCls:L,direction:q,className:U,style:W,classNames:H,styles:V}=(0,E.useComponentConfig)("drawer"),J=L("drawer",m),[X,Y,Q]=A(J),G=void 0===p&&P?()=>P(document.body):p,Z=(0,a.default)({"no-mask":!i,[`${J}-rtl`]:"rtl"===q},n,Y,Q),ee=t.useMemo(()=>null!=r?r:"large"===o?736:378,[r,o]),et=t.useMemo(()=>null!=l?l:"large"===o?736:378,[l,o]),ea={motionName:(0,O.getTransitionName)(J,"mask-motion"),motionAppear:!0,motionEnter:!0,motionLeave:!0,motionDeadline:500},en=(0,N.usePanelRef)(),er=(0,y.composeRef)(f,en),[el,eo]=(0,S.useZIndex)("Drawer",z.zIndex),{classNames:ei={},styles:es={}}=z;return X(t.createElement(C.default,{form:!0,space:!0},t.createElement($.default.Provider,{value:eo},t.createElement(k,Object.assign({prefixCls:J,onClose:u,maskMotion:ea,motion:e=>({motionName:(0,O.getTransitionName)(J,`panel-motion-${e}`),motionAppear:!0,motionEnter:!0,motionLeave:!0,motionDeadline:500})},z,{classNames:{mask:(0,a.default)(ei.mask,H.mask),content:(0,a.default)(ei.content,H.content),wrapper:(0,a.default)(ei.wrapper,H.wrapper)},styles:{mask:Object.assign(Object.assign(Object.assign({},es.mask),w),V.mask),content:Object.assign(Object.assign(Object.assign({},es.content),I),V.content),wrapper:Object.assign(Object.assign(Object.assign({},es.wrapper),D),V.wrapper)},open:null!=d?d:x,mask:i,push:s,width:ee,height:et,style:Object.assign(Object.assign({},W),h),className:(0,a.default)(U,g),rootClassName:Z,getContainer:G,afterOpenChange:null!=c?c:b,panelRef:er,zIndex:el,"aria-labelledby":null!=v?v:T,destroyOnClose:null!=_?_:R}),t.createElement(M,Object.assign({prefixCls:J},z,{ariaId:T,onClose:u}))))))};L._InternalPanelDoNotUseOrYouWillBeFired=e=>{let{prefixCls:n,style:r,className:l,placement:o="right"}=e,i=B(e,["prefixCls","style","className","placement"]),{getPrefixCls:s}=t.useContext(E.ConfigContext),d=s("drawer",n),[c,u,m]=A(d),p=(0,a.default)(d,`${d}-pure`,`${d}-${o}`,u,m,l);return c(t.createElement("div",{className:p,style:r},t.createElement(M,Object.assign({prefixCls:d},i))))},e.s(["Drawer",0,L],608856)},91979,e=>{"use strict";e.i(247167);var t=e.i(931067),a=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M909.1 209.3l-56.4 44.1C775.8 155.1 656.2 92 521.9 92 290 92 102.3 279.5 102 511.5 101.7 743.7 289.8 932 521.9 932c181.3 0 335.8-115 394.6-276.1 1.5-4.2-.7-8.9-4.9-10.3l-56.7-19.5a8 8 0 00-10.1 4.8c-1.8 5-3.8 10-5.9 14.9-17.3 41-42.1 77.8-73.7 109.4A344.77 344.77 0 01655.9 829c-42.3 17.9-87.4 27-133.8 27-46.5 0-91.5-9.1-133.8-27A341.5 341.5 0 01279 755.2a342.16 342.16 0 01-73.7-109.4c-17.9-42.4-27-87.4-27-133.9s9.1-91.5 27-133.9c17.3-41 42.1-77.8 73.7-109.4 31.6-31.6 68.4-56.4 109.3-73.8 42.3-17.9 87.4-27 133.8-27 46.5 0 91.5 9.1 133.8 27a341.5 341.5 0 01109.3 73.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 003 14.1l175.6 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c-.1-6.6-7.8-10.3-13-6.2z"}}]},name:"reload",theme:"outlined"};var r=e.i(9583),l=a.forwardRef(function(e,l){return a.createElement(r.default,(0,t.default)({},e,{ref:l,icon:n}))});e.s(["ReloadOutlined",0,l],91979)},751904,e=>{"use strict";var t=e.i(401361);e.s(["EditOutlined",()=>t.default])},123521,e=>{"use strict";var t=e.i(984125);e.s(["EyeOutlined",()=>t.default])},956224,e=>{"use strict";var t=e.i(843476),a=e.i(271645),n=e.i(954616),r=e.i(266027),l=e.i(912598),o=e.i(464571),i=e.i(175712),s=e.i(608856),d=e.i(21548),c=e.i(311451),u=e.i(770914),m=e.i(291542),p=e.i(592968),f=e.i(898586),y=e.i(998573),h=e.i(955135),g=e.i(751904),v=e.i(123521),x=e.i(646563),b=e.i(91979),w=e.i(928685),k=e.i(602869),j=e.i(808613),C=e.i(212931);let{Text:S}=f.Typography,O=({open:e,mode:n,initialRow:r,onClose:l,onSave:o})=>{let[i]=j.Form.useForm(),[s,d]=(0,a.useState)(!1);(0,a.useEffect)(()=>{e&&("edit"===n&&r?i.setFieldsValue({key:r.key,value:r.value,metadata:null!=r.metadata?JSON.stringify(r.metadata,null,2):""}):i.resetFields())},[e,n,r,i]);let u=async()=>{let e=await i.validateFields();d(!0);let t=await o(e.key.trim(),e.value??"",e.metadata??"","create"===n);d(!1),t&&(i.resetFields(),l())};return(0,t.jsx)(C.Modal,{open:e,title:"create"===n?"Create memory":`Edit ${r?.key??""}`,onCancel:()=>{i.resetFields(),l()},onOk:u,okText:"create"===n?"Create":"Save",confirmLoading:s,width:640,destroyOnClose:!0,children:(0,t.jsxs)(j.Form,{form:i,layout:"vertical",children:[(0,t.jsx)(j.Form.Item,{label:"Key",name:"key",rules:[{required:!0,message:"Key is required"}],tooltip:"Globally unique — two memories cannot share a key. Namespace your own keys if you need per-user isolation (e.g. user:123:notes).",children:(0,t.jsx)(c.Input,{placeholder:"e.g. user_role",disabled:"edit"===n})}),(0,t.jsx)(j.Form.Item,{label:"Value",name:"value",rules:[{required:!0,message:"Value is required"}],tooltip:"Markdown/text injected into LLM context. Plain strings are fine.",children:(0,t.jsx)(c.Input.TextArea,{rows:8,placeholder:"What the agent should remember…"})}),(0,t.jsx)(j.Form.Item,{label:(0,t.jsxs)("span",{children:["Metadata ",(0,t.jsx)(S,{type:"secondary",children:"(optional JSON)"})]}),name:"metadata",tooltip:"Optional structured metadata — must be valid JSON if provided.",children:(0,t.jsx)(c.Input.TextArea,{rows:4,placeholder:'{"tags": ["example"]}',style:{fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace"}})})]})})};var $=e.i(127952);let{Text:E,Paragraph:N,Title:I}=f.Typography;function D(e){if(!e)return"—";try{return new Date(e).toLocaleString()}catch{return e}}let M=({accessToken:e})=>{let[f,j]=(0,a.useState)(""),[C,S]=(0,a.useState)(""),[M,R]=(0,a.useState)(null),[_,z]=(0,a.useState)(null),[F,T]=(0,a.useState)(null),[P,A]=(0,a.useState)(!1),[B,K]=(0,a.useState)(1);a.default.useEffect(()=>{K(1)},[C]);let L=(0,l.useQueryClient)(),q="memoryList",{data:U,isLoading:W,isFetching:H}=(0,r.useQuery)({queryKey:[q,C,B],queryFn:()=>{if(!e)throw Error("Access token required");return(0,k.fetchMemoryList)(e,{keyPrefix:C||void 0,page:B,pageSize:50})},enabled:!!e}),V=(0,a.useMemo)(()=>U?.memories??[],[U]),J=U?.total??0,X=()=>L.invalidateQueries({queryKey:[q]}),Y=(0,n.useMutation)({mutationFn:t=>{if(!e)throw Error("Access token required");return(0,k.createMemory)(e,t)},onSuccess:e=>{y.message.success(`Created ${e.key}`),X()},onError:e=>{y.message.error(`Save failed: ${e.message}`)}}),Q=(0,n.useMutation)({mutationFn:t=>{if(!e)throw Error("Access token required");let{key:a,...n}=t;return(0,k.updateMemory)(e,a,n)},onSuccess:e=>{y.message.success(`Updated ${e.key}`),X()},onError:e=>{y.message.error(`Save failed: ${e.message}`)}}),G=(0,n.useMutation)({mutationFn:t=>{if(!e)throw Error("Access token required");return(0,k.deleteMemory)(e,t).then(()=>t)},onSuccess:e=>{y.message.success(`Deleted ${e}`),X()},onError:e=>{y.message.error(`Delete failed: ${e.message}`)}}),Z=async()=>{if(F)try{await G.mutateAsync(F.key),T(null)}catch{}},ee=async(t,a,n,r)=>{let l;if(!e)return!1;if(n.trim())try{l=JSON.parse(n)}catch{return y.message.error("Metadata must be valid JSON (or leave empty)."),!1}else l=r?void 0:null;try{return r?await Y.mutateAsync({key:t,value:a,metadata:l}):await Q.mutateAsync({key:t,value:a,metadata:l}),!0}catch{return!1}},et=(e,a)=>{if(!e)return(0,t.jsx)(E,{type:"secondary",children:"-"});let n=e.length>10?`${e.slice(0,7)}...`:e,r="font-mono text-blue-600 bg-blue-50 text-xs font-medium px-2 py-0.5 rounded-md border border-blue-200 inline-block max-w-[15ch] truncate whitespace-nowrap";return(0,t.jsx)(p.Tooltip,{title:e,children:a?(0,t.jsx)("button",{onClick:a,className:`${r} hover:bg-blue-100 cursor-pointer transition-colors text-left`,children:n}):(0,t.jsx)("span",{className:r,children:n})})},ea=[{title:"ID",dataIndex:"memory_id",key:"memory_id",width:140,render:(e,t)=>et(t.memory_id,()=>R(t))},{title:"Name",dataIndex:"key",key:"key",width:200,render:e=>(0,t.jsx)(E,{code:!0,children:e})},{title:"Preview",dataIndex:"value",key:"value",render:e=>(0,t.jsx)(E,{type:"secondary",style:{whiteSpace:"pre-wrap"},children:function(e,t=120){if(!e)return"";let a=e.trim();return a.length<=t?a:`${a.slice(0,t)}…`}(e)})},{title:"User ID",dataIndex:"user_id",key:"user_id",width:160,render:e=>et(e)},{title:"Team ID",dataIndex:"team_id",key:"team_id",width:160,render:e=>et(e)},{title:"Updated",dataIndex:"updated_at",key:"updated_at",width:180,render:e=>(0,t.jsx)(E,{type:"secondary",children:D(e)})},{title:"",key:"actions",width:140,render:(e,a)=>(0,t.jsxs)(u.Space,{size:4,children:[(0,t.jsx)(o.Button,{size:"small",type:"text",icon:(0,t.jsx)(v.EyeOutlined,{}),onClick:()=>R(a),"aria-label":"View"}),(0,t.jsx)(o.Button,{size:"small",type:"text",icon:(0,t.jsx)(g.EditOutlined,{}),onClick:()=>z(a),"aria-label":"Edit"}),(0,t.jsx)(o.Button,{size:"small",type:"text",danger:!0,icon:(0,t.jsx)(h.DeleteOutlined,{}),onClick:()=>{T(a)},"aria-label":"Delete"})]})}];return(0,t.jsxs)("div",{className:"w-full",style:{padding:24},children:[(0,t.jsxs)(u.Space,{direction:"vertical",size:"large",style:{width:"100%"},children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(I,{level:3,style:{marginBottom:4},children:"Memory"}),(0,t.jsxs)(N,{type:"secondary",style:{marginBottom:0},children:["Inspect what your agents have stored under ",(0,t.jsx)(E,{code:!0,children:"/v1/memory"}),". Scoped to memories visible to your user / team (admins see all)."]})]}),(0,t.jsxs)(i.Card,{children:[(0,t.jsxs)(u.Space,{style:{width:"100%",justifyContent:"space-between",marginBottom:16},wrap:!0,children:[(0,t.jsxs)(u.Space,{children:[(0,t.jsx)(c.Input,{allowClear:!0,placeholder:'Filter by key prefix, e.g. "user:"',prefix:(0,t.jsx)(w.SearchOutlined,{}),value:f,onChange:e=>j(e.target.value),onPressEnter:()=>S(f.trim()),onClear:()=>{j(""),S("")},style:{width:280}}),(0,t.jsx)(o.Button,{type:"primary",ghost:!0,onClick:()=>S(f.trim()),children:"Search"}),(0,t.jsx)(o.Button,{icon:(0,t.jsx)(b.ReloadOutlined,{}),onClick:()=>X(),loading:H&&!W,children:"Refresh"})]}),(0,t.jsx)(o.Button,{type:"primary",icon:(0,t.jsx)(x.PlusOutlined,{}),onClick:()=>A(!0),children:"New memory"})]}),(0,t.jsx)(m.Table,{rowKey:"memory_id",loading:W,dataSource:V,columns:ea,pagination:{current:B,pageSize:50,total:J,showSizeChanger:!1,showTotal:(e,t)=>`${t[0]}–${t[1]} of ${e}`,onChange:e=>K(e)},locale:{emptyText:(0,t.jsx)(d.Empty,{description:C?`No memories with keys starting with "${C}"`:"No memories stored yet"})}})]})]}),(0,t.jsx)(s.Drawer,{open:!!M,onClose:()=>R(null),title:M?(0,t.jsx)(u.Space,{children:(0,t.jsx)(E,{code:!0,children:M.key})}):"Memory",width:720,destroyOnClose:!0,children:M&&(0,t.jsxs)(u.Space,{direction:"vertical",size:"middle",style:{width:"100%"},children:[(0,t.jsxs)(u.Space,{size:"large",wrap:!0,children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(E,{strong:!0,style:{display:"block"},children:"Memory ID"}),(0,t.jsx)(E,{code:!0,style:{fontSize:12},children:M.memory_id})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(E,{strong:!0,style:{display:"block"},children:"User ID"}),(0,t.jsx)(E,{type:M.user_id?void 0:"secondary",children:M.user_id??"-"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(E,{strong:!0,style:{display:"block"},children:"Team ID"}),(0,t.jsx)(E,{type:M.team_id?void 0:"secondary",children:M.team_id??"-"})]})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(E,{strong:!0,children:"Value"}),(0,t.jsx)(N,{style:{background:"#fafafa",padding:12,borderRadius:6,whiteSpace:"pre-wrap",fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",fontSize:13},children:M.value})]}),void 0!==M.metadata&&null!==M.metadata&&(0,t.jsxs)("div",{children:[(0,t.jsx)(E,{strong:!0,children:"Metadata"}),(0,t.jsx)(N,{style:{background:"#fafafa",padding:12,borderRadius:6,whiteSpace:"pre-wrap",fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",fontSize:12},children:JSON.stringify(M.metadata,null,2)})]}),(0,t.jsxs)(u.Space,{split:(0,t.jsx)(E,{type:"secondary",children:"·"}),wrap:!0,size:"small",style:{color:"rgba(0,0,0,0.45)"},children:[(0,t.jsxs)(E,{type:"secondary",children:["Created ",D(M.created_at),M.created_by?` by ${M.created_by}`:""]}),(0,t.jsxs)(E,{type:"secondary",children:["Updated ",D(M.updated_at),M.updated_by?` by ${M.updated_by}`:""]})]})]})}),(0,t.jsx)(O,{open:P||!!_,mode:_?"edit":"create",initialRow:_??void 0,onClose:()=>{A(!1),z(null)},onSave:ee}),(0,t.jsx)($.default,{isOpen:!!F,title:"Delete memory",message:"This action cannot be undone.",resourceInformationTitle:"Memory",resourceInformation:F?[{label:"Key",value:F.key,code:!0},{label:"Memory ID",value:F.memory_id,code:!0},{label:"User ID",value:F.user_id??"-",code:!0},{label:"Team ID",value:F.team_id??"-",code:!0}]:[],onCancel:()=>{G.isPending||T(null)},onOk:Z,confirmLoading:G.isPending,requiredConfirmation:F?.key})]})};var R=e.i(135214);e.s(["default",0,function(){let{accessToken:e,userRole:a,userId:n}=(0,R.default)();return(0,t.jsx)(M,{accessToken:e,userID:n,userRole:a})}],956224)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0q6~n4y84cejn.js b/litellm/proxy/_experimental/out/_next/static/chunks/0q6~n4y84cejn.js new file mode 100644 index 00000000000..b82e28e8264 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/0q6~n4y84cejn.js @@ -0,0 +1 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,35983,992704,877891,401141,952744,605083,101852,919751,178677,635307,495470,333771,e=>{"use strict";let t,n,r,o,l;var i=e.i(290571),u=e.i(271645),s=e.i(783222),a=e.i(433336),c=e.i(174080),d=e.i(394487),f=e.i(503269),p=e.i(214520),m=e.i(835696),v=e.i(746725);function g(e,t=!1){let[n,r]=(0,u.useReducer)(()=>({}),{}),o=(0,u.useMemo)(()=>(function(e){if(null===e)return{width:0,height:0};let{width:t,height:n}=e.getBoundingClientRect();return{width:t,height:n}})(e),[e,n]);return(0,m.useIsoMorphicEffect)(()=>{if(!e)return;let t=new ResizeObserver(r);return t.observe(e),()=>{t.disconnect()}},[e]),t?{width:`${o.width}px`,height:`${o.height}px`}:o}e.s(["useElementSize",0,g],992704);var h=e.i(914189),b=e.i(544508),x=e.i(402155);class E extends Map{constructor(e){super(),this.factory=e}get(e){let t=super.get(e);return void 0===t&&(t=this.factory(e),this.set(e,t)),t}}function y(e,t){let n=e(),r=new Set;return{getSnapshot:()=>n,subscribe:e=>(r.add(e),()=>r.delete(e)),dispatch(e,...o){let l=t[e].call(n,...o);l&&(n=l,r.forEach(e=>e()))}}}function S(e){return(0,u.useSyncExternalStore)(e.subscribe,e.getSnapshot,e.getSnapshot)}let R=new E(()=>y(()=>[],{ADD(e){return this.includes(e)?this:[...this,e]},REMOVE(e){let t=this.indexOf(e);if(-1===t)return this;let n=this.slice();return n.splice(t,1),n}}));function w(e,t){let n=R.get(t),r=(0,u.useId)(),o=S(n);if((0,m.useIsoMorphicEffect)(()=>{if(e)return n.dispatch("ADD",r),()=>n.dispatch("REMOVE",r)},[n,e]),!e)return!1;let l=o.indexOf(r),i=o.length;return -1===l&&(l=i,i+=1),l===i-1}let O=new Map,P=new Map;function C(e){var t;let n=null!=(t=P.get(e))?t:0;return P.set(e,n+1),0!==n||(O.set(e,{"aria-hidden":e.getAttribute("aria-hidden"),inert:e.inert}),e.setAttribute("aria-hidden","true"),e.inert=!0),()=>(function(e){var t;let n=null!=(t=P.get(e))?t:1;if(1===n?P.delete(e):P.set(e,n-1),1!==n)return;let r=O.get(e);r&&(null===r["aria-hidden"]?e.removeAttribute("aria-hidden"):e.setAttribute("aria-hidden",r["aria-hidden"]),e.inert=r.inert,O.delete(e))})(e)}var M=e.i(941444);function I(e,t,n){let r=(0,M.useLatestValue)(e=>{let t=e.getBoundingClientRect();0===t.x&&0===t.y&&0===t.width&&0===t.height&&n()});(0,u.useEffect)(()=>{if(!e)return;let n=null===t?null:t instanceof HTMLElement?t:t.current;if(!n)return;let o=(0,b.disposables)();if("u">typeof ResizeObserver){let e=new ResizeObserver(()=>r.current(n));e.observe(n),o.add(()=>e.disconnect())}if("u">typeof IntersectionObserver){let e=new IntersectionObserver(()=>r.current(n));e.observe(n),o.add(()=>e.disconnect())}return()=>o.dispose()},[t,r,e])}e.s(["useOnDisappear",0,I],877891);var L=e.i(652265);function T(){return/iPhone/gi.test(window.navigator.platform)||/Mac/gi.test(window.navigator.platform)&&window.navigator.maxTouchPoints>0}function D(e,t,n,r){let o=(0,M.useLatestValue)(n);(0,u.useEffect)(()=>{if(e)return document.addEventListener(t,n,r),()=>document.removeEventListener(t,n,r);function n(e){o.current(e)}},[e,t,r])}function F(e,t,n,r){let o=(0,M.useLatestValue)(n);(0,u.useEffect)(()=>{if(e)return window.addEventListener(t,n,r),()=>window.removeEventListener(t,n,r);function n(e){o.current(e)}},[e,t,r])}function k(e,t,n){let r=w(e,"outside-click"),o=(0,M.useLatestValue)(n),l=(0,u.useCallback)(function(e,n){if(e.defaultPrevented)return;let r=n(e);if(null!==r&&r.getRootNode().contains(r)&&r.isConnected){for(let n of function e(t){return"function"==typeof t?e(t()):Array.isArray(t)||t instanceof Set?t:[t]}(t))if(null!==n&&(n.contains(r)||e.composed&&e.composedPath().includes(n)))return;return(0,L.isFocusableElement)(r,L.FocusableMode.Loose)||-1===r.tabIndex||e.preventDefault(),o.current(e,r)}},[o,t]),i=(0,u.useRef)(null);D(r,"pointerdown",e=>{var t,n;i.current=(null==(n=null==(t=e.composedPath)?void 0:t.call(e))?void 0:n[0])||e.target},!0),D(r,"mousedown",e=>{var t,n;i.current=(null==(n=null==(t=e.composedPath)?void 0:t.call(e))?void 0:n[0])||e.target},!0),D(r,"click",e=>{T()||/Android/gi.test(window.navigator.userAgent)||i.current&&(l(e,()=>i.current),i.current=null)},!0);let s=(0,u.useRef)({x:0,y:0});D(r,"touchstart",e=>{s.current.x=e.touches[0].clientX,s.current.y=e.touches[0].clientY},!0),D(r,"touchend",e=>{let t={x:e.changedTouches[0].clientX,y:e.changedTouches[0].clientY};if(!(Math.abs(t.x-s.current.x)>=30||Math.abs(t.y-s.current.y)>=30))return l(e,()=>e.target instanceof HTMLElement?e.target:null)},!0),F(r,"blur",e=>l(e,()=>window.document.activeElement instanceof HTMLIFrameElement?window.document.activeElement:null),!0)}function A(...e){return(0,u.useMemo)(()=>(0,x.getOwnerDocument)(...e),[...e])}e.s(["useWindowEvent",0,F],401141),e.s(["useOutsideClick",0,k],952744),e.s(["useOwnerDocument",0,A],605083);var H=e.i(144279);let N=y(()=>new Map,{PUSH(e,t){var n;let r=null!=(n=this.get(e))?n:{doc:e,count:0,d:(0,b.disposables)(),meta:new Set};return r.count++,r.meta.add(t),this.set(e,r),this},POP(e,t){let n=this.get(e);return n&&(n.count--,n.meta.delete(t)),this},SCROLL_PREVENT({doc:e,d:t,meta:n}){let r,o={doc:e,d:t,meta:function(e){let t={};for(let n of e)Object.assign(t,n(t));return t}(n)},l=[T()?{before({doc:e,d:t,meta:n}){function r(e){return n.containers.flatMap(e=>e()).some(t=>t.contains(e))}t.microTask(()=>{var n;if("auto"!==window.getComputedStyle(e.documentElement).scrollBehavior){let n=(0,b.disposables)();n.style(e.documentElement,"scrollBehavior","auto"),t.add(()=>t.microTask(()=>n.dispose()))}let o=null!=(n=window.scrollY)?n:window.pageYOffset,l=null;t.addEventListener(e,"click",t=>{if(t.target instanceof HTMLElement)try{let n=t.target.closest("a");if(!n)return;let{hash:o}=new URL(n.href),i=e.querySelector(o);i&&!r(i)&&(l=i)}catch{}},!0),t.addEventListener(e,"touchstart",e=>{if(e.target instanceof HTMLElement)if(r(e.target)){let n=e.target;for(;n.parentElement&&r(n.parentElement);)n=n.parentElement;t.style(n,"overscrollBehavior","contain")}else t.style(e.target,"touchAction","none")}),t.addEventListener(e,"touchmove",e=>{if(e.target instanceof HTMLElement&&"INPUT"!==e.target.tagName)if(r(e.target)){let t=e.target;for(;t.parentElement&&""!==t.dataset.headlessuiPortal&&!(t.scrollHeight>t.clientHeight||t.scrollWidth>t.clientWidth);)t=t.parentElement;""===t.dataset.headlessuiPortal&&e.preventDefault()}else e.preventDefault()},{passive:!1}),t.add(()=>{var e;o!==(null!=(e=window.scrollY)?e:window.pageYOffset)&&window.scrollTo(0,o),l&&l.isConnected&&(l.scrollIntoView({block:"nearest"}),l=null)})})}}:{},{before({doc:e}){var t;let n=e.documentElement;r=Math.max(0,(null!=(t=e.defaultView)?t:window).innerWidth-n.clientWidth)},after({doc:e,d:t}){let n=e.documentElement,o=Math.max(0,n.clientWidth-n.offsetWidth),l=Math.max(0,r-o);t.style(n,"paddingRight",`${l}px`)}},{before({doc:e,d:t}){t.style(e.documentElement,"overflow","hidden")}}];l.forEach(({before:e})=>null==e?void 0:e(o)),l.forEach(({after:e})=>null==e?void 0:e(o))},SCROLL_ALLOW({d:e}){e.dispose()},TEARDOWN({doc:e}){this.delete(e)}});function B(e,t,n=()=>[document.body]){!function(e,t,n=()=>({containers:[]})){let r=S(N),o=t?r.get(t):void 0;o&&o.count,(0,m.useIsoMorphicEffect)(()=>{if(!(!t||!e))return N.dispatch("PUSH",t,n),()=>N.dispatch("POP",t,n)},[e,t])}(w(e,"scroll-lock"),t,e=>{var t;return{containers:[...null!=(t=e.containers)?t:[],n]}})}N.subscribe(()=>{let e=N.getSnapshot(),t=new Map;for(let[n]of e)t.set(n,n.documentElement.style.overflow);for(let n of e.values()){let e="hidden"===t.get(n.doc),r=0!==n.count;(r&&!e||!r&&e)&&N.dispatch(n.count>0?"SCROLL_PREVENT":"SCROLL_ALLOW",n),0===n.count&&N.dispatch("TEARDOWN",n)}}),e.s(["useScrollLock",0,B],101852);var K=e.i(294316);let _=/([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g;function W(e){var t,n;let r=null!=(t=e.innerText)?t:"",o=e.cloneNode(!0);if(!(o instanceof HTMLElement))return r;let l=!1;for(let e of o.querySelectorAll('[hidden],[aria-hidden],[role="img"]'))e.remove(),l=!0;let i=l?null!=(n=o.innerText)?n:"":r;return _.test(i)&&(i=i.replace(_,"")),i}function V(e){return[e.screenX,e.screenY]}var j=e.i(83733),$=e.i(601893),U=e.i(953760),z="u">typeof document?u.useLayoutEffect:function(){};function Q(e,t){let n,r,o;if(e===t)return!0;if(typeof e!=typeof t)return!1;if("function"==typeof e&&e.toString()===t.toString())return!0;if(e&&t&&"object"==typeof e){if(Array.isArray(e)){if((n=e.length)!==t.length)return!1;for(r=n;0!=r--;)if(!Q(e[r],t[r]))return!1;return!0}if((n=(o=Object.keys(e)).length)!==Object.keys(t).length)return!1;for(r=n;0!=r--;)if(!({}).hasOwnProperty.call(t,o[r]))return!1;for(r=n;0!=r--;){let n=o[r];if(("_owner"!==n||!e.$$typeof)&&!Q(e[n],t[n]))return!1}return!0}return e!=e&&t!=t}function Y(e){return"u"{t.current=e}),t}let X=(e,t)=>{let n=(0,U.offset)(e);return{name:n.name,fn:n.fn,options:[e,t]}};e.i(247167);var J=e.i(229315),Z=e.i(343084);e.i(397126);let ee={...u},et=ee.useInsertionEffect||(e=>e());function en(e){let t=u.useRef(()=>{});return et(()=>{t.current=e}),u.useCallback(function(){for(var e=arguments.length,n=Array(e),r=0;rtypeof document?u.useLayoutEffect:u.useEffect;let eo=!1,el=0,ei=()=>"floating-ui-"+Math.random().toString(36).slice(2,6)+el++,eu=ee.useId||function(){let[e,t]=u.useState(()=>eo?ei():void 0);return er(()=>{null==e&&t(ei())},[]),u.useEffect(()=>{eo=!0},[]),e},es=u.createContext(null),ea=u.createContext(null),ec="active",ed="selected";function ef(e,t,n){let r=new Map,o="item"===n,l=e;if(o&&e){let{[ec]:t,[ed]:n,...r}=e;l=r}return{..."floating"===n&&{tabIndex:-1,"data-floating-ui-focusable":""},...l,...t.map(t=>{let r=t?t[n]:null;return"function"==typeof r?e?r(e):null:r}).concat(e).reduce((e,t)=>(t&&Object.entries(t).forEach(t=>{let[n,l]=t;if(!(o&&[ec,ed].includes(n)))if(0===n.indexOf("on")){if(r.has(n)||r.set(n,[]),"function"==typeof l){var i;null==(i=r.get(n))||i.push(l),e[n]=function(){for(var e,t=arguments.length,o=Array(t),l=0;le(...o)).find(e=>void 0!==e)}}}else e[n]=l}),e),{})}}function ep(e,t){return{...e,rects:{...e.rects,floating:{...e.rects.floating,height:t}}}}let em=(0,u.createContext)({styles:void 0,setReference:()=>{},setFloating:()=>{},getReferenceProps:()=>({}),getFloatingProps:()=>({}),slot:{}});em.displayName="FloatingContext";let ev=(0,u.createContext)(null);function eg(e){return(0,u.useMemo)(()=>e?"string"==typeof e?{to:e}:e:null,[e])}function eh(){return(0,u.useContext)(em).setReference}function eb(){return(0,u.useContext)(em).getReferenceProps}function ex(){let{getFloatingProps:e,slot:t}=(0,u.useContext)(em);return(0,u.useCallback)((...n)=>Object.assign({},e(...n),{"data-anchor":t.anchor}),[e,t])}function eE(e=null){!1===e&&(e=null),"string"==typeof e&&(e={to:e});let t=(0,u.useContext)(ev),n=(0,u.useMemo)(()=>e,[JSON.stringify(e,(e,t)=>{var n;return null!=(n=null==t?void 0:t.outerHTML)?n:t})]);(0,m.useIsoMorphicEffect)(()=>{null==t||t(null!=n?n:null)},[t,n]);let r=(0,u.useContext)(em);return(0,u.useMemo)(()=>[r.setFloating,e?r.styles:{}],[r.setFloating,e,r.styles])}function ey({children:e,enabled:t=!0}){var n,r,o,l,i,s,a,d,f,p,v,g,b;let x,E,y,S,R,w,O,P,C,M,I,L,T,[D,F]=(0,u.useState)(null),[k,A]=(0,u.useState)(0),H=(0,u.useRef)(null),[N,B]=(0,u.useState)(null);d=N,(0,m.useIsoMorphicEffect)(()=>{if(!d)return;let e=new MutationObserver(()=>{let e=window.getComputedStyle(d).maxHeight,t=parseFloat(e);if(isNaN(t))return;let n=parseInt(e);isNaN(n)||t!==n&&(d.style.maxHeight=`${Math.ceil(t)}px`)});return e.observe(d,{attributes:!0,attributeFilter:["style"]}),()=>{e.disconnect()}},[d]);let K=t&&null!==D&&null!==N,{to:_="bottom",gap:W=0,offset:V=0,padding:j=0,inner:$}=(f=D,p=N,x=eS(null!=(v=null==f?void 0:f.gap)?v:"var(--anchor-gap, 0)",p),E=eS(null!=(g=null==f?void 0:f.offset)?g:"var(--anchor-offset, 0)",p),y=eS(null!=(b=null==f?void 0:f.padding)?b:"var(--anchor-padding, 0)",p),{...f,gap:x,offset:E,padding:y}),[ee,et="center"]=_.split(" ");(0,m.useIsoMorphicEffect)(()=>{K&&A(0)},[K]);let{refs:eo,floatingStyles:el,context:ei}=function(e){void 0===e&&(e={});let{nodeId:t}=e,n=function(e){var t;let{open:n=!1,onOpenChange:r,elements:o}=e,l=eu(),i=u.useRef({}),[s]=u.useState(()=>{let e;return e=new Map,{emit(t,n){var r;null==(r=e.get(t))||r.forEach(e=>e(n))},on(t,n){e.set(t,[...e.get(t)||[],n])},off(t,n){var r;e.set(t,(null==(r=e.get(t))?void 0:r.filter(e=>e!==n))||[])}}}),a=null!=((null==(t=u.useContext(es))?void 0:t.id)||null),[c,d]=u.useState(o.reference),f=en((e,t,n)=>{i.current.openEvent=e?t:void 0,s.emit("openchange",{open:e,event:t,reason:n,nested:a}),null==r||r(e,t,n)}),p=u.useMemo(()=>({setPositionReference:d}),[]),m=u.useMemo(()=>({reference:c||o.reference||null,floating:o.floating||null,domReference:o.reference}),[c,o.reference,o.floating]);return u.useMemo(()=>({dataRef:i,open:n,onOpenChange:f,elements:m,events:s,floatingId:l,refs:p}),[n,f,m,s,l,p])}({...e,elements:{reference:null,floating:null,...e.elements}}),r=e.rootContext||n,o=r.elements,[l,i]=u.useState(null),[s,a]=u.useState(null),d=(null==o?void 0:o.domReference)||l,f=u.useRef(null),p=u.useContext(ea);er(()=>{d&&(f.current=d)},[d]);let m=function(e){void 0===e&&(e={});let{placement:t="bottom",strategy:n="absolute",middleware:r=[],platform:o,elements:{reference:l,floating:i}={},transform:s=!0,whileElementsMounted:a,open:d}=e,[f,p]=u.useState({x:0,y:0,strategy:n,placement:t,middlewareData:{},isPositioned:!1}),[m,v]=u.useState(r);Q(m,r)||v(r);let[g,h]=u.useState(null),[b,x]=u.useState(null),E=u.useCallback(e=>{e!==w.current&&(w.current=e,h(e))},[]),y=u.useCallback(e=>{e!==O.current&&(O.current=e,x(e))},[]),S=l||g,R=i||b,w=u.useRef(null),O=u.useRef(null),P=u.useRef(f),C=null!=a,M=G(a),I=G(o),L=G(d),T=u.useCallback(()=>{if(!w.current||!O.current)return;let e={placement:t,strategy:n,middleware:m};I.current&&(e.platform=I.current),(0,U.computePosition)(w.current,O.current,e).then(e=>{let t={...e,isPositioned:!1!==L.current};D.current&&!Q(P.current,t)&&(P.current=t,c.flushSync(()=>{p(t)}))})},[m,t,n,I,L]);z(()=>{!1===d&&P.current.isPositioned&&(P.current.isPositioned=!1,p(e=>({...e,isPositioned:!1})))},[d]);let D=u.useRef(!1);z(()=>(D.current=!0,()=>{D.current=!1}),[]),z(()=>{if(S&&(w.current=S),R&&(O.current=R),S&&R){if(M.current)return M.current(S,R,T);T()}},[S,R,T,M,C]);let F=u.useMemo(()=>({reference:w,floating:O,setReference:E,setFloating:y}),[E,y]),k=u.useMemo(()=>({reference:S,floating:R}),[S,R]),A=u.useMemo(()=>{let e={position:n,left:0,top:0};if(!k.floating)return e;let t=q(k.floating,f.x),r=q(k.floating,f.y);return s?{...e,transform:"translate("+t+"px, "+r+"px)",...Y(k.floating)>=1.5&&{willChange:"transform"}}:{position:n,left:t,top:r}},[n,s,k.floating,f.x,f.y]);return u.useMemo(()=>({...f,update:T,refs:F,elements:k,floatingStyles:A}),[f,T,F,k,A])}({...e,elements:{...o,...s&&{reference:s}}}),v=u.useCallback(e=>{let t=(0,J.isElement)(e)?{getBoundingClientRect:()=>e.getBoundingClientRect(),contextElement:e}:e;a(t),m.refs.setReference(t)},[m.refs]),g=u.useCallback(e=>{((0,J.isElement)(e)||null===e)&&(f.current=e,i(e)),((0,J.isElement)(m.refs.reference.current)||null===m.refs.reference.current||null!==e&&!(0,J.isElement)(e))&&m.refs.setReference(e)},[m.refs]),h=u.useMemo(()=>({...m.refs,setReference:g,setPositionReference:v,domReference:f}),[m.refs,g,v]),b=u.useMemo(()=>({...m.elements,domReference:d}),[m.elements,d]),x=u.useMemo(()=>({...m,...r,refs:h,elements:b,nodeId:t}),[m,h,b,t,r]);return er(()=>{r.dataRef.current.floatingContext=x;let e=null==p?void 0:p.nodesRef.current.find(e=>e.id===t);e&&(e.context=x)}),u.useMemo(()=>({...m,context:x,refs:h,elements:b}),[m,h,b,x])}({open:K,placement:"selection"===ee?"center"===et?"bottom":`bottom-${et}`:"center"===et?`${ee}`:`${ee}-${et}`,strategy:"absolute",transform:!1,middleware:[X({mainAxis:"selection"===ee?0:W,crossAxis:V}),(n={padding:j},{name:(S=(0,U.shift)(n)).name,fn:S.fn,options:[n,r]}),"selection"!==ee&&(o={padding:j},{name:(R=(0,U.flip)(o)).name,fn:R.fn,options:[o,l]}),"selection"===ee&&$?{name:"inner",options:w={...$,padding:j,overflowRef:H,offset:k,minItemsVisible:4,referenceOverflowThreshold:j,onFallbackChange(e){var t,n;if(!e)return;let r=ei.elements.floating;if(!r)return;let o=parseFloat(getComputedStyle(r).scrollPaddingBottom)||0,l=Math.min(4,r.childElementCount),i=0,u=0;for(let e of null!=(n=null==(t=ei.elements.floating)?void 0:t.childNodes)?n:[])if(e instanceof HTMLElement){let t=e.offsetTop,n=t+e.clientHeight+o,s=r.scrollTop,a=s+r.clientHeight;if(t>=s&&n<=a)l--;else{u=Math.max(0,Math.min(n,a)-Math.max(t,s)),i=e.clientHeight;break}}l>=1&&A(e=>{let t=i*l-u+o;return e>=t?e:t})}},async fn(e){let{listRef:t,overflowRef:n,onFallbackChange:r,offset:o=0,index:l=0,minItemsVisible:i=4,referenceOverflowThreshold:u=0,scrollRef:s,...a}=(0,Z.evaluate)(w,e),{rects:d,elements:{floating:f}}=e,p=t.current[l],m=(null==s?void 0:s.current)||f,v=f.clientTop||m.clientTop,g=0!==f.clientTop,h=0!==m.clientTop,b=f===m;if(!p)return{};let x={...e,...await X(-p.offsetTop-f.clientTop-d.reference.height/2-p.offsetHeight/2-o).fn(e)},E=await (0,U.detectOverflow)(ep(x,m.scrollHeight+v+f.clientTop),a),y=await (0,U.detectOverflow)(x,{...a,elementContext:"reference"}),S=(0,Z.max)(0,E.top),R=x.y+S,O=(m.scrollHeight>m.clientHeight?e=>e:Z.round)((0,Z.max)(0,m.scrollHeight+(g&&b||h?2*v:0)-S-(0,Z.max)(0,E.bottom)));if(m.style.maxHeight=O+"px",m.scrollTop=S,r){let e=m.offsetHeight=-u||y.bottom>=-u;c.flushSync(()=>r(e))}return n&&(n.current=await (0,U.detectOverflow)(ep({...x,y:R},m.offsetHeight+v+f.clientTop),a)),{y:R}}}:null,(i={padding:j,apply({availableWidth:e,availableHeight:t,elements:n}){Object.assign(n.floating.style,{overflow:"auto",maxWidth:`${e}px`,maxHeight:`min(var(--anchor-max-height, 100vh), ${t}px)`})}},{name:(O=(0,U.size)(i)).name,fn:O.fn,options:[i,s]})].filter(Boolean),whileElementsMounted:U.autoUpdate}),[ec=ee,ed=et]=ei.placement.split("-");"selection"===ee&&(ec="selection");let eg=(0,u.useMemo)(()=>({anchor:[ec,ed].filter(Boolean).join(" ")}),[ec,ed]),{getReferenceProps:eh,getFloatingProps:eb}=(P=(a=[function(e,t){let{open:n,elements:r}=e,{enabled:o=!0,overflowRef:l,scrollRef:i,onChange:s}=t,a=en(s),d=u.useRef(!1),f=u.useRef(null),p=u.useRef(null);u.useEffect(()=>{if(!o)return;function e(e){if(e.ctrlKey||!t||null==l.current)return;let n=e.deltaY,r=l.current.top>=-.5,o=l.current.bottom>=-.5,i=t.scrollHeight-t.clientHeight,u=n<0?-1:1,s=n<0?"max":"min";if(!(t.scrollHeight<=t.clientHeight))if(!r&&n>0||!o&&n<0)e.preventDefault(),c.flushSync(()=>{a(e=>e+Math[s](n,i*u))});else{let e;/firefox/i.test((e=navigator.userAgentData)&&Array.isArray(e.brands)?e.brands.map(e=>{let{brand:t,version:n}=e;return t+"/"+n}).join(" "):navigator.userAgent)&&(t.scrollTop+=n)}}let t=(null==i?void 0:i.current)||r.floating;if(n&&t)return t.addEventListener("wheel",e),requestAnimationFrame(()=>{f.current=t.scrollTop,null!=l.current&&(p.current={...l.current})}),()=>{f.current=null,p.current=null,t.removeEventListener("wheel",e)}},[o,n,r.floating,l,i,a]);let m=u.useMemo(()=>({onKeyDown(){d.current=!0},onWheel(){d.current=!1},onPointerMove(){d.current=!1},onScroll(){let e=(null==i?void 0:i.current)||r.floating;if(l.current&&e&&d.current){if(null!==f.current){let t=e.scrollTop-f.current;(l.current.bottom<-.5&&t<-1||l.current.top<-.5&&t>1)&&c.flushSync(()=>a(e=>e+t))}requestAnimationFrame(()=>{f.current=e.scrollTop})}}}),[r.floating,a,l,i]);return u.useMemo(()=>o?{floating:m}:{},[o,m])}(ei,{overflowRef:H,onChange:A})]).map(e=>null==e?void 0:e.reference),C=a.map(e=>null==e?void 0:e.floating),M=a.map(e=>null==e?void 0:e.item),I=u.useCallback(e=>ef(e,a,"reference"),P),L=u.useCallback(e=>ef(e,a,"floating"),C),T=u.useCallback(e=>ef(e,a,"item"),M),u.useMemo(()=>({getReferenceProps:I,getFloatingProps:L,getItemProps:T}),[I,L,T])),ex=(0,h.useEvent)(e=>{B(e),eo.setFloating(e)});return u.createElement(ev.Provider,{value:F},u.createElement(em.Provider,{value:{setFloating:ex,setReference:eo.setReference,styles:el,getReferenceProps:eh,getFloatingProps:eb,slot:eg}},e))}function eS(e,t,n){let r=(0,v.useDisposables)(),o=(0,h.useEvent)((e,t)=>{if(null==e)return[n,null];if("number"==typeof e)return[e,null];if("string"==typeof e){if(!t)return[n,null];let o=eR(e,t);return[o,n=>{let l=function e(t){let n=/var\((.*)\)/.exec(t);if(n){let t=n[1].indexOf(",");if(-1===t)return[n[1]];let r=n[1].slice(0,t).trim(),o=n[1].slice(t+1).trim();return o?[r,...e(o)]:[r]}return[]}(e);{let i=l.map(e=>window.getComputedStyle(t).getPropertyValue(e));r.requestAnimationFrame(function u(){r.nextFrame(u);let s=!1;for(let[e,n]of l.entries()){let r=window.getComputedStyle(t).getPropertyValue(n);if(i[e]!==r){i[e]=r,s=!0;break}}if(!s)return;let a=eR(e,t);o!==a&&(n(a),o=a)})}return r.dispose}]}return[n,null]}),l=(0,u.useMemo)(()=>o(e,t)[0],[e,t]),[i=l,s]=(0,u.useState)();return(0,m.useIsoMorphicEffect)(()=>{let[n,r]=o(e,t);if(s(n),r)return r(s)},[e,t]),i}function eR(e,t){let n=document.createElement("div");t.appendChild(n),n.style.setProperty("margin-top","0px","important"),n.style.setProperty("margin-top",e,"important");let r=parseFloat(window.getComputedStyle(n).marginTop)||0;return t.removeChild(n),r}ev.displayName="PlacementContext",e.s(["FloatingProvider",0,ey,"useFloatingPanel",0,eE,"useFloatingPanelProps",0,ex,"useFloatingReference",0,eh,"useFloatingReferenceProps",0,eb,"useResolvedAnchor",0,eg],919751);var ew=e.i(140721),eO=e.i(942803),eP=e.i(233137),eC=e.i(233538),eM=((t=eM||{})[t.First=0]="First",t[t.Previous=1]="Previous",t[t.Next=2]="Next",t[t.Last=3]="Last",t[t.Specific=4]="Specific",t[t.Nothing=5]="Nothing",t);function eI(e,t){let n=t.resolveItems();if(n.length<=0)return null;let r=t.resolveActiveIndex(),o=null!=r?r:-1;switch(e.focus){case 0:for(let e=0;e=0;--e)if(!t.resolveDisabled(n[e],e,n))return e;return r;case 2:for(let e=o+1;e=0;--e)if(!t.resolveDisabled(n[e],e,n))return e;return r;case 4:for(let r=0;r()=>{},()=>!1,()=>!e)),[n,r]=u.useState(eN.env.isHandoffComplete);return n&&!1===eN.env.isHandoffComplete&&r(!1),u.useEffect(()=>{!0!==n&&r(!0)},[n]),u.useEffect(()=>eN.env.handoff(),[]),!t&&n}e.s(["useServerHandoffComplete",0,eB],178677);let eK=(0,u.createContext)(!1),e_=u.Fragment,eW=(0,eD.forwardRefWithAs)(function(e,t){let n,r,o=(0,u.useRef)(null),l=(0,K.useSyncRefs)((0,K.optionalRef)(e=>{o.current=e}),t),i=A(o),s=function(e){let t=(0,u.useContext)(eK),n=(0,u.useContext)(ej),r=A(e),[o,l]=(0,u.useState)(()=>{var e;if(!t&&null!==n)return null!=(e=n.current)?e:null;if(eN.env.isServer)return null;let o=null==r?void 0:r.getElementById("headlessui-portal-root");if(o)return o;if(null===r)return null;let l=r.createElement("div");return l.setAttribute("id","headlessui-portal-root"),r.body.appendChild(l)});return(0,u.useEffect)(()=>{null!==o&&(null!=r&&r.body.contains(o)||null==r||r.body.appendChild(o))},[o,r]),(0,u.useEffect)(()=>{t||null!==n&&l(n.current)},[n,l,t]),o}(o),[a]=(0,u.useState)(()=>{var e;return eN.env.isServer?null:null!=(e=null==i?void 0:i.createElement("div"))?e:null}),d=(0,u.useContext)(e$),f=eB();(0,m.useIsoMorphicEffect)(()=>{!s||!a||s.contains(a)||(a.setAttribute("data-headlessui-portal",""),s.appendChild(a))},[s,a]),(0,m.useIsoMorphicEffect)(()=>{if(a&&d)return d.register(a)},[d,a]),n=(0,h.useEvent)(()=>{var e;s&&a&&(a instanceof Node&&s.contains(a)&&s.removeChild(a),s.childNodes.length<=0&&(null==(e=s.parentElement)||e.removeChild(s)))}),r=(0,u.useRef)(!1),(0,u.useEffect)(()=>(r.current=!1,()=>{r.current=!0,(0,eH.microTask)(()=>{r.current&&n()})}),[n]);let p=(0,eD.useRender)();return f&&s&&a?(0,c.createPortal)(p({ourProps:{ref:l},theirProps:e,slot:{},defaultTag:e_,name:"Portal"}),a):null}),eV=u.Fragment,ej=(0,u.createContext)(null),e$=(0,u.createContext)(null),eU=Object.assign((0,eD.forwardRefWithAs)(function(e,t){let n=(0,K.useSyncRefs)(t),{enabled:r=!0,...o}=e,l=(0,eD.useRender)();return r?u.default.createElement(eW,{...o,ref:n}):l({ourProps:{ref:n},theirProps:o,slot:{},defaultTag:e_,name:"Portal"})}),{Group:(0,eD.forwardRefWithAs)(function(e,t){let{target:n,...r}=e,o={ref:(0,K.useSyncRefs)(t)},l=(0,eD.useRender)();return u.default.createElement(ej.Provider,{value:n},l({ourProps:o,theirProps:r,defaultTag:eV,name:"Popover.Group"}))})});e.s(["Portal",0,eU,"useNestedPortals",0,function(){let e=(0,u.useContext)(e$),t=(0,u.useRef)([]),n=(0,h.useEvent)(n=>(t.current.push(n),e&&e.register(n),()=>r(n))),r=(0,h.useEvent)(n=>{let r=t.current.indexOf(n);-1!==r&&t.current.splice(r,1),e&&e.unregister(n)}),o=(0,u.useMemo)(()=>({register:n,unregister:r,portals:t}),[n,r,t]);return[t,(0,u.useMemo)(()=>function({children:e}){return u.default.createElement(e$.Provider,{value:o},e)},[o])]}],635307);var ez=((n=ez||{})[n.Open=0]="Open",n[n.Closed=1]="Closed",n),eQ=((r=eQ||{})[r.Single=0]="Single",r[r.Multi=1]="Multi",r),eY=((o=eY||{})[o.Pointer=0]="Pointer",o[o.Other=1]="Other",o),eq=((l=eq||{})[l.OpenListbox=0]="OpenListbox",l[l.CloseListbox=1]="CloseListbox",l[l.GoToOption=2]="GoToOption",l[l.Search=3]="Search",l[l.ClearSearch=4]="ClearSearch",l[l.RegisterOption=5]="RegisterOption",l[l.UnregisterOption=6]="UnregisterOption",l[l.SetButtonElement=7]="SetButtonElement",l[l.SetOptionsElement=8]="SetOptionsElement",l);function eG(e,t=e=>e){let n=null!==e.activeOptionIndex?e.options[e.activeOptionIndex]:null,r=(0,L.sortByDomNode)(t(e.options.slice()),e=>e.dataRef.current.domRef.current),o=n?r.indexOf(n):null;return -1===o&&(o=null),{options:r,activeOptionIndex:o}}let eX={1:e=>e.dataRef.current.disabled||1===e.listboxState?e:{...e,activeOptionIndex:null,listboxState:1,__demoMode:!1},0(e){if(e.dataRef.current.disabled||0===e.listboxState)return e;let t=e.activeOptionIndex,{isSelected:n}=e.dataRef.current,r=e.options.findIndex(e=>n(e.dataRef.current.value));return -1!==r&&(t=r),{...e,listboxState:0,activeOptionIndex:t,__demoMode:!1}},2(e,t){var n,r,o,l,i;if(e.dataRef.current.disabled||1===e.listboxState)return e;let u={...e,searchQuery:"",activationTrigger:null!=(n=t.trigger)?n:1,__demoMode:!1};if(t.focus===eM.Nothing)return{...u,activeOptionIndex:null};if(t.focus===eM.Specific)return{...u,activeOptionIndex:e.options.findIndex(e=>e.id===t.id)};if(t.focus===eM.Previous){let n=e.activeOptionIndex;if(null!==n){let l=e.options[n].dataRef.current.domRef,i=eI(t,{resolveItems:()=>e.options,resolveActiveIndex:()=>e.activeOptionIndex,resolveId:e=>e.id,resolveDisabled:e=>e.dataRef.current.disabled});if(null!==i){let t=e.options[i].dataRef.current.domRef;if((null==(r=l.current)?void 0:r.previousElementSibling)===t.current||(null==(o=t.current)?void 0:o.previousElementSibling)===null)return{...u,activeOptionIndex:i}}}}else if(t.focus===eM.Next){let n=e.activeOptionIndex;if(null!==n){let r=e.options[n].dataRef.current.domRef,o=eI(t,{resolveItems:()=>e.options,resolveActiveIndex:()=>e.activeOptionIndex,resolveId:e=>e.id,resolveDisabled:e=>e.dataRef.current.disabled});if(null!==o){let t=e.options[o].dataRef.current.domRef;if((null==(l=r.current)?void 0:l.nextElementSibling)===t.current||(null==(i=t.current)?void 0:i.nextElementSibling)===null)return{...u,activeOptionIndex:o}}}}let s=eG(e),a=eI(t,{resolveItems:()=>s.options,resolveActiveIndex:()=>s.activeOptionIndex,resolveId:e=>e.id,resolveDisabled:e=>e.dataRef.current.disabled});return{...u,...s,activeOptionIndex:a}},3:(e,t)=>{if(e.dataRef.current.disabled||1===e.listboxState)return e;let n=+(""===e.searchQuery),r=e.searchQuery+t.value.toLowerCase(),o=(null!==e.activeOptionIndex?e.options.slice(e.activeOptionIndex+n).concat(e.options.slice(0,e.activeOptionIndex+n)):e.options).find(e=>{var t;return!e.dataRef.current.disabled&&(null==(t=e.dataRef.current.textValue)?void 0:t.startsWith(r))}),l=o?e.options.indexOf(o):-1;return -1===l||l===e.activeOptionIndex?{...e,searchQuery:r}:{...e,searchQuery:r,activeOptionIndex:l,activationTrigger:1}},4:e=>e.dataRef.current.disabled||1===e.listboxState||""===e.searchQuery?e:{...e,searchQuery:""},5:(e,t)=>{let n={id:t.id,dataRef:t.dataRef},r=eG(e,e=>[...e,n]);return null===e.activeOptionIndex&&e.dataRef.current.isSelected(t.dataRef.current.value)&&(r.activeOptionIndex=r.options.indexOf(n)),{...e,...r}},6:(e,t)=>{let n=eG(e,e=>{let n=e.findIndex(e=>e.id===t.id);return -1!==n&&e.splice(n,1),e});return{...e,...n,activationTrigger:1}},7:(e,t)=>e.buttonElement===t.element?e:{...e,buttonElement:t.element},8:(e,t)=>e.optionsElement===t.element?e:{...e,optionsElement:t.element}},eJ=(0,u.createContext)(null);function eZ(e){let t=(0,u.useContext)(eJ);if(null===t){let t=Error(`<${e} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,eZ),t}return t}eJ.displayName="ListboxActionsContext";let e0=(0,u.createContext)(null);function e1(e){let t=(0,u.useContext)(e0);if(null===t){let t=Error(`<${e} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,e1),t}return t}function e3(e,t){return(0,eT.match)(t.type,eX,e,t)}e0.displayName="ListboxDataContext";let e7=u.Fragment,e4=(0,u.createContext)(!1),e5=eD.RenderFeatures.RenderStrategy|eD.RenderFeatures.Static,e2=u.Fragment,e8=(0,eD.forwardRefWithAs)(function(e,t){var n;let r=(0,$.useDisabled)(),{value:o,defaultValue:l,form:i,name:s,onChange:a,by:c,invalid:d=!1,disabled:g=r||!1,horizontal:b=!1,multiple:x=!1,__demoMode:E=!1,...y}=e,S=b?"horizontal":"vertical",R=(0,K.useSyncRefs)(t),w=(0,p.useDefaultValue)(l),[O=x?[]:void 0,P]=(0,f.useControllable)(o,a,w),[C,M]=(0,u.useReducer)(e3,{dataRef:(0,u.createRef)(),listboxState:+!E,options:[],searchQuery:"",activeOptionIndex:null,activationTrigger:1,optionsVisible:!1,buttonElement:null,optionsElement:null,__demoMode:E}),I=(0,u.useRef)({static:!1,hold:!1}),T=(0,u.useRef)(new Map),D=function(e=function(e,t){return null!==e&&null!==t&&"object"==typeof e&&"object"==typeof t&&"id"in e&&"id"in t?e.id===t.id:e===t}){return(0,u.useCallback)((t,n)=>"string"==typeof e?(null==t?void 0:t[e])===(null==n?void 0:n[e]):e(t,n),[e])}(c),F=(0,u.useCallback)(e=>(0,eT.match)(A.mode,{1:()=>O.some(t=>D(t,e)),0:()=>D(O,e)}),[O]),A=(0,u.useMemo)(()=>({...C,value:O,disabled:g,invalid:d,mode:+!!x,orientation:S,compare:D,isSelected:F,optionsPropsRef:I,listRef:T}),[O,g,d,x,C,T]);(0,m.useIsoMorphicEffect)(()=>{C.dataRef.current=A},[A]),k(0===A.listboxState,[A.buttonElement,A.optionsElement],(e,t)=>{var n;M({type:1}),(0,L.isFocusableElement)(t,L.FocusableMode.Loose)||(e.preventDefault(),null==(n=A.buttonElement)||n.focus())});let H=(0,u.useMemo)(()=>({open:0===A.listboxState,disabled:g,invalid:d,value:O}),[A,g,O,d]),N=(0,h.useEvent)(e=>{let t=A.options.find(t=>t.id===e);t&&z(t.dataRef.current.value)}),B=(0,h.useEvent)(()=>{if(null!==A.activeOptionIndex){let{dataRef:e,id:t}=A.options[A.activeOptionIndex];z(e.current.value),M({type:2,focus:eM.Specific,id:t})}}),_=(0,h.useEvent)(()=>M({type:0})),W=(0,h.useEvent)(()=>M({type:1})),V=(0,v.useDisposables)(),j=(0,h.useEvent)((e,t,n)=>{V.dispose(),V.microTask(()=>e===eM.Specific?M({type:2,focus:eM.Specific,id:t,trigger:n}):M({type:2,focus:e,trigger:n}))}),U=(0,h.useEvent)((e,t)=>(M({type:5,id:e,dataRef:t}),()=>M({type:6,id:e}))),z=(0,h.useEvent)(e=>(0,eT.match)(A.mode,{0:()=>null==P?void 0:P(e),1(){let t=A.value.slice(),n=t.findIndex(t=>D(t,e));return -1===n?t.push(e):t.splice(n,1),null==P?void 0:P(t)}})),Q=(0,h.useEvent)(e=>M({type:3,value:e})),Y=(0,h.useEvent)(()=>M({type:4})),q=(0,h.useEvent)(e=>{M({type:7,element:e})}),G=(0,h.useEvent)(e=>{M({type:8,element:e})}),X=(0,u.useMemo)(()=>({onChange:z,registerOption:U,goToOption:j,closeListbox:W,openListbox:_,selectActiveOption:B,selectOption:N,search:Q,clearSearch:Y,setButtonElement:q,setOptionsElement:G}),[]),[J,Z]=(0,eA.useLabels)({inherit:!0}),ee=(0,u.useCallback)(()=>{if(void 0!==w)return null==P?void 0:P(w)},[P,w]),et=(0,eD.useRender)();return u.default.createElement(Z,{value:J,props:{htmlFor:null==(n=A.buttonElement)?void 0:n.id},slot:{open:0===A.listboxState,disabled:g}},u.default.createElement(ey,null,u.default.createElement(eJ.Provider,{value:X},u.default.createElement(e0.Provider,{value:A},u.default.createElement(eP.OpenClosedProvider,{value:(0,eT.match)(A.listboxState,{0:eP.State.Open,1:eP.State.Closed})},null!=s&&null!=O&&u.default.createElement(ew.FormFields,{disabled:g,data:{[s]:O},form:i,onReset:ee}),et({ourProps:{ref:R},theirProps:y,slot:H,defaultTag:e7,name:"Listbox"}))))))}),e9=(0,eD.forwardRefWithAs)(function(e,t){var n;let r=e1("Listbox.Button"),o=eZ("Listbox.Button"),l=(0,u.useId)(),i=(0,eO.useProvidedId)(),{id:f=i||`headlessui-listbox-button-${l}`,disabled:p=r.disabled||!1,autoFocus:m=!1,...v}=e,g=(0,K.useSyncRefs)(t,eh(),o.setButtonElement),b=eb(),x=(0,h.useEvent)(e=>{switch(e.key){case ek.Keys.Enter:(0,eL.attemptSubmit)(e.currentTarget);break;case ek.Keys.Space:case ek.Keys.ArrowDown:e.preventDefault(),(0,c.flushSync)(()=>o.openListbox()),r.value||o.goToOption(eM.First);break;case ek.Keys.ArrowUp:e.preventDefault(),(0,c.flushSync)(()=>o.openListbox()),r.value||o.goToOption(eM.Last)}}),E=(0,h.useEvent)(e=>{e.key===ek.Keys.Space&&e.preventDefault()}),y=(0,h.useEvent)(e=>{var t;if((0,eC.isDisabledReactIssue7711)(e.currentTarget))return e.preventDefault();0===r.listboxState?((0,c.flushSync)(()=>o.closeListbox()),null==(t=r.buttonElement)||t.focus({preventScroll:!0})):(e.preventDefault(),o.openListbox())}),S=(0,h.useEvent)(e=>e.preventDefault()),R=(0,eA.useLabelledBy)([f]),w=(0,eF.useDescribedBy)(),{isFocusVisible:O,focusProps:P}=(0,s.useFocusRing)({autoFocus:m}),{isHovered:C,hoverProps:M}=(0,a.useHover)({isDisabled:p}),{pressed:I,pressProps:L}=(0,d.useActivePress)({disabled:p}),T=(0,u.useMemo)(()=>({open:0===r.listboxState,active:I||0===r.listboxState,disabled:p,invalid:r.invalid,value:r.value,hover:C,focus:O,autofocus:m}),[r.listboxState,r.value,p,C,O,I,r.invalid,m]),D=(0,eD.mergeProps)(b(),{ref:g,id:f,type:(0,H.useResolveButtonType)(e,r.buttonElement),"aria-haspopup":"listbox","aria-controls":null==(n=r.optionsElement)?void 0:n.id,"aria-expanded":0===r.listboxState,"aria-labelledby":R,"aria-describedby":w,disabled:p||void 0,autoFocus:m,onKeyDown:x,onKeyUp:E,onKeyPress:S,onClick:y},P,M,L);return(0,eD.useRender)()({ourProps:D,theirProps:v,slot:T,defaultTag:"button",name:"Listbox.Button"})}),e6=eA.Label,te=(0,eD.forwardRefWithAs)(function(e,t){var n,r;let o=(0,u.useId)(),{id:l=`headlessui-listbox-options-${o}`,anchor:i,portal:s=!1,modal:a=!0,transition:d=!1,...f}=e,p=eg(i),[E,y]=(0,u.useState)(null);p&&(s=!0);let S=e1("Listbox.Options"),R=eZ("Listbox.Options"),O=A(S.optionsElement),P=(0,eP.useOpenClosed)(),[M,T]=(0,j.useTransition)(d,E,null!==P?(P&eP.State.Open)===eP.State.Open:0===S.listboxState);I(M,S.buttonElement,R.closeListbox),B(!S.__demoMode&&a&&0===S.listboxState,O),function(e,{allowed:t,disallowed:n}={}){let r=w(e,"inert-others");(0,m.useIsoMorphicEffect)(()=>{var e,o;if(!r)return;let l=(0,b.disposables)();for(let t of null!=(e=null==n?void 0:n())?e:[])t&&l.add(C(t));let i=null!=(o=null==t?void 0:t())?o:[];for(let e of i){if(!e)continue;let t=(0,x.getOwnerDocument)(e);if(!t)continue;let n=e.parentElement;for(;n&&n!==t.body;){for(let e of n.children)i.some(t=>e.contains(t))||l.add(C(e));n=n.parentElement}}return l.dispose},[r,t,n])}(!S.__demoMode&&a&&0===S.listboxState,{allowed:(0,u.useCallback)(()=>[S.buttonElement,S.optionsElement],[S.buttonElement,S.optionsElement])});let D=!function(e,t){let n=(0,u.useRef)({left:0,top:0});if((0,m.useIsoMorphicEffect)(()=>{if(!t)return;let e=t.getBoundingClientRect();e&&(n.current=e)},[e,t]),null==t||!e||t===document.activeElement)return!1;let r=t.getBoundingClientRect();return r.top!==n.current.top||r.left!==n.current.left}(0!==S.listboxState,S.buttonElement)&&M,F=function(e,t){let[n,r]=(0,u.useState)(t);return e||n===t||r(t),e?n:t}(M&&1===S.listboxState,S.value),k=(0,h.useEvent)(e=>S.compare(F,e)),H=(0,u.useMemo)(()=>{var e;if(null==p||!(null!=(e=null==p?void 0:p.to)&&e.includes("selection")))return null;let t=S.options.findIndex(e=>k(e.dataRef.current.value));return -1===t&&(t=0),t},[p,S.options]),[N,_]=eE((()=>{if(null==p)return;if(null===H)return{...p,inner:void 0};let e=Array.from(S.listRef.current.values());return{...p,inner:{listRef:{current:e},index:H}}})()),W=ex(),V=(0,K.useSyncRefs)(t,p?N:null,R.setOptionsElement,y),$=(0,v.useDisposables)();(0,u.useEffect)(()=>{var e;let t=S.optionsElement;t&&0===S.listboxState&&t!==(null==(e=(0,x.getOwnerDocument)(t))?void 0:e.activeElement)&&(null==t||t.focus({preventScroll:!0}))},[S.listboxState,S.optionsElement]);let U=(0,h.useEvent)(e=>{var t,n;switch($.dispose(),e.key){case ek.Keys.Space:if(""!==S.searchQuery)return e.preventDefault(),e.stopPropagation(),R.search(e.key);case ek.Keys.Enter:if(e.preventDefault(),e.stopPropagation(),null!==S.activeOptionIndex){let{dataRef:e}=S.options[S.activeOptionIndex];R.onChange(e.current.value)}0===S.mode&&((0,c.flushSync)(()=>R.closeListbox()),null==(t=S.buttonElement)||t.focus({preventScroll:!0}));break;case(0,eT.match)(S.orientation,{vertical:ek.Keys.ArrowDown,horizontal:ek.Keys.ArrowRight}):return e.preventDefault(),e.stopPropagation(),R.goToOption(eM.Next);case(0,eT.match)(S.orientation,{vertical:ek.Keys.ArrowUp,horizontal:ek.Keys.ArrowLeft}):return e.preventDefault(),e.stopPropagation(),R.goToOption(eM.Previous);case ek.Keys.Home:case ek.Keys.PageUp:return e.preventDefault(),e.stopPropagation(),R.goToOption(eM.First);case ek.Keys.End:case ek.Keys.PageDown:return e.preventDefault(),e.stopPropagation(),R.goToOption(eM.Last);case ek.Keys.Escape:e.preventDefault(),e.stopPropagation(),(0,c.flushSync)(()=>R.closeListbox()),null==(n=S.buttonElement)||n.focus({preventScroll:!0});return;case ek.Keys.Tab:e.preventDefault(),e.stopPropagation(),(0,c.flushSync)(()=>R.closeListbox()),(0,L.focusFrom)(S.buttonElement,e.shiftKey?L.Focus.Previous:L.Focus.Next);break;default:1===e.key.length&&(R.search(e.key),$.setTimeout(()=>R.clearSearch(),350))}}),z=null==(n=S.buttonElement)?void 0:n.id,Q=(0,u.useMemo)(()=>({open:0===S.listboxState}),[S.listboxState]),Y=(0,eD.mergeProps)(p?W():{},{id:l,ref:V,"aria-activedescendant":null===S.activeOptionIndex||null==(r=S.options[S.activeOptionIndex])?void 0:r.id,"aria-multiselectable":1===S.mode||void 0,"aria-labelledby":z,"aria-orientation":S.orientation,onKeyDown:U,role:"listbox",tabIndex:0===S.listboxState?0:void 0,style:{...f.style,..._,"--button-width":g(S.buttonElement,!0).width},...(0,j.transitionDataAttributes)(T)}),q=(0,eD.useRender)();return u.default.createElement(eU,{enabled:!!s&&(e.static||M)},u.default.createElement(e0.Provider,{value:1===S.mode?S:{...S,isSelected:k}},q({ourProps:Y,theirProps:f,slot:Q,defaultTag:"div",features:e5,visible:D,name:"Listbox.Options"})))}),tt=(0,eD.forwardRefWithAs)(function(e,t){let n,r,o,l=(0,u.useId)(),{id:i=`headlessui-listbox-option-${l}`,disabled:s=!1,value:a,...d}=e,f=!0===(0,u.useContext)(e4),p=e1("Listbox.Option"),v=eZ("Listbox.Option"),g=null!==p.activeOptionIndex&&p.options[p.activeOptionIndex].id===i,x=p.isSelected(a),E=(0,u.useRef)(null),y=(n=(0,u.useRef)(""),r=(0,u.useRef)(""),(0,h.useEvent)(()=>{let e=E.current;if(!e)return"";let t=e.innerText;if(n.current===t)return r.current;let o=(function(e){let t=e.getAttribute("aria-label");if("string"==typeof t)return t.trim();let n=e.getAttribute("aria-labelledby");if(n){let e=n.split(" ").map(e=>{let t=document.getElementById(e);if(t){let e=t.getAttribute("aria-label");return"string"==typeof e?e.trim():W(t).trim()}return null}).filter(Boolean);if(e.length>0)return e.join(", ")}return W(e).trim()})(e).trim().toLowerCase();return n.current=t,r.current=o,o})),S=(0,M.useLatestValue)({disabled:s,value:a,domRef:E,get textValue(){return y()}}),R=(0,K.useSyncRefs)(t,E,e=>{e?p.listRef.current.set(i,e):p.listRef.current.delete(i)});(0,m.useIsoMorphicEffect)(()=>{if(!p.__demoMode&&0===p.listboxState&&g&&0!==p.activationTrigger)return(0,b.disposables)().requestAnimationFrame(()=>{var e,t;null==(t=null==(e=E.current)?void 0:e.scrollIntoView)||t.call(e,{block:"nearest"})})},[E,g,p.__demoMode,p.listboxState,p.activationTrigger,p.activeOptionIndex]),(0,m.useIsoMorphicEffect)(()=>{if(!f)return v.registerOption(i,S)},[S,i,f]);let w=(0,h.useEvent)(e=>{var t;if(s)return e.preventDefault();v.onChange(a),0===p.mode&&((0,c.flushSync)(()=>v.closeListbox()),null==(t=p.buttonElement)||t.focus({preventScroll:!0}))}),O=(0,h.useEvent)(()=>{if(s)return v.goToOption(eM.Nothing);v.goToOption(eM.Specific,i)}),P=(o=(0,u.useRef)([-1,-1]),{wasMoved(e){let t=V(e);return(o.current[0]!==t[0]||o.current[1]!==t[1])&&(o.current=t,!0)},update(e){o.current=V(e)}}),C=(0,h.useEvent)(e=>{P.update(e),!s&&(g||v.goToOption(eM.Specific,i,0))}),I=(0,h.useEvent)(e=>{P.wasMoved(e)&&(s||g||v.goToOption(eM.Specific,i,0))}),L=(0,h.useEvent)(e=>{P.wasMoved(e)&&(s||g&&v.goToOption(eM.Nothing))}),T=(0,u.useMemo)(()=>({active:g,focus:g,selected:x,disabled:s,selectedOption:x&&f}),[g,x,s,f]),D=f?{}:{id:i,ref:R,role:"option",tabIndex:!0===s?void 0:-1,"aria-disabled":!0===s||void 0,"aria-selected":x,disabled:void 0,onClick:w,onFocus:O,onPointerEnter:C,onMouseEnter:C,onPointerMove:I,onMouseMove:I,onPointerLeave:L,onMouseLeave:L},F=(0,eD.useRender)();return!x&&f?null:F({ourProps:D,theirProps:d,slot:T,defaultTag:"div",name:"Listbox.Option"})}),tn=Object.assign(e8,{Button:e9,Label:e6,Options:te,Option:tt,SelectedOption:(0,eD.forwardRefWithAs)(function(e,t){let{options:n,placeholder:r,...o}=e,l={ref:(0,K.useSyncRefs)(t)},i=e1("ListboxSelectedOption"),s=(0,u.useMemo)(()=>({}),[]),a=void 0===i.value||null===i.value||1===i.mode&&Array.isArray(i.value)&&0===i.value.length,c=(0,eD.useRender)();return u.default.createElement(e4.Provider,{value:!0},c({ourProps:l,theirProps:{...o,children:u.default.createElement(u.default.Fragment,null,r&&a?r:n)},slot:s,defaultTag:e2,name:"ListboxSelectedOption"}))})});e.s(["Listbox",0,tn,"ListboxButton",0,e9,"ListboxOption",0,tt,"ListboxOptions",0,te],495470);var tr=e.i(444755);let to=(0,e.i(673706).makeClassName)("SelectItem"),tl=u.default.forwardRef((e,t)=>{let{value:n,icon:r,className:o,children:l}=e,s=(0,i.__rest)(e,["value","icon","className","children"]);return u.default.createElement(tt,Object.assign({className:(0,tr.tremorTwMerge)(to("root"),"flex justify-start items-center cursor-default text-tremor-default px-2.5 py-2.5","data-[focus]:bg-tremor-background-muted data-[focus]:text-tremor-content-strong data-[selected]:text-tremor-content-strong data-[selected]:bg-tremor-background-muted text-tremor-content-emphasis","dark:data-[focus]:bg-dark-tremor-background-muted dark:data-[focus]:text-dark-tremor-content-strong dark:data-[selected]:text-dark-tremor-content-strong dark:data-[selected]:bg-dark-tremor-background-muted dark:text-dark-tremor-content-emphasis",o),ref:t,key:n,value:n},s),r&&u.default.createElement(r,{className:(0,tr.tremorTwMerge)(to("icon"),"flex-none w-5 h-5 mr-1.5","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle")}),u.default.createElement("span",{className:"whitespace-nowrap truncate"},null!=l?l:n))});tl.displayName="SelectItem",e.s(["default",0,tl],333771),e.s(["SelectItem",0,tl],35983)}]); \ No newline at end of file diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0qd74dcl8o._1.js b/litellm/proxy/_experimental/out/_next/static/chunks/0qd74dcl8o._1.js new file mode 100644 index 00000000000..8f455d4fdd1 --- /dev/null +++ b/litellm/proxy/_experimental/out/_next/static/chunks/0qd74dcl8o._1.js @@ -0,0 +1,2 @@ +(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,184163,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M505.7 661a8 8 0 0012.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"}}]},name:"download",theme:"outlined"};var i=e.i(9583),s=r.forwardRef(function(e,s){return r.createElement(i.default,(0,t.default)({},e,{ref:s,icon:n}))});e.s(["default",0,s],184163)},309821,e=>{"use strict";e.i(247167);var t=e.i(271645),r=e.i(135551),n=e.i(201072),i=e.i(121229),s=e.i(726289),l=e.i(864517),a=e.i(343794),o=e.i(529681),c=e.i(242064),u=e.i(931067),d=e.i(209428),m=e.i(703923),f={percent:0,prefixCls:"rc-progress",strokeColor:"#2db7f5",strokeLinecap:"round",strokeWidth:1,trailColor:"#D9D9D9",trailWidth:1,gapPosition:"bottom"},p=function(){var e=(0,t.useRef)([]),r=(0,t.useRef)(null);return(0,t.useEffect)(function(){var t=Date.now(),n=!1;e.current.forEach(function(e){if(e){n=!0;var i=e.style;i.transitionDuration=".3s, .3s, .3s, .06s",r.current&&t-r.current<100&&(i.transitionDuration="0s, 0s")}}),n&&(r.current=Date.now())}),e.current},h=e.i(410160),g=e.i(392221),x=e.i(654310),v=0,y=(0,x.default)();let b=function(e){var r=t.useState(),n=(0,g.default)(r,2),i=n[0],s=n[1];return t.useEffect(function(){var e;s("rc_progress_".concat((y?(e=v,v+=1):e="TEST_OR_SSR",e)))},[]),e||i};var _=function(e){var r=e.bg,n=e.children;return t.createElement("div",{style:{width:"100%",height:"100%",background:r}},n)};function w(e,t){return Object.keys(e).map(function(r){var n=parseFloat(r),i="".concat(Math.floor(n*t),"%");return"".concat(e[r]," ").concat(i)})}var j=t.forwardRef(function(e,r){var n=e.prefixCls,i=e.color,s=e.gradientId,l=e.radius,a=e.style,o=e.ptg,c=e.strokeLinecap,u=e.strokeWidth,d=e.size,m=e.gapDegree,f=i&&"object"===(0,h.default)(i),p=d/2,g=t.createElement("circle",{className:"".concat(n,"-circle-path"),r:l,cx:p,cy:p,stroke:f?"#FFF":void 0,strokeLinecap:c,strokeWidth:u,opacity:+(0!==o),style:a,ref:r});if(!f)return g;var x="".concat(s,"-conic"),v=w(i,(360-m)/360),y=w(i,1),b="conic-gradient(from ".concat(m?"".concat(180+m/2,"deg"):"0deg",", ").concat(v.join(", "),")"),j="linear-gradient(to ".concat(m?"bottom":"top",", ").concat(y.join(", "),")");return t.createElement(t.Fragment,null,t.createElement("mask",{id:x},g),t.createElement("foreignObject",{x:0,y:0,width:d,height:d,mask:"url(#".concat(x,")")},t.createElement(_,{bg:j},t.createElement(_,{bg:b}))))}),C=function(e,t,r,n,i,s,l,a,o,c){var u=arguments.length>10&&void 0!==arguments[10]?arguments[10]:0,d=(100-n)/100*t;return"round"===o&&100!==n&&(d+=c/2)>=t&&(d=t-.01),{stroke:"string"==typeof a?a:void 0,strokeDasharray:"".concat(t,"px ").concat(e),strokeDashoffset:d+u,transform:"rotate(".concat(i+r/100*360*((360-s)/360)+(0===s?0:({bottom:0,top:180,left:90,right:-90})[l]),"deg)"),transformOrigin:"".concat(50,"px ").concat(50,"px"),transition:"stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s",fillOpacity:0}},k=["id","prefixCls","steps","strokeWidth","trailWidth","gapDegree","gapPosition","trailColor","strokeLinecap","style","className","strokeColor","percent"];function S(e){var t=null!=e?e:[];return Array.isArray(t)?t:[t]}let E=function(e){var r,n,i,s,l=(0,d.default)((0,d.default)({},f),e),o=l.id,c=l.prefixCls,g=l.steps,x=l.strokeWidth,v=l.trailWidth,y=l.gapDegree,_=void 0===y?0:y,w=l.gapPosition,E=l.trailColor,O=l.strokeLinecap,N=l.style,I=l.className,T=l.strokeColor,R=l.percent,P=(0,m.default)(l,k),$=b(o),D="".concat($,"-gradient"),A=50-x/2,F=2*Math.PI*A,L=_>0?90+_/2:-90,M=(360-_)/360*F,B="object"===(0,h.default)(g)?g:{count:g,gap:2},U=B.count,z=B.gap,V=S(R),W=S(T),H=W.find(function(e){return e&&"object"===(0,h.default)(e)}),K=H&&"object"===(0,h.default)(H)?"butt":O,q=C(F,M,0,100,L,_,w,E,K,x),X=p();return t.createElement("svg",(0,u.default)({className:(0,a.default)("".concat(c,"-circle"),I),viewBox:"0 0 ".concat(100," ").concat(100),style:N,id:o,role:"presentation"},P),!U&&t.createElement("circle",{className:"".concat(c,"-circle-trail"),r:A,cx:50,cy:50,stroke:E,strokeLinecap:K,strokeWidth:v||x,style:q}),U?(r=Math.round(U*(V[0]/100)),n=100/U,i=0,Array(U).fill(null).map(function(e,s){var l=s<=r-1?W[0]:E,a=l&&"object"===(0,h.default)(l)?"url(#".concat(D,")"):void 0,o=C(F,M,i,n,L,_,w,l,"butt",x,z);return i+=(M-o.strokeDashoffset+z)*100/M,t.createElement("circle",{key:s,className:"".concat(c,"-circle-path"),r:A,cx:50,cy:50,stroke:a,strokeWidth:x,opacity:1,style:o,ref:function(e){X[s]=e}})})):(s=0,V.map(function(e,r){var n=W[r]||W[W.length-1],i=C(F,M,s,e,L,_,w,n,K,x);return s+=e,t.createElement(j,{key:r,color:n,ptg:e,radius:A,prefixCls:c,gradientId:D,style:i,strokeLinecap:K,strokeWidth:x,gapDegree:_,ref:function(e){X[r]=e},size:100})}).reverse()))};var O=e.i(491816);e.i(765846);var N=e.i(896091);function I(e){return!e||e<0?0:e>100?100:e}function T({success:e,successPercent:t}){let r=t;return e&&"progress"in e&&(r=e.progress),e&&"percent"in e&&(r=e.percent),r}let R=(e,t,r)=>{var n,i,s,l;let a=-1,o=-1;if("step"===t){let t=r.steps,n=r.strokeWidth;"string"==typeof e||void 0===e?(a="small"===e?2:14,o=null!=n?n:8):"number"==typeof e?[a,o]=[e,e]:[a=14,o=8]=Array.isArray(e)?e:[e.width,e.height],a*=t}else if("line"===t){let t=null==r?void 0:r.strokeWidth;"string"==typeof e||void 0===e?o=t||("small"===e?6:8):"number"==typeof e?[a,o]=[e,e]:[a=-1,o=8]=Array.isArray(e)?e:[e.width,e.height]}else("circle"===t||"dashboard"===t)&&("string"==typeof e||void 0===e?[a,o]="small"===e?[60,60]:[120,120]:"number"==typeof e?[a,o]=[e,e]:Array.isArray(e)&&(a=null!=(i=null!=(n=e[0])?n:e[1])?i:120,o=null!=(l=null!=(s=e[0])?s:e[1])?l:120));return[a,o]},P=e=>{let{prefixCls:r,trailColor:n=null,strokeLinecap:i="round",gapPosition:s,gapDegree:l,width:o=120,type:c,children:u,success:d,size:m=o,steps:f}=e,[p,h]=R(m,"circle"),{strokeWidth:g}=e;void 0===g&&(g=Math.max(3/p*100,6));let x=t.useMemo(()=>l||0===l?l:"dashboard"===c?75:void 0,[l,c]),v=(({percent:e,success:t,successPercent:r})=>{let n=I(T({success:t,successPercent:r}));return[n,I(I(e)-n)]})(e),y="[object Object]"===Object.prototype.toString.call(e.strokeColor),b=(({success:e={},strokeColor:t})=>{let{strokeColor:r}=e;return[r||N.presetPrimaryColors.green,t||null]})({success:d,strokeColor:e.strokeColor}),_=(0,a.default)(`${r}-inner`,{[`${r}-circle-gradient`]:y}),w=t.createElement(E,{steps:f,percent:f?v[1]:v,strokeWidth:g,trailWidth:g,strokeColor:f?b[1]:b,strokeLinecap:i,trailColor:n,prefixCls:r,gapDegree:x,gapPosition:s||"dashboard"===c&&"bottom"||void 0}),j=p<=20,C=t.createElement("div",{className:_,style:{width:p,height:h,fontSize:.15*p+6}},w,!j&&u);return j?t.createElement(O.default,{title:u},C):C};e.i(296059);var $=e.i(694758),D=e.i(915654),A=e.i(183293),F=e.i(246422),L=e.i(838378);let M="--progress-line-stroke-color",B="--progress-percent",U=e=>{let t=e?"100%":"-100%";return new $.Keyframes(`antProgress${e?"RTL":"LTR"}Active`,{"0%":{transform:`translateX(${t}) scaleX(0)`,opacity:.1},"20%":{transform:`translateX(${t}) scaleX(0)`,opacity:.5},to:{transform:"translateX(0) scaleX(1)",opacity:0}})},z=(0,F.genStyleHooks)("Progress",e=>{let t=e.calc(e.marginXXS).div(2).equal(),r=(0,L.mergeToken)(e,{progressStepMarginInlineEnd:t,progressStepMinWidth:t,progressActiveMotionDuration:"2.4s"});return[(e=>{let{componentCls:t,iconCls:r}=e;return{[t]:Object.assign(Object.assign({},(0,A.resetComponent)(e)),{display:"inline-block","&-rtl":{direction:"rtl"},"&-line":{position:"relative",width:"100%",fontSize:e.fontSize},[`${t}-outer`]:{display:"inline-flex",alignItems:"center",width:"100%"},[`${t}-inner`]:{position:"relative",display:"inline-block",width:"100%",flex:1,overflow:"hidden",verticalAlign:"middle",backgroundColor:e.remainingColor,borderRadius:e.lineBorderRadius},[`${t}-inner:not(${t}-circle-gradient)`]:{[`${t}-circle-path`]:{stroke:e.defaultColor}},[`${t}-success-bg, ${t}-bg`]:{position:"relative",background:e.defaultColor,borderRadius:e.lineBorderRadius,transition:`all ${e.motionDurationSlow} ${e.motionEaseInOutCirc}`},[`${t}-layout-bottom`]:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",[`${t}-text`]:{width:"max-content",marginInlineStart:0,marginTop:e.marginXXS}},[`${t}-bg`]:{overflow:"hidden","&::after":{content:'""',background:{_multi_value_:!0,value:["inherit",`var(${M})`]},height:"100%",width:`calc(1 / var(${B}) * 100%)`,display:"block"},[`&${t}-bg-inner`]:{minWidth:"max-content","&::after":{content:"none"},[`${t}-text-inner`]:{color:e.colorWhite,[`&${t}-text-bright`]:{color:"rgba(0, 0, 0, 0.45)"}}}},[`${t}-success-bg`]:{position:"absolute",insetBlockStart:0,insetInlineStart:0,backgroundColor:e.colorSuccess},[`${t}-text`]:{display:"inline-block",marginInlineStart:e.marginXS,color:e.colorText,lineHeight:1,width:"2em",whiteSpace:"nowrap",textAlign:"start",verticalAlign:"middle",wordBreak:"normal",[r]:{fontSize:e.fontSize},[`&${t}-text-outer`]:{width:"max-content"},[`&${t}-text-outer${t}-text-start`]:{width:"max-content",marginInlineStart:0,marginInlineEnd:e.marginXS}},[`${t}-text-inner`]:{display:"flex",justifyContent:"center",alignItems:"center",width:"100%",height:"100%",marginInlineStart:0,padding:`0 ${(0,D.unit)(e.paddingXXS)}`,[`&${t}-text-start`]:{justifyContent:"start"},[`&${t}-text-end`]:{justifyContent:"end"}},[`&${t}-status-active`]:{[`${t}-bg::before`]:{position:"absolute",inset:0,backgroundColor:e.colorBgContainer,borderRadius:e.lineBorderRadius,opacity:0,animationName:U(),animationDuration:e.progressActiveMotionDuration,animationTimingFunction:e.motionEaseOutQuint,animationIterationCount:"infinite",content:'""'}},[`&${t}-rtl${t}-status-active`]:{[`${t}-bg::before`]:{animationName:U(!0)}},[`&${t}-status-exception`]:{[`${t}-bg`]:{backgroundColor:e.colorError},[`${t}-text`]:{color:e.colorError}},[`&${t}-status-exception ${t}-inner:not(${t}-circle-gradient)`]:{[`${t}-circle-path`]:{stroke:e.colorError}},[`&${t}-status-success`]:{[`${t}-bg`]:{backgroundColor:e.colorSuccess},[`${t}-text`]:{color:e.colorSuccess}},[`&${t}-status-success ${t}-inner:not(${t}-circle-gradient)`]:{[`${t}-circle-path`]:{stroke:e.colorSuccess}}})}})(r),(e=>{let{componentCls:t,iconCls:r}=e;return{[t]:{[`${t}-circle-trail`]:{stroke:e.remainingColor},[`&${t}-circle ${t}-inner`]:{position:"relative",lineHeight:1,backgroundColor:"transparent"},[`&${t}-circle ${t}-text`]:{position:"absolute",insetBlockStart:"50%",insetInlineStart:0,width:"100%",margin:0,padding:0,color:e.circleTextColor,fontSize:e.circleTextFontSize,lineHeight:1,whiteSpace:"normal",textAlign:"center",transform:"translateY(-50%)",[r]:{fontSize:e.circleIconFontSize}},[`${t}-circle&-status-exception`]:{[`${t}-text`]:{color:e.colorError}},[`${t}-circle&-status-success`]:{[`${t}-text`]:{color:e.colorSuccess}}},[`${t}-inline-circle`]:{lineHeight:1,[`${t}-inner`]:{verticalAlign:"bottom"}}}})(r),(e=>{let{componentCls:t}=e;return{[t]:{[`${t}-steps`]:{display:"inline-block","&-outer":{display:"flex",flexDirection:"row",alignItems:"center"},"&-item":{flexShrink:0,minWidth:e.progressStepMinWidth,marginInlineEnd:e.progressStepMarginInlineEnd,backgroundColor:e.remainingColor,transition:`all ${e.motionDurationSlow}`,"&-active":{backgroundColor:e.defaultColor}}}}}})(r),(e=>{let{componentCls:t,iconCls:r}=e;return{[t]:{[`${t}-small&-line, ${t}-small&-line ${t}-text ${r}`]:{fontSize:e.fontSizeSM}}}})(r)]},e=>({circleTextColor:e.colorText,defaultColor:e.colorInfo,remainingColor:e.colorFillSecondary,lineBorderRadius:100,circleTextFontSize:"1em",circleIconFontSize:`${e.fontSize/e.fontSizeSM}em`}));var V=function(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&0>t.indexOf(n)&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,n=Object.getOwnPropertySymbols(e);it.indexOf(n[i])&&Object.prototype.propertyIsEnumerable.call(e,n[i])&&(r[n[i]]=e[n[i]]);return r};let W=e=>{let{prefixCls:r,direction:n,percent:i,size:s,strokeWidth:l,strokeColor:o,strokeLinecap:c="round",children:u,trailColor:d=null,percentPosition:m,success:f}=e,{align:p,type:h}=m,g=o&&"string"!=typeof o?((e,t)=>{let{from:r=N.presetPrimaryColors.blue,to:n=N.presetPrimaryColors.blue,direction:i="rtl"===t?"to left":"to right"}=e,s=V(e,["from","to","direction"]);if(0!==Object.keys(s).length){let e,t=(e=[],Object.keys(s).forEach(t=>{let r=Number.parseFloat(t.replace(/%/g,""));Number.isNaN(r)||e.push({key:r,value:s[t]})}),(e=e.sort((e,t)=>e.key-t.key)).map(({key:e,value:t})=>`${t} ${e}%`).join(", ")),r=`linear-gradient(${i}, ${t})`;return{background:r,[M]:r}}let l=`linear-gradient(${i}, ${r}, ${n})`;return{background:l,[M]:l}})(o,n):{[M]:o,background:o},x="square"===c||"butt"===c?0:void 0,[v,y]=R(null!=s?s:[-1,l||("small"===s?6:8)],"line",{strokeWidth:l}),b=Object.assign(Object.assign({width:`${I(i)}%`,height:y,borderRadius:x},g),{[B]:I(i)/100}),_=T(e),w={width:`${I(_)}%`,height:y,borderRadius:x,backgroundColor:null==f?void 0:f.strokeColor},j=t.createElement("div",{className:`${r}-inner`,style:{backgroundColor:d||void 0,borderRadius:x}},t.createElement("div",{className:(0,a.default)(`${r}-bg`,`${r}-bg-${h}`),style:b},"inner"===h&&u),void 0!==_&&t.createElement("div",{className:`${r}-success-bg`,style:w})),C="outer"===h&&"start"===p,k="outer"===h&&"end"===p;return"outer"===h&&"center"===p?t.createElement("div",{className:`${r}-layout-bottom`},j,u):t.createElement("div",{className:`${r}-outer`,style:{width:v<0?"100%":v}},C&&u,j,k&&u)},H=e=>{let{size:r,steps:n,rounding:i=Math.round,percent:s=0,strokeWidth:l=8,strokeColor:o,trailColor:c=null,prefixCls:u,children:d}=e,m=i(s/100*n),[f,p]=R(null!=r?r:["small"===r?2:14,l],"step",{steps:n,strokeWidth:l}),h=f/n,g=Array.from({length:n});for(let e=0;et.indexOf(n)&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,n=Object.getOwnPropertySymbols(e);it.indexOf(n[i])&&Object.prototype.propertyIsEnumerable.call(e,n[i])&&(r[n[i]]=e[n[i]]);return r};let q=["normal","exception","active","success"],X=t.forwardRef((e,u)=>{let d,{prefixCls:m,className:f,rootClassName:p,steps:h,strokeColor:g,percent:x=0,size:v="default",showInfo:y=!0,type:b="line",status:_,format:w,style:j,percentPosition:C={}}=e,k=K(e,["prefixCls","className","rootClassName","steps","strokeColor","percent","size","showInfo","type","status","format","style","percentPosition"]),{align:S="end",type:E="outer"}=C,O=Array.isArray(g)?g[0]:g,N="string"==typeof g||Array.isArray(g)?g:void 0,$=t.useMemo(()=>{if(O){let e="string"==typeof O?O:Object.values(O)[0];return new r.FastColor(e).isLight()}return!1},[g]),D=t.useMemo(()=>{var t,r;let n=T(e);return Number.parseInt(void 0!==n?null==(t=null!=n?n:0)?void 0:t.toString():null==(r=null!=x?x:0)?void 0:r.toString(),10)},[x,e.success,e.successPercent]),A=t.useMemo(()=>!q.includes(_)&&D>=100?"success":_||"normal",[_,D]),{getPrefixCls:F,direction:L,progress:M}=t.useContext(c.ConfigContext),B=F("progress",m),[U,V,X]=z(B),Q="line"===b,G=Q&&!h,J=t.useMemo(()=>{let r;if(!y)return null;let o=T(e),c=w||(e=>`${e}%`),u=Q&&$&&"inner"===E;return"inner"===E||w||"exception"!==A&&"success"!==A?r=c(I(x),I(o)):"exception"===A?r=Q?t.createElement(s.default,null):t.createElement(l.default,null):"success"===A&&(r=Q?t.createElement(n.default,null):t.createElement(i.default,null)),t.createElement("span",{className:(0,a.default)(`${B}-text`,{[`${B}-text-bright`]:u,[`${B}-text-${S}`]:G,[`${B}-text-${E}`]:G}),title:"string"==typeof r?r:void 0},r)},[y,x,D,A,b,B,w]);"line"===b?d=h?t.createElement(H,Object.assign({},e,{strokeColor:N,prefixCls:B,steps:"object"==typeof h?h.count:h}),J):t.createElement(W,Object.assign({},e,{strokeColor:O,prefixCls:B,direction:L,percentPosition:{align:S,type:E}}),J):("circle"===b||"dashboard"===b)&&(d=t.createElement(P,Object.assign({},e,{strokeColor:O,prefixCls:B,progressStatus:A}),J));let Y=(0,a.default)(B,`${B}-status-${A}`,{[`${B}-${"dashboard"===b&&"circle"||b}`]:"line"!==b,[`${B}-inline-circle`]:"circle"===b&&R(v,"circle")[0]<=20,[`${B}-line`]:G,[`${B}-line-align-${S}`]:G,[`${B}-line-position-${E}`]:G,[`${B}-steps`]:h,[`${B}-show-info`]:y,[`${B}-${v}`]:"string"==typeof v,[`${B}-rtl`]:"rtl"===L},null==M?void 0:M.className,f,p,V,X);return U(t.createElement("div",Object.assign({ref:u,style:Object.assign(Object.assign({},null==M?void 0:M.style),j),className:Y,role:"progressbar","aria-valuenow":D,"aria-valuemin":0,"aria-valuemax":100},(0,o.default)(k,["trailColor","strokeWidth","width","gapDegree","gapPosition","strokeLinecap","success","successPercent"])),d))});e.s(["default",0,X],309821)},519756,e=>{"use strict";e.i(247167);var t=e.i(931067),r=e.i(271645);let n={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M400 317.7h73.9V656c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V317.7H624c6.7 0 10.4-7.7 6.3-12.9L518.3 163a8 8 0 00-12.6 0l-112 141.7c-4.1 5.3-.4 13 6.3 13zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"}}]},name:"upload",theme:"outlined"};var i=e.i(9583),s=r.forwardRef(function(e,s){return r.createElement(i.default,(0,t.default)({},e,{ref:s,icon:n}))});e.s(["UploadOutlined",0,s],519756)},743151,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.CopyToClipboard=void 0;var n=l(e.r(844343)),i=l(e.r(271645)),s=["text","onCopy","options","children"];function l(e){return e&&e.__esModule?e:{default:e}}function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function c(e){for(var t=1;t{"use strict";var n=e.r(743151).CopyToClipboard;n.CopyToClipboard=n,t.exports=n},988297,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 4v16m8-8H4"}))});e.s(["PlusIcon",0,r],988297)},233538,e=>{"use strict";e.s(["isDisabledReactIssue7711",0,function(e){let t=e.parentElement,r=null;for(;t&&!(t instanceof HTMLFieldSetElement);)t instanceof HTMLLegendElement&&(r=t),t=t.parentElement;let n=(null==t?void 0:t.getAttribute("disabled"))==="";return!(n&&function(e){if(!e)return!1;let t=e.previousElementSibling;for(;null!==t;){if(t instanceof HTMLLegendElement)return!1;t=t.previousElementSibling}return!0}(r))&&n}])},83733,233137,e=>{"use strict";let t,r;var n,i,s=e.i(247167),l=e.i(271645),a=e.i(544508),o=e.i(746725),c=e.i(835696);void 0!==s.default&&"u">typeof globalThis&&"u">typeof Element&&(null==(n=null==s.default?void 0:s.default.env)?void 0:n.NODE_ENV)==="test"&&void 0===(null==(i=null==Element?void 0:Element.prototype)?void 0:i.getAnimations)&&(Element.prototype.getAnimations=function(){return console.warn(["Headless UI has polyfilled `Element.prototype.getAnimations` for your tests.","Please install a proper polyfill e.g. `jsdom-testing-mocks`, to silence these warnings.","","Example usage:","```js","import { mockAnimationsApi } from 'jsdom-testing-mocks'","mockAnimationsApi()","```"].join(` +`)),[]});var u=((t=u||{})[t.None=0]="None",t[t.Closed=1]="Closed",t[t.Enter=2]="Enter",t[t.Leave=4]="Leave",t);e.s(["transitionDataAttributes",0,function(e){let t={};for(let r in e)!0===e[r]&&(t[`data-${r}`]="");return t},"useTransition",0,function(e,t,r,n){let[i,s]=(0,l.useState)(r),{hasFlag:u,addFlag:d,removeFlag:m}=function(e=0){let[t,r]=(0,l.useState)(e),n=(0,l.useCallback)(e=>r(e),[t]),i=(0,l.useCallback)(e=>r(t=>t|e),[t]),s=(0,l.useCallback)(e=>(t&e)===e,[t]);return{flags:t,setFlag:n,addFlag:i,hasFlag:s,removeFlag:(0,l.useCallback)(e=>r(t=>t&~e),[r]),toggleFlag:(0,l.useCallback)(e=>r(t=>t^e),[r])}}(e&&i?3:0),f=(0,l.useRef)(!1),p=(0,l.useRef)(!1),h=(0,o.useDisposables)();return(0,c.useIsoMorphicEffect)(()=>{var i;if(e){if(r&&s(!0),!t){r&&d(3);return}return null==(i=null==n?void 0:n.start)||i.call(n,r),function(e,{prepare:t,run:r,done:n,inFlight:i}){let s=(0,a.disposables)();return function(e,{inFlight:t,prepare:r}){if(null!=t&&t.current)return r();let n=e.style.transition;e.style.transition="none",r(),e.offsetHeight,e.style.transition=n}(e,{prepare:t,inFlight:i}),s.nextFrame(()=>{r(),s.requestAnimationFrame(()=>{s.add(function(e,t){var r,n;let i=(0,a.disposables)();if(!e)return i.dispose;let s=!1;i.add(()=>{s=!0});let l=null!=(n=null==(r=e.getAnimations)?void 0:r.call(e).filter(e=>e instanceof CSSTransition))?n:[];return 0===l.length?t():Promise.allSettled(l.map(e=>e.finished)).then(()=>{s||t()}),i.dispose}(e,n))})}),s.dispose}(t,{inFlight:f,prepare(){p.current?p.current=!1:p.current=f.current,f.current=!0,p.current||(r?(d(3),m(4)):(d(4),m(2)))},run(){p.current?r?(m(3),d(4)):(m(4),d(3)):r?m(1):d(1)},done(){var e;p.current&&"function"==typeof t.getAnimations&&t.getAnimations().length>0||(f.current=!1,m(7),r||s(!1),null==(e=null==n?void 0:n.end)||e.call(n,r))}})}},[e,r,t,h]),e?[i,{closed:u(1),enter:u(2),leave:u(4),transition:u(2)||u(4)}]:[r,{closed:void 0,enter:void 0,leave:void 0,transition:void 0}]}],83733);let d=(0,l.createContext)(null);d.displayName="OpenClosedContext";var m=((r=m||{})[r.Open=1]="Open",r[r.Closed=2]="Closed",r[r.Closing=4]="Closing",r[r.Opening=8]="Opening",r);e.s(["OpenClosedProvider",0,function({value:e,children:t}){return l.default.createElement(d.Provider,{value:e},t)},"ResetOpenClosedProvider",0,function({children:e}){return l.default.createElement(d.Provider,{value:null},e)},"State",0,m,"useOpenClosed",0,function(){return(0,l.useContext)(d)}],233137)},677667,674175,886148,543086,e=>{"use strict";let t,r;var n,i=e.i(290571),s=e.i(783222),l=e.i(433336),a=e.i(271645),o=e.i(394487),c=e.i(914189),u=e.i(144279),d=e.i(294316),m=e.i(83733);let f=(0,a.createContext)(()=>{});function p({value:e,children:t}){return a.default.createElement(f.Provider,{value:e},t)}e.s(["CloseProvider",0,p],674175);var h=e.i(233137),g=e.i(233538),x=e.i(397701),v=e.i(402155),y=e.i(700020);let b=null!=(n=a.default.startTransition)?n:function(e){e()};var _=e.i(998348),w=((t=w||{})[t.Open=0]="Open",t[t.Closed=1]="Closed",t),j=((r=j||{})[r.ToggleDisclosure=0]="ToggleDisclosure",r[r.CloseDisclosure=1]="CloseDisclosure",r[r.SetButtonId=2]="SetButtonId",r[r.SetPanelId=3]="SetPanelId",r[r.SetButtonElement=4]="SetButtonElement",r[r.SetPanelElement=5]="SetPanelElement",r);let C={0:e=>({...e,disclosureState:(0,x.match)(e.disclosureState,{0:1,1:0})}),1:e=>1===e.disclosureState?e:{...e,disclosureState:1},2:(e,t)=>e.buttonId===t.buttonId?e:{...e,buttonId:t.buttonId},3:(e,t)=>e.panelId===t.panelId?e:{...e,panelId:t.panelId},4:(e,t)=>e.buttonElement===t.element?e:{...e,buttonElement:t.element},5:(e,t)=>e.panelElement===t.element?e:{...e,panelElement:t.element}},k=(0,a.createContext)(null);function S(e){let t=(0,a.useContext)(k);if(null===t){let t=Error(`<${e} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,S),t}return t}k.displayName="DisclosureContext";let E=(0,a.createContext)(null);E.displayName="DisclosureAPIContext";let O=(0,a.createContext)(null);function N(e,t){return(0,x.match)(t.type,C,e,t)}O.displayName="DisclosurePanelContext";let I=a.Fragment,T=y.RenderFeatures.RenderStrategy|y.RenderFeatures.Static,R=Object.assign((0,y.forwardRefWithAs)(function(e,t){let{defaultOpen:r=!1,...n}=e,i=(0,a.useRef)(null),s=(0,d.useSyncRefs)(t,(0,d.optionalRef)(e=>{i.current=e},void 0===e.as||e.as===a.Fragment)),l=(0,a.useReducer)(N,{disclosureState:+!r,buttonElement:null,panelElement:null,buttonId:null,panelId:null}),[{disclosureState:o,buttonId:u},m]=l,f=(0,c.useEvent)(e=>{m({type:1});let t=(0,v.getOwnerDocument)(i);if(!t||!u)return;let r=e?e instanceof HTMLElement?e:e.current instanceof HTMLElement?e.current:t.getElementById(u):t.getElementById(u);null==r||r.focus()}),g=(0,a.useMemo)(()=>({close:f}),[f]),b=(0,a.useMemo)(()=>({open:0===o,close:f}),[o,f]),_=(0,y.useRender)();return a.default.createElement(k.Provider,{value:l},a.default.createElement(E.Provider,{value:g},a.default.createElement(p,{value:f},a.default.createElement(h.OpenClosedProvider,{value:(0,x.match)(o,{0:h.State.Open,1:h.State.Closed})},_({ourProps:{ref:s},theirProps:n,slot:b,defaultTag:I,name:"Disclosure"})))))}),{Button:(0,y.forwardRefWithAs)(function(e,t){let r=(0,a.useId)(),{id:n=`headlessui-disclosure-button-${r}`,disabled:i=!1,autoFocus:m=!1,...f}=e,[p,h]=S("Disclosure.Button"),x=(0,a.useContext)(O),v=null!==x&&x===p.panelId,b=(0,a.useRef)(null),w=(0,d.useSyncRefs)(b,t,(0,c.useEvent)(e=>{if(!v)return h({type:4,element:e})}));(0,a.useEffect)(()=>{if(!v)return h({type:2,buttonId:n}),()=>{h({type:2,buttonId:null})}},[n,h,v]);let j=(0,c.useEvent)(e=>{var t;if(v){if(1===p.disclosureState)return;switch(e.key){case _.Keys.Space:case _.Keys.Enter:e.preventDefault(),e.stopPropagation(),h({type:0}),null==(t=p.buttonElement)||t.focus()}}else switch(e.key){case _.Keys.Space:case _.Keys.Enter:e.preventDefault(),e.stopPropagation(),h({type:0})}}),C=(0,c.useEvent)(e=>{e.key===_.Keys.Space&&e.preventDefault()}),k=(0,c.useEvent)(e=>{var t;(0,g.isDisabledReactIssue7711)(e.currentTarget)||i||(v?(h({type:0}),null==(t=p.buttonElement)||t.focus()):h({type:0}))}),{isFocusVisible:E,focusProps:N}=(0,s.useFocusRing)({autoFocus:m}),{isHovered:I,hoverProps:T}=(0,l.useHover)({isDisabled:i}),{pressed:R,pressProps:P}=(0,o.useActivePress)({disabled:i}),$=(0,a.useMemo)(()=>({open:0===p.disclosureState,hover:I,active:R,disabled:i,focus:E,autofocus:m}),[p,I,R,E,i,m]),D=(0,u.useResolveButtonType)(e,p.buttonElement),A=v?(0,y.mergeProps)({ref:w,type:D,disabled:i||void 0,autoFocus:m,onKeyDown:j,onClick:k},N,T,P):(0,y.mergeProps)({ref:w,id:n,type:D,"aria-expanded":0===p.disclosureState,"aria-controls":p.panelElement?p.panelId:void 0,disabled:i||void 0,autoFocus:m,onKeyDown:j,onKeyUp:C,onClick:k},N,T,P);return(0,y.useRender)()({ourProps:A,theirProps:f,slot:$,defaultTag:"button",name:"Disclosure.Button"})}),Panel:(0,y.forwardRefWithAs)(function(e,t){let r=(0,a.useId)(),{id:n=`headlessui-disclosure-panel-${r}`,transition:i=!1,...s}=e,[l,o]=S("Disclosure.Panel"),{close:u}=function e(t){let r=(0,a.useContext)(E);if(null===r){let r=Error(`<${t} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(r,e),r}return r}("Disclosure.Panel"),[f,p]=(0,a.useState)(null),g=(0,d.useSyncRefs)(t,(0,c.useEvent)(e=>{b(()=>o({type:5,element:e}))}),p);(0,a.useEffect)(()=>(o({type:3,panelId:n}),()=>{o({type:3,panelId:null})}),[n,o]);let x=(0,h.useOpenClosed)(),[v,_]=(0,m.useTransition)(i,f,null!==x?(x&h.State.Open)===h.State.Open:0===l.disclosureState),w=(0,a.useMemo)(()=>({open:0===l.disclosureState,close:u}),[l.disclosureState,u]),j={ref:g,id:n,...(0,m.transitionDataAttributes)(_)},C=(0,y.useRender)();return a.default.createElement(h.ResetOpenClosedProvider,null,a.default.createElement(O.Provider,{value:l.panelId},C({ourProps:j,theirProps:s,slot:w,defaultTag:"div",features:T,visible:v,name:"Disclosure.Panel"})))})});e.s(["Disclosure",0,R],886148);let P=(0,a.createContext)(void 0);var $=e.i(444755);let D=(0,e.i(673706).makeClassName)("Accordion"),A=(0,a.createContext)({isOpen:!1}),F=a.default.forwardRef((e,t)=>{var r;let{defaultOpen:n=!1,children:s,className:l}=e,o=(0,i.__rest)(e,["defaultOpen","children","className"]),c=null!=(r=(0,a.useContext)(P))?r:(0,$.tremorTwMerge)("rounded-tremor-default border");return a.default.createElement(R,Object.assign({as:"div",ref:t,className:(0,$.tremorTwMerge)(D("root"),"overflow-hidden","bg-tremor-background border-tremor-border","dark:bg-dark-tremor-background dark:border-dark-tremor-border",c,l),defaultOpen:n},o),({open:e})=>a.default.createElement(A.Provider,{value:{isOpen:e}},s))});F.displayName="Accordion",e.s(["OpenContext",0,A,"default",0,F],543086),e.s(["Accordion",0,F],677667)},130643,e=>{"use strict";var t=e.i(290571),r=e.i(271645),n=e.i(886148),i=e.i(444755);let s=(0,e.i(673706).makeClassName)("AccordionBody"),l=r.default.forwardRef((e,l)=>{let{children:a,className:o}=e,c=(0,t.__rest)(e,["children","className"]);return r.default.createElement(n.Disclosure.Panel,Object.assign({ref:l,className:(0,i.tremorTwMerge)(s("root"),"w-full text-tremor-default px-4 pb-3","text-tremor-content","dark:text-dark-tremor-content",o)},c),a)});l.displayName="AccordionBody",e.s(["AccordionBody",0,l],130643)},898667,e=>{"use strict";var t=e.i(290571),r=e.i(271645),n=e.i(886148);let i=e=>{var n=(0,t.__rest)(e,[]);return r.default.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor"},n),r.default.createElement("path",{d:"M11.9999 10.8284L7.0502 15.7782L5.63599 14.364L11.9999 8L18.3639 14.364L16.9497 15.7782L11.9999 10.8284Z"}))};var s=e.i(543086),l=e.i(444755);let a=(0,e.i(673706).makeClassName)("AccordionHeader"),o=r.default.forwardRef((e,o)=>{let{children:c,className:u}=e,d=(0,t.__rest)(e,["children","className"]),{isOpen:m}=(0,r.useContext)(s.OpenContext);return r.default.createElement(n.Disclosure.Button,Object.assign({ref:o,className:(0,l.tremorTwMerge)(a("root"),"w-full flex items-center justify-between px-4 py-3","text-tremor-content-emphasis","dark:text-dark-tremor-content-emphasis",u)},d),r.default.createElement("div",{className:(0,l.tremorTwMerge)(a("children"),"flex flex-1 text-inherit mr-4")},c),r.default.createElement("div",null,r.default.createElement(i,{className:(0,l.tremorTwMerge)(a("arrowIcon"),"h-5 w-5 -mr-1","text-tremor-content-subtle","dark:text-dark-tremor-content-subtle",m?"transition-all":"transition-all -rotate-180")})))});o.displayName="AccordionHeader",e.s(["AccordionHeader",0,o],898667)},220508,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"}))});e.s(["CheckCircleIcon",0,r],220508)},503269,214520,601893,694421,140721,942803,35889,722678,e=>{"use strict";var t=e.i(271645),r=e.i(914189);e.s(["useControllable",0,function(e,n,i){let[s,l]=(0,t.useState)(i),a=void 0!==e,o=(0,t.useRef)(a),c=(0,t.useRef)(!1),u=(0,t.useRef)(!1);return!a||o.current||c.current?a||!o.current||u.current||(u.current=!0,o.current=a,console.error("A component is changing from controlled to uncontrolled. This may be caused by the value changing from a defined value to undefined, which should not happen.")):(c.current=!0,o.current=a,console.error("A component is changing from uncontrolled to controlled. This may be caused by the value changing from undefined to a defined value, which should not happen.")),[a?e:s,(0,r.useEvent)(e=>(a||l(e),null==n?void 0:n(e)))]}],503269),e.s(["useDefaultValue",0,function(e){let[r]=(0,t.useState)(e);return r}],214520);let n=(0,t.createContext)(void 0);function i(){return(0,t.useContext)(n)}e.s(["useDisabled",0,i],601893);var s=e.i(174080),l=e.i(746725);function a(e={},t=null,r=[]){for(let[n,i]of Object.entries(e))!function e(t,r,n){if(Array.isArray(n))for(let[i,s]of n.entries())e(t,o(r,i.toString()),s);else n instanceof Date?t.push([r,n.toISOString()]):"boolean"==typeof n?t.push([r,n?"1":"0"]):"string"==typeof n?t.push([r,n]):"number"==typeof n?t.push([r,`${n}`]):null==n?t.push([r,""]):a(n,r,t)}(r,o(t,n),i);return r}function o(e,t){return e?e+"["+t+"]":t}e.s(["attemptSubmit",0,function(e){var t,r;let n=null!=(t=null==e?void 0:e.form)?t:e.closest("form");if(n){for(let t of n.elements)if(t!==e&&("INPUT"===t.tagName&&"submit"===t.type||"BUTTON"===t.tagName&&"submit"===t.type||"INPUT"===t.nodeName&&"image"===t.type))return void t.click();null==(r=n.requestSubmit)||r.call(n)}},"objectToFormEntries",0,a],694421);var c=e.i(700020),u=e.i(2788);let d=(0,t.createContext)(null);function m({children:e}){let r=(0,t.useContext)(d);if(!r)return t.default.createElement(t.default.Fragment,null,e);let{target:n}=r;return n?(0,s.createPortal)(t.default.createElement(t.default.Fragment,null,e),n):null}function f({setForm:e,formId:r}){return(0,t.useEffect)(()=>{if(r){let t=document.getElementById(r);t&&e(t)}},[e,r]),r?null:t.default.createElement(u.Hidden,{features:u.HiddenFeatures.Hidden,as:"input",type:"hidden",hidden:!0,readOnly:!0,ref:t=>{if(!t)return;let r=t.closest("form");r&&e(r)}})}e.s(["FormFields",0,function({data:e,form:r,disabled:n,onReset:i,overrides:s}){let[o,d]=(0,t.useState)(null),p=(0,l.useDisposables)();return(0,t.useEffect)(()=>{if(i&&o)return p.addEventListener(o,"reset",i)},[o,r,i]),t.default.createElement(m,null,t.default.createElement(f,{setForm:d,formId:r}),a(e).map(([e,i])=>t.default.createElement(u.Hidden,{features:u.HiddenFeatures.Hidden,...(0,c.compact)({key:e,as:"input",type:"hidden",hidden:!0,readOnly:!0,form:r,disabled:n,name:e,value:i,...s})})))}],140721);let p=(0,t.createContext)(void 0);function h(){return(0,t.useContext)(p)}e.s(["useProvidedId",0,h],942803);var g=e.i(835696),x=e.i(294316);let v=(0,t.createContext)(null);v.displayName="DescriptionContext";let y=Object.assign((0,c.forwardRefWithAs)(function(e,r){let n=(0,t.useId)(),s=i(),{id:l=`headlessui-description-${n}`,...a}=e,o=function e(){let r=(0,t.useContext)(v);if(null===r){let t=Error("You used a component, but it is not inside a relevant parent.");throw Error.captureStackTrace&&Error.captureStackTrace(t,e),t}return r}(),u=(0,x.useSyncRefs)(r);(0,g.useIsoMorphicEffect)(()=>o.register(l),[l,o.register]);let d=s||!1,m=(0,t.useMemo)(()=>({...o.slot,disabled:d}),[o.slot,d]),f={ref:u,...o.props,id:l};return(0,c.useRender)()({ourProps:f,theirProps:a,slot:m,defaultTag:"p",name:o.name||"Description"})}),{});e.s(["Description",0,y,"useDescribedBy",0,function(){var e,r;return null!=(r=null==(e=(0,t.useContext)(v))?void 0:e.value)?r:void 0},"useDescriptions",0,function(){let[e,n]=(0,t.useState)([]);return[e.length>0?e.join(" "):void 0,(0,t.useMemo)(()=>function(e){let i=(0,r.useEvent)(e=>(n(t=>[...t,e]),()=>n(t=>{let r=t.slice(),n=r.indexOf(e);return -1!==n&&r.splice(n,1),r}))),s=(0,t.useMemo)(()=>({register:i,slot:e.slot,name:e.name,props:e.props,value:e.value}),[i,e.slot,e.name,e.props,e.value]);return t.default.createElement(v.Provider,{value:s},e.children)},[n])]}],35889);let b=(0,t.createContext)(null);function _(e){var r,n,i;let s=null!=(n=null==(r=(0,t.useContext)(b))?void 0:r.value)?n:void 0;return(null!=(i=null==e?void 0:e.length)?i:0)>0?[s,...e].filter(Boolean).join(" "):s}b.displayName="LabelContext";let w=Object.assign((0,c.forwardRefWithAs)(function(e,n){var s;let l=(0,t.useId)(),a=function e(){let r=(0,t.useContext)(b);if(null===r){let t=Error("You used a ; - * nested ones live under collapsible submenus, so expand submenus until the link is clickable. + * nested ones live under collapsible groups whose children only render while the + * group is open, so expand collapsed groups until the link is clickable. */ async function clickSidebar(page: Page, segment: string) { - const link = page.locator(`a[href$="/ui/${segment}"]`).first(); + const link = sidebar(page).locator(`a[href$="/ui/${segment}"]`).first(); for (let i = 0; i < 8 && !(await link.isVisible().catch(() => false)); i++) { - const collapsedSubmenu = page - .locator(".ant-menu-submenu:not(.ant-menu-submenu-open) > .ant-menu-submenu-title") + // A collapsed group is a menu item with a group-toggle button but no + // rendered submenu yet; clicking the toggle expands it. + const collapsedGroup = sidebar(page) + .locator( + '[data-slot="sidebar-menu-item"]:has(> [data-slot="sidebar-menu-button"]):not(:has(> [data-slot="sidebar-menu-sub"])) > [data-slot="sidebar-menu-button"]', + ) .first(); - if (!(await collapsedSubmenu.isVisible().catch(() => false))) break; - await collapsedSubmenu.click(); + if (!(await collapsedGroup.isVisible().catch(() => false))) break; + await collapsedGroup.click(); await page.waitForTimeout(250); } await link.click(); diff --git a/ui/litellm-dashboard/e2e_tests/tests/navigation/sidebar.spec.ts b/ui/litellm-dashboard/e2e_tests/tests/navigation/sidebar.spec.ts index 7ac2e7df39d..7e42d07ae7c 100644 --- a/ui/litellm-dashboard/e2e_tests/tests/navigation/sidebar.spec.ts +++ b/ui/litellm-dashboard/e2e_tests/tests/navigation/sidebar.spec.ts @@ -42,7 +42,9 @@ for (const { role, storage } of roles) { throw new Error(`No page mapping found for menu label: ${buttonLabel}`); } - const tab = page.getByRole("menuitem", { name: buttonLabel }); + // Sidebar items are links inside the `complementary` landmark; scoping + // there avoids the top-bar breadcrumb, which also links the page name. + const tab = page.getByRole("complementary").getByRole("link", { name: buttonLabel }); await expect(tab).toBeVisible(); await tab.click(); diff --git a/ui/litellm-dashboard/e2e_tests/tests/proxy-admin/keys.spec.ts b/ui/litellm-dashboard/e2e_tests/tests/proxy-admin/keys.spec.ts index 644228c5ff9..a55c19a53de 100644 --- a/ui/litellm-dashboard/e2e_tests/tests/proxy-admin/keys.spec.ts +++ b/ui/litellm-dashboard/e2e_tests/tests/proxy-admin/keys.spec.ts @@ -137,11 +137,10 @@ test.describe("Proxy Admin - Keys", () => { // No team selection — leave team dropdown empty so the key is owned by the admin user // Select models — open the multi-select and pick the all-models meta-option. - // The Create Key modal labels this "All Team Models" even when no team is selected - // (see src/components/organisms/create_key_button.tsx:944), unlike the team/user - // settings screens which use "All Proxy Models". + // With no team selected the modal offers "All Proxy Models"; the team-scoped + // "All Team Models" option only appears once a team is picked. await page.locator(".ant-select-selection-overflow").click(); - await page.locator(".ant-select-dropdown:visible").getByText("All Team Models").click(); + await page.locator(".ant-select-dropdown:visible").getByText("All Proxy Models").click(); await page.keyboard.press("Escape"); await page.getByRole("button", { name: "Create Key", exact: true }).click(); diff --git a/ui/litellm-dashboard/e2e_tests/tests/settings/adminSettings.spec.ts b/ui/litellm-dashboard/e2e_tests/tests/settings/adminSettings.spec.ts index f61532b05a5..c4a14a891d4 100644 --- a/ui/litellm-dashboard/e2e_tests/tests/settings/adminSettings.spec.ts +++ b/ui/litellm-dashboard/e2e_tests/tests/settings/adminSettings.spec.ts @@ -6,8 +6,11 @@ test.describe("Add Model", () => { test("admin settings test", async ({ page }) => { await page.goto("/ui"); - await page.getByRole("menuitem", { name: /Settings/ }).click(); - await page.getByRole("menuitem", { name: /Admin Settings/ }).click(); + // "Settings" is a collapsible group (button) in the sidebar; expand it, then + // click the "Admin Settings" child link. Scope to the complementary landmark. + const sidebar = page.getByRole("complementary"); + await sidebar.getByRole("button", { name: /Settings/ }).click(); + await sidebar.getByRole("link", { name: /Admin Settings/ }).click(); await page.getByRole("tab", { name: "UI Settings" }).click(); await expect(page.getByText("Configuration for UI-specific")).toBeVisible(); }); diff --git a/ui/litellm-dashboard/e2e_tests/tests/settings/routerSettings.spec.ts b/ui/litellm-dashboard/e2e_tests/tests/settings/routerSettings.spec.ts index 98b86ec9b11..3e140b9ab56 100644 --- a/ui/litellm-dashboard/e2e_tests/tests/settings/routerSettings.spec.ts +++ b/ui/litellm-dashboard/e2e_tests/tests/settings/routerSettings.spec.ts @@ -3,6 +3,14 @@ import { ADMIN_STORAGE_PATH } from "../../constants"; import { navigateToPage } from "../../helpers/navigation"; import { Page } from "../../fixtures/pages"; import { Role, users } from "../../fixtures/users"; +// Type-only import of the OpenAPI-generated backend schema, erased at runtime by +// esbuild. It types the round-trips below so mistakes surface in the editor; the live +// test against the real proxy is what actually enforces the contract. +import type { components } from "../../../src/lib/http/schema"; + +// These tests mutate the proxy's shared router_settings, and the Loadbalancing save +// echoes the whole settings object, so they must not run concurrently. +test.describe.configure({ mode: "serial" }); const PRIMARY = "fake-openai-gpt-4"; const FALLBACK = "fake-anthropic-claude"; @@ -99,3 +107,84 @@ test.describe("Router Settings - Fallbacks", () => { await expect(newRow).toHaveCount(1, { timeout: 10_000 }); }); }); + +type ConfigYAML = components["schemas"]["ConfigYAML"]; +type RouterSettingsResponse = components["schemas"]["RouterSettingsResponse"]; + +const BASE_URL = "http://localhost:4000"; +const ADMIN_AUTH = { Authorization: `Bearer ${users[Role.ProxyAdmin].password}` }; + +/** + * Apply a router_settings patch through the typed /config/update contract. The + * server merges it over existing settings (request wins), so only the passed keys + * change. Fails loudly if the write is rejected instead of leaving a silent bad seed. + */ +async function patchRouterSettings( + request: import("@playwright/test").APIRequestContext, + patch: Partial>, +) { + const res = await request.post(`${BASE_URL}/config/update`, { + headers: ADMIN_AUTH, + data: { router_settings: patch }, + }); + expect(res.ok(), `seed /config/update failed: ${res.status()} ${await res.text()}`).toBeTruthy(); +} + +test.describe("Router Settings - Loadbalancing", () => { + test.use({ storageState: ADMIN_STORAGE_PATH }); + + // Pin num_retries and an empty routing_groups so the assertions are deterministic. + // Empty already reproduces LIT-4057: the old tab serialized [] to the string "[]" + // and the save 422'd. + test.beforeEach(async ({ request }) => { + await patchRouterSettings(request, { num_retries: 3, routing_groups: [] }); + }); + + test.afterEach(async ({ request }) => { + await patchRouterSettings(request, { num_retries: 3 }); + }); + + test("saves the Loadbalancing tab without a 422 when routing_groups is present, and persists", async ({ + page, + request, + }) => { + await navigateToPage(page, Page.RouterSettings); + await page.getByRole("tab", { name: "Loadbalancing" }).click(); + + const numRetries = page.locator('input[name="num_retries"]'); + await expect(numRetries).toHaveValue("3", { timeout: 15_000 }); + // routing_groups belongs to its own tab and must not leak into this form. + await expect(page.locator('input[name="routing_groups"]')).toHaveCount(0); + + await numRetries.fill("5"); + + // LIT-4057: the tab used to serialize routing_groups as the string "[]", + // which the backend rejects with 422 while the UI still claimed success. + // Assert the save actually succeeds at the network level. + const saveResponse = page.waitForResponse( + (res) => res.url().includes("/config/update") && res.request().method() === "POST", + { timeout: 15_000 }, + ); + await page.getByRole("button", { name: /save changes/i }).click(); + expect((await saveResponse).status()).toBe(200); + + await expect(page.getByText(/router settings updated successfully/i).first()).toBeVisible({ timeout: 10_000 }); + + // The ticket's core symptom was that a refresh showed the old value. + await navigateToPage(page, Page.RouterSettings); + await page.getByRole("tab", { name: "Loadbalancing" }).click(); + await expect(page.locator('input[name="num_retries"]')).toHaveValue("5", { timeout: 15_000 }); + + // The typed backend read agrees the change persisted. + await expect + .poll( + async () => { + const res = await request.get(`${BASE_URL}/router/settings`, { headers: ADMIN_AUTH }); + const data = (await res.json()) as RouterSettingsResponse; + return data.current_values?.num_retries; + }, + { timeout: 10_000 }, + ) + .toBe(5); + }); +}); diff --git a/ui/litellm-dashboard/eslint-budgets.json b/ui/litellm-dashboard/eslint-budgets.json index 2139d177512..f08e1bb6160 100644 --- a/ui/litellm-dashboard/eslint-budgets.json +++ b/ui/litellm-dashboard/eslint-budgets.json @@ -1,5 +1,8 @@ { "@typescript-eslint/no-explicit-any": { "max": 2040, "target": 1500 }, + "no-console": { "max": 484, "target": 0 }, "complexity": { "max": 140, "target": 80 }, - "max-depth": { "max": 70, "target": 30 } + "max-depth": { "max": 70, "target": 30 }, + "local/no-large-inline-object-arg": { "max": 560, "target": 300 }, + "local/no-long-condition-chain": { "max": 265, "target": 120 } } diff --git a/ui/litellm-dashboard/eslint-metrics.json b/ui/litellm-dashboard/eslint-metrics.json index deef1136b43..7abbb186771 100644 --- a/ui/litellm-dashboard/eslint-metrics.json +++ b/ui/litellm-dashboard/eslint-metrics.json @@ -1,5 +1,8 @@ { - "@typescript-eslint/no-explicit-any": 2016, - "complexity": 127, - "max-depth": 61 + "@typescript-eslint/no-explicit-any": 1978, + "complexity": 130, + "local/no-large-inline-object-arg": 509, + "local/no-long-condition-chain": 234, + "max-depth": 59, + "no-console": 16 } diff --git a/ui/litellm-dashboard/eslint-suppressions.json b/ui/litellm-dashboard/eslint-suppressions.json index e3ae304c41c..2448348bbce 100644 --- a/ui/litellm-dashboard/eslint-suppressions.json +++ b/ui/litellm-dashboard/eslint-suppressions.json @@ -1,7 +1,167 @@ { - "src/app/(dashboard)/api-reference/APIReferenceView.tsx": { + "scripts/check-lint-budgets.mjs": { + "no-nested-ternary": { + "count": 1 + } + }, + "src/app/(dashboard)/admin-panel/_components/AdminPanel.tsx": { "no-restricted-imports": { "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/api-reference/_components/APIReferenceView.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/budgets/_components/budget_modal.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/budgets/_components/budget_panel.test.tsx": { + "unused-imports/no-unused-imports": { + "count": 2 + } + }, + "src/app/(dashboard)/budgets/_components/budget_panel.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/budgets/_components/edit_budget_modal.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/caching/_components/cache_dashboard.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/purity": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 2 + } + }, + "src/app/(dashboard)/caching/_components/cache_health.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/caching/_components/cache_settings/RedisTypeSelector.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/caching/_components/cache_settings/index.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/cost-tracking/_components/add_margin_form.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/cost-tracking/_components/add_provider_form.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/cost-tracking/_components/cost_tracking_settings.tsx": { + "no-nested-ternary": { + "count": 2 + }, + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/cost-tracking/_components/how_it_works.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_cost_results.test.tsx": { + "unused-imports/no-unused-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_cost_results.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_export_dropdown.test.tsx": { + "unused-imports/no-unused-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/cost-tracking/_components/pricing_calculator/multi_export_dropdown.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/cost-tracking/_components/pricing_calculator/use_multi_cost_estimate.ts": { + "no-restricted-syntax": { + "count": 1 + } + }, + "src/app/(dashboard)/cost-tracking/_components/provider_discount_table.test.tsx": { + "unused-imports/no-unused-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/cost-tracking/_components/provider_discount_table.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/cost-tracking/_components/provider_display_helpers.test.ts": { + "unused-imports/no-unused-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/cost-tracking/_components/provider_margin_table.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/cost-tracking/_components/use_discount_config.ts": { + "no-restricted-syntax": { + "count": 2 + } + }, + "src/app/(dashboard)/cost-tracking/_components/use_margin_config.ts": { + "no-restricted-syntax": { + "count": 2 + } + }, + "src/app/(dashboard)/guardrails-monitor/_components/EvaluationSettingsModal.tsx": { + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx": { + "no-nested-ternary": { + "count": 3 + } + }, + "src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx": { + "no-nested-ternary": { + "count": 8 } }, "src/app/(dashboard)/hooks/accessGroups/useAccessGroupDetails.ts": { @@ -164,6 +324,11 @@ "count": 2 } }, + "src/app/(dashboard)/memory/_components/MemoryView.tsx": { + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, "src/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView.tsx": { "no-restricted-imports": { "count": 1 @@ -194,6 +359,9 @@ } }, "src/app/(dashboard)/models-and-endpoints/components/ModelRetrySettingsTab.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } @@ -203,11 +371,425 @@ "count": 1 } }, + "src/app/(dashboard)/old-usage/_components/usage.tsx": { + "no-restricted-imports": { + "count": 2 + }, + "react-hooks/immutability": { + "count": 1 + }, + "react-hooks/purity": { + "count": 1 + } + }, + "src/app/(dashboard)/organizations/_components/organizations.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/playground/components/chat_ui/AdditionalModelSettings.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 2 + } + }, + "src/app/(dashboard)/playground/components/chat_ui/AgentBuilderView.tsx": { + "no-nested-ternary": { + "count": 2 + }, + "react-hooks/set-state-in-effect": { + "count": 5 + } + }, + "src/app/(dashboard)/playground/components/chat_ui/ChatImageUtils.test.tsx": { + "max-nested-callbacks": { + "count": 1 + } + }, + "src/app/(dashboard)/playground/components/chat_ui/ChatMessageBubble.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, + "src/app/(dashboard)/playground/components/chat_ui/ChatUI.tsx": { + "no-nested-ternary": { + "count": 7 + }, + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 4 + }, + "unused-imports/no-unused-imports": { + "count": 13 + } + }, + "src/app/(dashboard)/playground/components/chat_ui/CodeInterpreterOutput.tsx": { + "no-nested-ternary": { + "count": 1 + }, + "no-restricted-syntax": { + "count": 2 + } + }, + "src/app/(dashboard)/playground/components/chat_ui/CodeInterpreterTool.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/playground/components/chat_ui/RealtimePlayground.tsx": { + "no-nested-ternary": { + "count": 2 + }, + "react-hooks/immutability": { + "count": 2 + }, + "react-hooks/preserve-manual-memoization": { + "count": 1 + } + }, + "src/app/(dashboard)/playground/components/compareUI/CompareUI.tsx": { + "no-nested-ternary": { + "count": 4 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/playground/components/compareUI/components/MessageDisplay.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, + "src/app/(dashboard)/playground/components/compareUI/components/ModelSelector.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/playground/components/complianceUI/ComplianceUI.tsx": { + "no-nested-ternary": { + "count": 8 + }, + "react-hooks/preserve-manual-memoization": { + "count": 3 + } + }, + "src/app/(dashboard)/playground/llm_calls/a2a_send_message.tsx": { + "max-params": { + "count": 2 + }, + "no-restricted-syntax": { + "count": 2 + } + }, + "src/app/(dashboard)/playground/llm_calls/anthropic_messages.tsx": { + "max-params": { + "count": 1 + } + }, + "src/app/(dashboard)/playground/llm_calls/audio_speech.tsx": { + "max-params": { + "count": 1 + } + }, + "src/app/(dashboard)/playground/llm_calls/audio_transcriptions.tsx": { + "max-params": { + "count": 1 + } + }, + "src/app/(dashboard)/playground/llm_calls/embeddings_api.tsx": { + "max-params": { + "count": 1 + }, + "no-restricted-syntax": { + "count": 1 + } + }, + "src/app/(dashboard)/playground/llm_calls/fetch_agents.tsx": { + "no-restricted-syntax": { + "count": 1 + } + }, + "src/app/(dashboard)/playground/llm_calls/image_edits.tsx": { + "max-params": { + "count": 1 + } + }, + "src/app/(dashboard)/playground/llm_calls/image_generation.tsx": { + "max-params": { + "count": 1 + } + }, + "src/app/(dashboard)/playground/llm_calls/interactions_api.tsx": { + "max-params": { + "count": 1 + }, + "no-restricted-syntax": { + "count": 1 + } + }, "src/app/(dashboard)/playground/page.tsx": { "no-restricted-imports": { "count": 1 } }, + "src/app/(dashboard)/projects/_components/ProjectDetailsPage.tsx": { + "no-nested-ternary": { + "count": 3 + }, + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/projects/_components/ProjectKeysSection.tsx": { + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/projects/_components/ProjectModals/ProjectBaseForm.tsx": { + "react-hooks/set-state-in-effect": { + "count": 2 + } + }, + "src/app/(dashboard)/projects/_components/ProjectsPage.tsx": { + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/prompts/_components/add_prompt_form.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/prompts/_components/index.tsx": { + "no-nested-ternary": { + "count": 1 + }, + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/prompts/_components/prompt_editor_view/DeveloperMessageCard.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/prompts/_components/prompt_editor_view/ModelConfigCard.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/prompts/_components/prompt_editor_view/PromptCodeSnippets.tsx": { + "no-nested-ternary": { + "count": 1 + }, + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/prompts/_components/prompt_editor_view/PromptEditorHeader.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/prompts/_components/prompt_editor_view/PromptMessagesCard.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/prompts/_components/prompt_editor_view/PublishModal.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/prompts/_components/prompt_editor_view/ToolsCard.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/prompts/_components/prompt_editor_view/VersionHistorySidePanel.test.tsx": { + "max-nested-callbacks": { + "count": 1 + } + }, + "src/app/(dashboard)/prompts/_components/prompt_editor_view/VersionHistorySidePanel.tsx": { + "no-nested-ternary": { + "count": 1 + }, + "react-hooks/immutability": { + "count": 1 + } + }, + "src/app/(dashboard)/prompts/_components/prompt_editor_view/conversation_panel/MessageInput.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/prompts/_components/prompt_editor_view/conversation_panel/index.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/prompts/_components/prompt_editor_view/conversation_panel/useConversation.ts": { + "no-restricted-syntax": { + "count": 1 + } + }, + "src/app/(dashboard)/prompts/_components/prompt_info.tsx": { + "no-nested-ternary": { + "count": 3 + }, + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 2 + } + }, + "src/app/(dashboard)/prompts/_components/prompt_table.tsx": { + "no-nested-ternary": { + "count": 1 + }, + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/router-settings/_components/general_settings.tsx": { + "no-nested-ternary": { + "count": 3 + }, + "no-restricted-imports": { + "count": 2 + } + }, + "src/app/(dashboard)/search-tools/_components/CreateSearchTools.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/search-tools/_components/SearchToolTester.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/search-tools/_components/SearchToolView.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/search-tools/_components/SearchTools.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/static-components": { + "count": 1 + } + }, + "src/app/(dashboard)/transform-request/TransformRequestPanel.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/ui-theme/UIThemeSettings.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "no-restricted-syntax": { + "count": 3 + }, + "react-hooks/immutability": { + "count": 1 + } + }, + "src/app/(dashboard)/users/_components/DefaultUserSettings.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/users/_components/edit_user.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/users/_components/user_edit_view.test.tsx": { + "no-nested-ternary": { + "count": 1 + }, + "react/display-name": { + "count": 1 + } + }, + "src/app/(dashboard)/users/_components/user_edit_view.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/users/_components/view_users.tsx": { + "no-nested-ternary": { + "count": 1 + }, + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/users/_components/view_users/columns.tsx": { + "max-params": { + "count": 1 + }, + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/users/_components/view_users/table.tsx": { + "no-nested-ternary": { + "count": 1 + }, + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/users/_components/view_users/user_info_view.tsx": { + "no-restricted-imports": { + "count": 1 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/workflows/WorkflowRuns.tsx": { + "no-nested-ternary": { + "count": 1 + }, + "no-restricted-syntax": { + "count": 3 + }, + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/chat/page.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, "src/app/login/LoginPage.tsx": { "react-hooks/set-state-in-effect": { "count": 2 @@ -239,6 +821,9 @@ } }, "src/components/AIHub/ModelHubTable.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } @@ -270,6 +855,9 @@ } }, "src/components/AIHub/forms/MakeMCPPublicForm.tsx": { + "no-nested-ternary": { + "count": 2 + }, "no-restricted-imports": { "count": 1 }, @@ -285,89 +873,6 @@ "count": 1 } }, - "src/components/AdminPanel.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/cost-tracking/components/add_margin_form.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/cost-tracking/components/add_provider_form.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/cost-tracking/components/cost_tracking_settings.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/cost-tracking/components/how_it_works.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/cost-tracking/components/pricing_calculator/multi_cost_results.test.tsx": { - "unused-imports/no-unused-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/cost-tracking/components/pricing_calculator/multi_cost_results.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/cost-tracking/components/pricing_calculator/multi_export_dropdown.test.tsx": { - "unused-imports/no-unused-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/cost-tracking/components/pricing_calculator/multi_export_dropdown.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/cost-tracking/components/pricing_calculator/use_multi_cost_estimate.ts": { - "no-restricted-syntax": { - "count": 1 - } - }, - "src/app/(dashboard)/cost-tracking/components/provider_discount_table.test.tsx": { - "unused-imports/no-unused-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/cost-tracking/components/provider_discount_table.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/cost-tracking/components/provider_display_helpers.test.ts": { - "unused-imports/no-unused-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/cost-tracking/components/provider_margin_table.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/cost-tracking/components/use_discount_config.ts": { - "no-restricted-syntax": { - "count": 2 - } - }, - "src/app/(dashboard)/cost-tracking/components/use_margin_config.ts": { - "no-restricted-syntax": { - "count": 2 - } - }, "src/components/CreateUserButton.tsx": { "no-restricted-imports": { "count": 1 @@ -376,17 +881,18 @@ "count": 1 } }, - "src/components/DefaultUserSettings.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "src/components/DeletedKeysPage/DeletedKeysTable/DeletedKeysTable.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } }, "src/components/DeletedTeamsPage/DeletedTeamsTable/DeletedTeamsTable.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } @@ -419,23 +925,13 @@ "count": 1 } }, - "src/app/(dashboard)/guardrails-monitor/components/EvaluationSettingsModal.tsx": { - "react-hooks/set-state-in-effect": { + "src/components/GuardrailSettingsView.tsx": { + "no-nested-ternary": { "count": 1 } }, - "src/app/(dashboard)/guardrails-monitor/components/GuardrailsMonitorView.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/guardrails-monitor/components/ScoreChart.test.tsx": { - "react/display-name": { - "count": 1 - } - }, - "src/app/(dashboard)/guardrails-monitor/components/ScoreChart.tsx": { - "no-restricted-imports": { + "src/components/GuardrailsMonitor/LogViewer.tsx": { + "no-nested-ternary": { "count": 1 } }, @@ -444,8 +940,8 @@ "count": 1 } }, - "src/app/(dashboard)/memory/components/MemoryView.tsx": { - "react-hooks/set-state-in-effect": { + "src/components/ModelSelect/PaginatedModelSelect/PaginatedModelSelect.tsx": { + "no-nested-ternary": { "count": 1 } }, @@ -465,6 +961,9 @@ } }, "src/components/OldTeams.tsx": { + "no-nested-ternary": { + "count": 4 + }, "no-restricted-imports": { "count": 1 }, @@ -472,26 +971,6 @@ "count": 4 } }, - "src/app/(dashboard)/projects/components/ProjectDetailsPage.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/projects/components/ProjectKeysSection.tsx": { - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/projects/components/ProjectModals/ProjectBaseForm.tsx": { - "react-hooks/set-state-in-effect": { - "count": 2 - } - }, - "src/app/(dashboard)/projects/components/ProjectsPage.tsx": { - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, "src/components/SCIM.tsx": { "no-restricted-imports": { "count": 1 @@ -505,33 +984,15 @@ "count": 1 } }, - "src/app/(dashboard)/search-tools/_components/CreateSearchTools.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/search-tools/_components/SearchToolTester.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/search-tools/_components/SearchToolView.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/search-tools/_components/SearchTools.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/static-components": { + "src/components/Settings/AdminSettings/HashicorpVault/HashicorpVault.tsx": { + "no-nested-ternary": { "count": 1 } }, "src/components/Settings/AdminSettings/MCPSemanticFilterSettings/MCPSemanticFilterSettings.tsx": { + "no-nested-ternary": { + "count": 1 + }, "react-hooks/set-state-in-effect": { "count": 1 } @@ -546,6 +1007,11 @@ "count": 1 } }, + "src/components/Settings/AdminSettings/SSOSettings/RedactableField.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, "src/components/Settings/AdminSettings/SSOSettings/SSOSettingsLoadingSkeleton.test.tsx": { "max-nested-callbacks": { "count": 4 @@ -556,7 +1022,15 @@ "count": 2 } }, + "src/components/Settings/AdminSettings/UISettings/UISettings.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, "src/components/Settings/LoggingAndAlerts/LoggingCallbacks/LoggingCallbacksTable.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } @@ -582,12 +1056,20 @@ "count": 1 } }, + "src/components/TeamSSOSettings.test.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, "src/components/ToolDetail.tsx": { "unused-imports/no-unused-imports": { "count": 2 } }, "src/components/ToolPolicies.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 }, @@ -607,6 +1089,9 @@ } }, "src/components/UsageIndicator.tsx": { + "no-nested-ternary": { + "count": 4 + }, "no-restricted-imports": { "count": 1 }, @@ -624,6 +1109,11 @@ "count": 1 } }, + "src/components/UsagePage/components/EndpointUsage/components/EndpointUsageTable.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, "src/components/UsagePage/components/EntityUsage/EntityUsage.tsx": { "no-restricted-imports": { "count": 1 @@ -650,11 +1140,17 @@ } }, "src/components/UsagePage/components/UsageAIChatPanel.tsx": { + "no-nested-ternary": { + "count": 1 + }, "react-hooks/immutability": { "count": 1 } }, "src/components/UsagePage/components/UsagePageView.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 }, @@ -674,16 +1170,25 @@ } }, "src/components/VirtualKeysPage/VirtualKeysTable.tsx": { + "no-nested-ternary": { + "count": 2 + }, "no-restricted-imports": { "count": 1 } }, "src/components/activity_metrics.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } }, "src/components/add_model/AddModelForm.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } @@ -720,11 +1225,22 @@ } }, "src/components/add_model/litellm_model_name.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } }, + "src/components/add_model/model_connection_test.tsx": { + "no-nested-ternary": { + "count": 2 + } + }, "src/components/add_model/provider_specific_fields.tsx": { + "no-nested-ternary": { + "count": 5 + }, "no-restricted-imports": { "count": 1 }, @@ -745,15 +1261,18 @@ "count": 1 } }, - "src/components/agents.tsx": { + "src/app/(dashboard)/agents/_components/AgentsPanel.tsx": { "no-restricted-imports": { "count": 1 }, "react-hooks/set-state-in-effect": { - "count": 2 + "count": 1 } }, - "src/components/agents/add_agent_form.tsx": { + "src/app/(dashboard)/agents/_components/add_agent_form.tsx": { + "no-nested-ternary": { + "count": 3 + }, "no-restricted-imports": { "count": 1 }, @@ -764,7 +1283,7 @@ "count": 1 } }, - "src/components/agents/agent_card_discovery.tsx": { + "src/app/(dashboard)/agents/_components/agent_card_discovery.tsx": { "react-hooks/refs": { "count": 3 }, @@ -772,12 +1291,20 @@ "count": 1 } }, - "src/components/agents/agent_cost_view.tsx": { + "src/app/(dashboard)/agents/_components/agent_cost_view.tsx": { "no-restricted-imports": { "count": 1 } }, - "src/components/agents/agent_info.tsx": { + "src/app/(dashboard)/agents/_components/agent_form_fields.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, + "src/app/(dashboard)/agents/_components/agent_info.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 }, @@ -785,27 +1312,20 @@ "count": 1 } }, - "src/components/alerting/dynamic_form.tsx": { - "no-restricted-imports": { + "src/app/(dashboard)/agents/_components/agent_virtual_keys.tsx": { + "no-nested-ternary": { "count": 1 } }, - "src/app/(dashboard)/budgets/components/budget_modal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/budgets/components/budget_panel.test.tsx": { - "unused-imports/no-unused-imports": { + "src/app/(dashboard)/agents/_components/dynamic_agent_form_fields.tsx": { + "no-nested-ternary": { "count": 2 } }, - "src/app/(dashboard)/budgets/components/budget_panel.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/budgets/components/edit_budget_modal.tsx": { + "src/components/alerting/dynamic_form.tsx": { + "no-nested-ternary": { + "count": 4 + }, "no-restricted-imports": { "count": 1 } @@ -818,41 +1338,32 @@ "count": 1 } }, - "src/app/(dashboard)/caching/components/cache_dashboard.tsx": { - "no-restricted-imports": { + "src/components/chat/KeysPanel.tsx": { + "no-nested-ternary": { "count": 1 - }, - "react-hooks/purity": { + } + }, + "src/components/chat/MCPAppsPanel.tsx": { + "no-nested-ternary": { + "count": 7 + } + }, + "src/components/chat/MCPConnectPicker.tsx": { + "no-nested-ternary": { "count": 1 - }, - "react-hooks/set-state-in-effect": { + } + }, + "src/components/chat/MCPCredentialsTab.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, + "src/components/chat/UsagePanel.tsx": { + "no-nested-ternary": { "count": 2 } }, - "src/app/(dashboard)/caching/components/cache_health.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/caching/components/cache_settings/CacheFieldRenderer.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/caching/components/cache_settings/RedisTypeSelector.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/caching/components/cache_settings/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/components/claude_code_plugins.tsx": { + "src/app/(dashboard)/skills/_components/ClaudeCodePluginsPanel.tsx": { "no-restricted-imports": { "count": 1 }, @@ -868,17 +1379,15 @@ "count": 1 } }, - "src/components/claude_code_plugins/add_plugin_form.tsx": { + "src/app/(dashboard)/skills/_components/add_plugin_form.tsx": { "no-restricted-imports": { "count": 1 } }, - "src/components/claude_code_plugins/helpers.test.ts": { - "unused-imports/no-unused-imports": { + "src/app/(dashboard)/skills/_components/plugin_table.tsx": { + "no-nested-ternary": { "count": 1 - } - }, - "src/components/claude_code_plugins/plugin_table.tsx": { + }, "no-restricted-imports": { "count": 1 } @@ -969,6 +1478,9 @@ } }, "src/components/common_components/chartUtils.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } @@ -984,6 +1496,9 @@ } }, "src/components/common_components/simple_table.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } @@ -1006,11 +1521,6 @@ "count": 1 } }, - "src/components/edit_user.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "src/components/email_events/email_event_settings.tsx": { "no-restricted-imports": { "count": 1 @@ -1024,32 +1534,38 @@ "count": 1 } }, - "src/components/general_settings.tsx": { + "src/app/(dashboard)/guardrails/_components/GuardrailsPanel.tsx": { + "react-hooks/set-state-in-effect": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/GuardrailTestPanel.tsx": { "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/GuardrailTestPlayground.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/GuardrailTestResults.tsx": { + "no-restricted-imports": { + "count": 1 + } + }, + "src/app/(dashboard)/guardrails/_components/TeamGuardrailsTab.tsx": { + "no-nested-ternary": { "count": 2 - } - }, - "src/components/guardrails.tsx": { + }, "react-hooks/set-state-in-effect": { "count": 1 } }, - "src/components/guardrails/GuardrailTestPanel.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/components/guardrails/GuardrailTestResults.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/components/guardrails/TeamGuardrailsTab.tsx": { - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/components/guardrails/add_guardrail_form.tsx": { + "src/app/(dashboard)/guardrails/_components/add_guardrail_form.tsx": { + "no-nested-ternary": { + "count": 4 + }, "react-hooks/set-state-in-effect": { "count": 1 }, @@ -1057,22 +1573,28 @@ "count": 2 } }, - "src/components/guardrails/content_filter/CompetitorIntentConfiguration.tsx": { + "src/app/(dashboard)/guardrails/_components/content_filter/CompetitorIntentConfiguration.tsx": { + "no-nested-ternary": { + "count": 1 + }, "react-hooks/set-state-in-effect": { "count": 1 } }, - "src/components/guardrails/content_filter/ContentCategoryConfiguration.tsx": { + "src/app/(dashboard)/guardrails/_components/content_filter/ContentCategoryConfiguration.tsx": { + "no-nested-ternary": { + "count": 3 + }, "react-hooks/set-state-in-effect": { "count": 1 } }, - "src/components/guardrails/content_filter/ContentFilterDisplay.tsx": { + "src/app/(dashboard)/guardrails/_components/content_filter/ContentFilterDisplay.tsx": { "no-restricted-imports": { "count": 1 } }, - "src/components/guardrails/content_filter/ContentFilterManager.tsx": { + "src/app/(dashboard)/guardrails/_components/content_filter/ContentFilterManager.tsx": { "max-params": { "count": 2 }, @@ -1080,7 +1602,10 @@ "count": 1 } }, - "src/components/guardrails/custom_code/CustomCodeModal.tsx": { + "src/app/(dashboard)/guardrails/_components/custom_code/CustomCodeModal.tsx": { + "no-nested-ternary": { + "count": 6 + }, "no-restricted-imports": { "count": 1 }, @@ -1088,7 +1613,7 @@ "count": 1 } }, - "src/components/guardrails/edit_guardrail_form.tsx": { + "src/app/(dashboard)/guardrails/_components/edit_guardrail_form.tsx": { "no-restricted-imports": { "count": 1 }, @@ -1099,7 +1624,7 @@ "count": 1 } }, - "src/components/guardrails/guardrail_info.tsx": { + "src/app/(dashboard)/guardrails/_components/guardrail_info.tsx": { "max-params": { "count": 1 }, @@ -1110,22 +1635,31 @@ "count": 3 } }, - "src/components/guardrails/guardrail_optional_params.tsx": { + "src/app/(dashboard)/guardrails/_components/guardrail_optional_params.tsx": { + "no-nested-ternary": { + "count": 5 + }, "react-hooks/set-state-in-effect": { "count": 1 } }, - "src/components/guardrails/guardrail_provider_fields.tsx": { + "src/app/(dashboard)/guardrails/_components/guardrail_provider_fields.tsx": { + "no-nested-ternary": { + "count": 5 + }, "react-hooks/set-state-in-effect": { "count": 1 } }, - "src/components/guardrails/guardrail_table.tsx": { + "src/app/(dashboard)/guardrails/_components/guardrail_table.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { - "count": 2 + "count": 1 } }, - "src/components/guardrails/tool_permission/ToolPermissionRulesEditor.tsx": { + "src/app/(dashboard)/guardrails/_components/tool_permission/ToolPermissionRulesEditor.tsx": { "no-restricted-imports": { "count": 1 }, @@ -1143,6 +1677,19 @@ "count": 1 } }, + "src/components/llm_calls/chat_completion.tsx": { + "max-params": { + "count": 1 + }, + "no-nested-ternary": { + "count": 1 + } + }, + "src/components/llm_calls/responses_api.tsx": { + "max-params": { + "count": 1 + } + }, "src/components/mcp_hub_table_columns.tsx": { "no-restricted-imports": { "count": 1 @@ -1173,7 +1720,15 @@ "count": 1 } }, + "src/components/mcp_tools/MCPToolArgumentsForm.tsx": { + "no-nested-ternary": { + "count": 5 + } + }, "src/components/mcp_tools/MCPToolsetsTab.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 }, @@ -1185,11 +1740,17 @@ } }, "src/components/mcp_tools/McpCrudPermissionPanel.tsx": { + "no-nested-ternary": { + "count": 3 + }, "no-restricted-imports": { "count": 1 } }, "src/components/mcp_tools/OAuthFormFields.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } @@ -1200,6 +1761,9 @@ } }, "src/components/mcp_tools/ToolTestPanel.tsx": { + "no-nested-ternary": { + "count": 3 + }, "no-restricted-imports": { "count": 1 }, @@ -1207,12 +1771,20 @@ "count": 1 } }, + "src/components/mcp_tools/UserEnvVarsModal.tsx": { + "no-nested-ternary": { + "count": 2 + } + }, "src/components/mcp_tools/create_mcp_server.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 }, "react-hooks/set-state-in-effect": { - "count": 5 + "count": 4 } }, "src/components/mcp_tools/mcp_connect.tsx": { @@ -1224,6 +1796,9 @@ } }, "src/components/mcp_tools/mcp_connection_status.tsx": { + "no-nested-ternary": { + "count": 3 + }, "no-restricted-imports": { "count": 1 } @@ -1244,6 +1819,9 @@ } }, "src/components/mcp_tools/mcp_server_edit.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 }, @@ -1260,6 +1838,9 @@ } }, "src/components/mcp_tools/mcp_servers.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 }, @@ -1273,6 +1854,9 @@ } }, "src/components/mcp_tools/mcp_tools.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 }, @@ -1304,6 +1888,9 @@ } }, "src/components/model_dashboard/HealthCheckComponent.tsx": { + "no-nested-ternary": { + "count": 3 + }, "no-restricted-imports": { "count": 1 }, @@ -1312,6 +1899,9 @@ } }, "src/components/model_dashboard/all_models_table.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } @@ -1320,11 +1910,17 @@ "max-params": { "count": 1 }, + "no-nested-ternary": { + "count": 2 + }, "no-restricted-imports": { "count": 1 } }, "src/components/model_dashboard/table.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } @@ -1348,6 +1944,9 @@ } }, "src/components/model_info_view.tsx": { + "no-nested-ternary": { + "count": 14 + }, "no-restricted-imports": { "count": 1 }, @@ -1356,6 +1955,9 @@ } }, "src/components/molecules/filter.tsx": { + "no-nested-ternary": { + "count": 2 + }, "react-hooks/use-memo": { "count": 1 } @@ -1372,6 +1974,9 @@ "max-params": { "count": 1 }, + "no-nested-ternary": { + "count": 2 + }, "no-restricted-imports": { "count": 1 } @@ -1385,6 +1990,9 @@ "max-params": { "count": 23 }, + "no-nested-ternary": { + "count": 5 + }, "no-restricted-syntax": { "count": 154 } @@ -1426,11 +2034,6 @@ "count": 1 } }, - "src/components/organizations.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "src/components/page_utils.test.ts": { "max-nested-callbacks": { "count": 3 @@ -1460,6 +2063,9 @@ } }, "src/components/permissions/MCPServerPermissions.tsx": { + "no-nested-ternary": { + "count": 3 + }, "no-restricted-imports": { "count": 1 } @@ -1469,133 +2075,12 @@ "count": 1 } }, - "src/app/(dashboard)/playground/components/chat_ui/AdditionalModelSettings.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 2 - } - }, - "src/app/(dashboard)/playground/components/chat_ui/AgentBuilderView.tsx": { - "react-hooks/set-state-in-effect": { - "count": 5 - } - }, - "src/app/(dashboard)/playground/components/chat_ui/ChatImageUtils.test.tsx": { - "max-nested-callbacks": { + "src/components/policies/PolicySelector.tsx": { + "no-nested-ternary": { "count": 1 } }, - "src/app/(dashboard)/playground/components/chat_ui/ChatUI.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 4 - }, - "unused-imports/no-unused-imports": { - "count": 13 - } - }, - "src/app/(dashboard)/playground/components/chat_ui/CodeInterpreterOutput.tsx": { - "no-restricted-syntax": { - "count": 2 - } - }, - "src/app/(dashboard)/playground/components/chat_ui/CodeInterpreterTool.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/playground/components/chat_ui/RealtimePlayground.tsx": { - "react-hooks/immutability": { - "count": 2 - }, - "react-hooks/preserve-manual-memoization": { - "count": 1 - } - }, - "src/app/(dashboard)/playground/components/compareUI/CompareUI.tsx": { - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/playground/components/compareUI/components/ModelSelector.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/playground/components/complianceUI/ComplianceUI.tsx": { - "react-hooks/preserve-manual-memoization": { - "count": 3 - } - }, - "src/app/(dashboard)/playground/llm_calls/a2a_send_message.tsx": { - "max-params": { - "count": 2 - }, - "no-restricted-syntax": { - "count": 2 - } - }, - "src/app/(dashboard)/playground/llm_calls/anthropic_messages.tsx": { - "max-params": { - "count": 1 - } - }, - "src/app/(dashboard)/playground/llm_calls/audio_speech.tsx": { - "max-params": { - "count": 1 - } - }, - "src/app/(dashboard)/playground/llm_calls/audio_transcriptions.tsx": { - "max-params": { - "count": 1 - } - }, - "src/components/llm_calls/chat_completion.tsx": { - "max-params": { - "count": 1 - } - }, - "src/app/(dashboard)/playground/llm_calls/embeddings_api.tsx": { - "max-params": { - "count": 1 - }, - "no-restricted-syntax": { - "count": 1 - } - }, - "src/app/(dashboard)/playground/llm_calls/fetch_agents.tsx": { - "no-restricted-syntax": { - "count": 1 - } - }, - "src/app/(dashboard)/playground/llm_calls/image_edits.tsx": { - "max-params": { - "count": 1 - } - }, - "src/app/(dashboard)/playground/llm_calls/image_generation.tsx": { - "max-params": { - "count": 1 - } - }, - "src/app/(dashboard)/playground/llm_calls/interactions_api.tsx": { - "max-params": { - "count": 1 - }, - "no-restricted-syntax": { - "count": 1 - } - }, - "src/components/llm_calls/responses_api.tsx": { - "max-params": { - "count": 1 - } - }, - "src/components/policies/add_attachment_form.tsx": { + "src/app/(dashboard)/policies/_components/add_attachment_form.tsx": { "no-restricted-imports": { "count": 1 }, @@ -1603,7 +2088,7 @@ "count": 1 } }, - "src/components/policies/add_policy_form.tsx": { + "src/app/(dashboard)/policies/_components/add_policy_form.tsx": { "no-restricted-imports": { "count": 1 }, @@ -1614,7 +2099,10 @@ "count": 1 } }, - "src/components/policies/ai_suggestion_modal.tsx": { + "src/app/(dashboard)/policies/_components/ai_suggestion_modal.tsx": { + "no-nested-ternary": { + "count": 10 + }, "no-restricted-imports": { "count": 1 }, @@ -1622,37 +2110,46 @@ "count": 1 } }, - "src/components/policies/attachment_table.test.tsx": { + "src/app/(dashboard)/policies/_components/attachment_table.test.tsx": { "react/display-name": { "count": 1 } }, - "src/components/policies/attachment_table.tsx": { + "src/app/(dashboard)/policies/_components/attachment_table.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } }, - "src/components/policies/guardrail_selection_modal.tsx": { + "src/app/(dashboard)/policies/_components/guardrail_selection_modal.tsx": { + "no-nested-ternary": { + "count": 1 + }, "react-hooks/set-state-in-effect": { "count": 1 } }, - "src/components/policies/impact_popover.test.tsx": { + "src/app/(dashboard)/policies/_components/impact_popover.test.tsx": { "react/display-name": { "count": 1 } }, - "src/components/policies/impact_popover.tsx": { + "src/app/(dashboard)/policies/_components/impact_popover.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } }, - "src/components/policies/index.test.tsx": { + "src/app/(dashboard)/policies/_components/index.test.tsx": { "react/display-name": { "count": 1 } }, - "src/components/policies/index.tsx": { + "src/app/(dashboard)/policies/_components/index.tsx": { "no-restricted-imports": { "count": 1 }, @@ -1660,7 +2157,10 @@ "count": 1 } }, - "src/components/policies/pipeline_flow_builder.tsx": { + "src/app/(dashboard)/policies/_components/pipeline_flow_builder.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 }, @@ -1668,7 +2168,7 @@ "count": 2 } }, - "src/components/policies/policy_info.tsx": { + "src/app/(dashboard)/policies/_components/policy_info.tsx": { "no-restricted-imports": { "count": 1 }, @@ -1676,17 +2176,20 @@ "count": 1 } }, - "src/components/policies/policy_table.test.tsx": { + "src/app/(dashboard)/policies/_components/policy_table.test.tsx": { "react/display-name": { "count": 1 } }, - "src/components/policies/policy_table.tsx": { + "src/app/(dashboard)/policies/_components/policy_table.tsx": { + "no-nested-ternary": { + "count": 2 + }, "no-restricted-imports": { "count": 1 } }, - "src/components/policies/policy_test_panel.tsx": { + "src/app/(dashboard)/policies/_components/policy_test_panel.tsx": { "no-restricted-imports": { "count": 1 }, @@ -1694,7 +2197,7 @@ "count": 1 } }, - "src/components/policies/template_parameter_modal.tsx": { + "src/app/(dashboard)/policies/_components/template_parameter_modal.tsx": { "no-restricted-imports": { "count": 1 }, @@ -1710,88 +2213,10 @@ "count": 2 } }, - "src/app/(dashboard)/prompts/components/add_prompt_form.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/prompts/components/prompt_editor_view/DeveloperMessageCard.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/prompts/components/prompt_editor_view/ModelConfigCard.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/prompts/components/prompt_editor_view/PromptCodeSnippets.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/prompts/components/prompt_editor_view/PromptEditorHeader.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/prompts/components/prompt_editor_view/PromptMessagesCard.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/prompts/components/prompt_editor_view/PublishModal.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/prompts/components/prompt_editor_view/ToolsCard.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/prompts/components/prompt_editor_view/VersionHistorySidePanel.test.tsx": { - "max-nested-callbacks": { - "count": 1 - } - }, - "src/app/(dashboard)/prompts/components/prompt_editor_view/VersionHistorySidePanel.tsx": { - "react-hooks/immutability": { - "count": 1 - } - }, - "src/app/(dashboard)/prompts/components/prompt_editor_view/conversation_panel/MessageInput.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/prompts/components/prompt_editor_view/conversation_panel/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/prompts/components/prompt_editor_view/conversation_panel/useConversation.ts": { - "no-restricted-syntax": { - "count": 1 - } - }, - "src/app/(dashboard)/prompts/components/prompt_info.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 2 - } - }, - "src/app/(dashboard)/prompts/components/prompt_table.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "src/components/public_model_hub.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } @@ -1801,12 +2226,25 @@ "count": 1 } }, + "src/components/router_settings/ReliabilityRetriesSection.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, "src/components/routing_groups/index.tsx": { "react-hooks/preserve-manual-memoization": { "count": 1 } }, + "src/components/search_tools/SearchToolSelector.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, "src/components/settings.tsx": { + "no-nested-ternary": { + "count": 2 + }, "no-restricted-imports": { "count": 1 } @@ -1834,17 +2272,17 @@ "count": 1 } }, - "src/components/tag_management/TagTable.tsx": { + "src/app/(dashboard)/tag-management/_components/TagTable.tsx": { "no-restricted-imports": { "count": 1 } }, - "src/components/tag_management/components/CreateTagModal.tsx": { + "src/app/(dashboard)/tag-management/_components/components/CreateTagModal.tsx": { "no-restricted-imports": { "count": 1 } }, - "src/components/tag_management/index.tsx": { + "src/app/(dashboard)/tag-management/_components/index.tsx": { "no-restricted-imports": { "count": 1 }, @@ -1852,7 +2290,7 @@ "count": 1 } }, - "src/components/tag_management/tag_info.tsx": { + "src/app/(dashboard)/tag-management/_components/tag_info.tsx": { "no-restricted-imports": { "count": 1 }, @@ -1861,6 +2299,9 @@ } }, "src/components/team/EditMembership.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } @@ -1871,6 +2312,9 @@ } }, "src/components/team/TeamInfo.tsx": { + "no-nested-ternary": { + "count": 3 + }, "no-restricted-imports": { "count": 1 }, @@ -1879,6 +2323,9 @@ } }, "src/components/team/TeamVirtualKeysTable.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 } @@ -1902,6 +2349,9 @@ } }, "src/components/templates/key_edit_view.tsx": { + "no-nested-ternary": { + "count": 2 + }, "no-restricted-imports": { "count": 1 } @@ -1912,6 +2362,9 @@ } }, "src/components/templates/key_info_view.tsx": { + "no-nested-ternary": { + "count": 1 + }, "no-restricted-imports": { "count": 1 }, @@ -1919,33 +2372,6 @@ "count": 1 } }, - "src/app/(dashboard)/transform-request/TransformRequestPanel.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/app/(dashboard)/ui-theme/UIThemeSettings.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "no-restricted-syntax": { - "count": 3 - }, - "react-hooks/immutability": { - "count": 1 - } - }, - "src/components/usage.tsx": { - "no-restricted-imports": { - "count": 2 - }, - "react-hooks/immutability": { - "count": 1 - }, - "react-hooks/purity": { - "count": 1 - } - }, "src/components/user_agent_activity.tsx": { "no-restricted-imports": { "count": 2 @@ -1962,25 +2388,15 @@ "count": 2 } }, - "src/components/user_edit_view.test.tsx": { - "react/display-name": { + "src/app/(dashboard)/vector-stores/_components/CreateVectorStore.tsx": { + "no-restricted-imports": { "count": 1 } }, - "src/components/user_edit_view.tsx": { - "no-restricted-imports": { - "count": 1 + "src/app/(dashboard)/vector-stores/_components/VectorStoreForm.tsx": { + "no-nested-ternary": { + "count": 2 }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/components/vector_store_management/CreateVectorStore.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/components/vector_store_management/VectorStoreForm.tsx": { "no-restricted-imports": { "count": 1 }, @@ -1988,12 +2404,12 @@ "count": 1 } }, - "src/components/vector_store_management/VectorStoreTable.tsx": { + "src/app/(dashboard)/vector-stores/_components/VectorStoreTable.tsx": { "no-restricted-imports": { "count": 1 } }, - "src/components/vector_store_management/index.tsx": { + "src/app/(dashboard)/vector-stores/_components/index.tsx": { "no-restricted-imports": { "count": 1 }, @@ -2001,7 +2417,7 @@ "count": 1 } }, - "src/components/vector_store_management/vector_store_info.tsx": { + "src/app/(dashboard)/vector-stores/_components/vector_store_info.tsx": { "no-restricted-imports": { "count": 1 }, @@ -2009,12 +2425,38 @@ "count": 1 } }, + "src/components/view_logs/EvalViewer/EvalViewer.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, "src/components/view_logs/GuardrailViewer/CompliancePanel.tsx": { + "no-nested-ternary": { + "count": 2 + }, "react-hooks/set-state-in-effect": { "count": 1 } }, + "src/components/view_logs/GuardrailViewer/ContentFilterDetails.tsx": { + "no-nested-ternary": { + "count": 1 + } + }, + "src/components/view_logs/GuardrailViewer/GuardrailViewer.tsx": { + "no-nested-ternary": { + "count": 4 + } + }, + "src/components/view_logs/LogDetailsDrawer/LogDetailContent.tsx": { + "no-nested-ternary": { + "count": 4 + } + }, "src/components/view_logs/LogDetailsDrawer/LogDetailsDrawer.tsx": { + "no-nested-ternary": { + "count": 3 + }, "react-hooks/set-state-in-effect": { "count": 2 } @@ -2024,14 +2466,19 @@ "count": 2 } }, + "src/components/view_logs/LogDetailsDrawer/prettyMessagesUtils.ts": { + "no-nested-ternary": { + "count": 1 + } + }, "src/components/view_logs/LogDetailsDrawer/useKeyboardNavigation.ts": { "react-hooks/immutability": { "count": 2 } }, - "src/components/view_logs/columns.tsx": { - "no-restricted-imports": { - "count": 1 + "src/components/view_logs/LogsTableToolbar.tsx": { + "no-nested-ternary": { + "count": 4 } }, "src/components/view_logs/index.tsx": { @@ -2043,8 +2490,8 @@ } }, "src/components/view_logs/table.tsx": { - "no-restricted-imports": { - "count": 1 + "no-nested-ternary": { + "count": 2 } }, "src/components/view_user_spend.tsx": { @@ -2052,43 +2499,6 @@ "count": 2 } }, - "src/components/view_users.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/components/view_users/columns.tsx": { - "max-params": { - "count": 1 - }, - "no-restricted-imports": { - "count": 1 - } - }, - "src/components/view_users/table.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "src/components/view_users/user_info_view.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, - "src/app/(dashboard)/workflows/WorkflowRuns.tsx": { - "no-restricted-syntax": { - "count": 3 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } - }, "src/contexts/AuthContext.tsx": { "react-hooks/set-state-in-effect": { "count": 1 @@ -2120,6 +2530,9 @@ } }, "src/hooks/useTestMCPConnection.tsx": { + "no-nested-ternary": { + "count": 1 + }, "react-hooks/set-state-in-effect": { "count": 1 } @@ -2137,19 +2550,14 @@ "count": 1 } }, - "src/utils/dataUtils.test.ts": { - "max-nested-callbacks": { + "src/lib/http/client.ts": { + "no-nested-ternary": { "count": 1 } }, - "tailwind.config.js": { - "@typescript-eslint/no-require-imports": { - "count": 4 - } - }, - "tailwind.config.ts": { - "@typescript-eslint/no-require-imports": { - "count": 3 + "src/utils/dataUtils.test.ts": { + "max-nested-callbacks": { + "count": 1 } }, "tests/CreateKeyPage.expiredToken.test.tsx": { @@ -2167,13 +2575,5 @@ "react/display-name": { "count": 1 } - }, - "src/app/(dashboard)/prompts/components/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, - "react-hooks/set-state-in-effect": { - "count": 1 - } } -} +} \ No newline at end of file diff --git a/ui/litellm-dashboard/eslint.config.mjs b/ui/litellm-dashboard/eslint.config.mjs index 10caebb5196..0cf5b4ff655 100644 --- a/ui/litellm-dashboard/eslint.config.mjs +++ b/ui/litellm-dashboard/eslint.config.mjs @@ -3,6 +3,7 @@ import tseslint from "typescript-eslint"; import nextCoreWebVitals from "eslint-config-next/core-web-vitals"; import prettier from "eslint-config-prettier/flat"; import unusedImports from "eslint-plugin-unused-imports"; +import local from "./scripts/eslint-rules/index.mjs"; const eslintConfig = [ { @@ -13,10 +14,13 @@ const eslintConfig = [ ...nextCoreWebVitals, prettier, { - plugins: { "unused-imports": unusedImports }, + plugins: { "unused-imports": unusedImports, local }, rules: { "unused-imports/no-unused-imports": "error", + "local/no-large-inline-object-arg": "warn", + "local/no-long-condition-chain": "warn", "@typescript-eslint/no-explicit-any": "warn", + "no-console": ["warn", { allow: ["warn", "error"] }], "@typescript-eslint/no-unused-vars": "off", "@typescript-eslint/no-unused-expressions": "off", "@typescript-eslint/ban-ts-comment": "off", @@ -27,6 +31,7 @@ const eslintConfig = [ "no-useless-escape": "off", "no-self-assign": "error", "no-var": "error", + "no-nested-ternary": "error", "react/no-danger": "error", complexity: ["warn", 20], "max-depth": ["warn", 4], diff --git a/ui/litellm-dashboard/knip.json b/ui/litellm-dashboard/knip.json index 6f129398981..afed6b0f90e 100644 --- a/ui/litellm-dashboard/knip.json +++ b/ui/litellm-dashboard/knip.json @@ -1,11 +1,40 @@ { "$schema": "https://unpkg.com/knip@5/schema.json", - "entry": ["scripts/**/*.{ts,mjs}"], + "entry": ["scripts/**/*.{ts,mjs}", "src/components/ui/**/*.{ts,tsx}"], "project": ["src/**/*.{ts,tsx}", "tests/**/*.{ts,tsx}", "scripts/**/*.{ts,mjs}", "e2e_tests/**/*.ts"], "ignore": ["src/lib/http/schema.d.ts"], - "ignoreDependencies": ["openapi-typescript"], + "ignoreDependencies": [ + "openapi-typescript", + "@headlessui/tailwindcss", + "@tailwindcss/forms", + "tailwindcss", + "tw-animate-css" + ], "playwright": { - "config": "e2e_tests/playwright.config.ts", + "config": [ + "e2e_tests/playwright.config.ts", + "e2e_tests/serverRootPath.config.ts", + "e2e_tests/migration.serverRootPath.config.ts" + ], "entry": ["e2e_tests/**/*.spec.ts", "e2e_tests/**/*.setup.ts", "e2e_tests/globalSetup.ts"] + }, + "vitest": { + "config": ["vitest.config.ts"] + }, + "rules": { + "files": "error", + "dependencies": "error", + "devDependencies": "error", + "optionalPeerDependencies": "error", + "unlisted": "error", + "binaries": "error", + "unresolved": "error", + "exports": "warn", + "nsExports": "warn", + "types": "warn", + "nsTypes": "warn", + "enumMembers": "warn", + "classMembers": "warn", + "duplicates": "warn" } } diff --git a/ui/litellm-dashboard/next.config.mjs b/ui/litellm-dashboard/next.config.mjs index 19a2ca298fe..876df2b49cf 100644 --- a/ui/litellm-dashboard/next.config.mjs +++ b/ui/litellm-dashboard/next.config.mjs @@ -7,6 +7,9 @@ const __dirname = path.dirname(__filename); const nextConfig = { output: "export", + compiler: { + removeConsole: process.env.NODE_ENV === "production" ? { exclude: ["error", "warn"] } : false, + }, // Required with output: "export" — default image optimizer runs only in server mode. // See https://nextjs.org/docs/messages/export-image-api images: { diff --git a/ui/litellm-dashboard/package-lock.json b/ui/litellm-dashboard/package-lock.json index 2afc145d15b..49fdb38c47b 100644 --- a/ui/litellm-dashboard/package-lock.json +++ b/ui/litellm-dashboard/package-lock.json @@ -8,7 +8,10 @@ "name": "litellm-dashboard", "version": "0.1.0", "dependencies": { + "@ant-design/cssinjs": "1.24.0", + "@ant-design/icons": "5.6.1", "@anthropic-ai/sdk": "0.92.0", + "@base-ui/react": "^1.6.0", "@headlessui/tailwindcss": "0.2.2", "@heroicons/react": "1.0.6", "@tanstack/react-pacer": "0.2.0", @@ -18,6 +21,7 @@ "@types/papaparse": "5.5.2", "antd": "5.29.3", "cva": "1.0.0-beta.4", + "date-fns": "^4.4.0", "dayjs": "1.11.19", "jwt-decode": "4.0.0", "lucide-react": "0.513.0", @@ -31,6 +35,7 @@ "react-json-view-lite": "2.5.0", "react-markdown": "9.1.0", "react-syntax-highlighter": "15.6.6", + "recharts": "3.9.2", "remark-gfm": "4.0.1", "tailwind-merge": "3.4.0", "uuid": "14.0.0" @@ -39,6 +44,7 @@ "@eslint/js": "9.39.2", "@playwright/test": "1.58.1", "@tailwindcss/forms": "0.5.11", + "@tailwindcss/postcss": "4.3.2", "@testing-library/dom": "10.4.1", "@testing-library/jest-dom": "6.9.1", "@testing-library/react": "16.3.2", @@ -51,7 +57,6 @@ "@types/react-syntax-highlighter": "15.5.13", "@vitest/coverage-v8": "3.2.6", "@vitest/ui": "3.2.6", - "autoprefixer": "10.4.24", "eslint": "9.39.2", "eslint-config-next": "16.2.6", "eslint-config-prettier": "10.1.8", @@ -61,7 +66,8 @@ "openapi-typescript": "7.13.0", "postcss": "8.5.13", "prettier": "3.2.5", - "tailwindcss": "3.4.19", + "tailwindcss": "4.3.2", + "tw-animate-css": "1.4.0", "typescript": "5.9.3", "typescript-eslint": "8.60.1", "vitest": "3.2.6" @@ -89,6 +95,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -555,6 +562,79 @@ "node": ">=6.9.0" } }, + "node_modules/@base-ui/react": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@base-ui/react/-/react-1.6.0.tgz", + "integrity": "sha512-/jzjTWJYXhRFO45Bev9lc3cHbmjzCMpUqbMZ2AgKy/z25mY9B6shGSNcXcjQar9n5doM0KYW1W8fcFv2jZBuMw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.29.2", + "@base-ui/utils": "0.3.1", + "@floating-ui/react-dom": "^2.1.8", + "@floating-ui/utils": "^0.2.11", + "use-sync-external-store": "^1.6.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@date-fns/tz": "^1.2.0", + "@types/react": "^17 || ^18 || ^19", + "date-fns": "^4.0.0", + "react": "^17 || ^18 || ^19", + "react-dom": "^17 || ^18 || ^19" + }, + "peerDependenciesMeta": { + "@date-fns/tz": { + "optional": true + }, + "@types/react": { + "optional": true + }, + "date-fns": { + "optional": true + } + } + }, + "node_modules/@base-ui/react/node_modules/@floating-ui/react-dom": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", + "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.7.6" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@base-ui/utils": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@base-ui/utils/-/utils-0.3.1.tgz", + "integrity": "sha512-gFFiltORVmW/N6IILTGxizP3PBpVpysqML1ALY5Vk0mH+7faVkCknOU31goYHN5Aoek2dkjxva1XOD2Ce9WuIg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.29.2", + "@floating-ui/utils": "^0.2.11", + "reselect": "^5.2.0", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "@types/react": "^17 || ^18 || ^19", + "react": "^17 || ^18 || ^19", + "react-dom": "^17 || ^18 || ^19" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@bcoe/v8-coverage": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", @@ -2048,6 +2128,7 @@ "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -2069,6 +2150,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -2078,12 +2160,14 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -2091,14 +2175,14 @@ } }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", - "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", + "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@tybys/wasm-util": "^0.10.1" + "@tybys/wasm-util": "^0.10.3" }, "funding": { "type": "github", @@ -2257,6 +2341,7 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -2270,6 +2355,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -2279,6 +2365,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -2842,6 +2929,32 @@ "npm": ">=9.5.0" } }, + "node_modules/@reduxjs/toolkit": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.12.0.tgz", + "integrity": "sha512-KiT+RzZbp6mQET+Mg+h2c97+9j1sNflUxQkIHI7Yuzf6Peu+OYpmkn6nbHWmLLWj+1ZODUJFwGZ7gx3L9R9EOw==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^11.0.0", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.61.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.61.1.tgz", @@ -3199,10 +3312,22 @@ "dev": true, "license": "MIT" }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, "node_modules/@swc/helpers": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.21.tgz", - "integrity": "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==", + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.8.0" @@ -3221,6 +3346,277 @@ "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1" } }, + "node_modules/@tailwindcss/node": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.2.tgz", + "integrity": "sha512-yWP/sqEcBLaD8JuA6zNwxoYKr75qxTioYwlRwekj5Jr/I5GXnoJfjetH/psLUIv74cYTH2lBUEzBkinthoYcBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "5.21.6", + "jiti": "^2.7.0", + "lightningcss": "1.32.0", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.3.2" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.2.tgz", + "integrity": "sha512-z8ZgnzX8gdNoWLBLqBPoh/sjnxkwvf9ZuWjnO0l0yIzbLa5/9S+eC5QxGZKRobVHIC3/1BoMWjHblqWjcgFgag==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.3.2", + "@tailwindcss/oxide-darwin-arm64": "4.3.2", + "@tailwindcss/oxide-darwin-x64": "4.3.2", + "@tailwindcss/oxide-freebsd-x64": "4.3.2", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.2", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.2", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.2", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.2", + "@tailwindcss/oxide-linux-x64-musl": "4.3.2", + "@tailwindcss/oxide-wasm32-wasi": "4.3.2", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.2", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.2" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.2.tgz", + "integrity": "sha512-WHxqIuHpvZ5VtdX6GTl1Ik/Vp2YuN42Et+0CdeaVd/frQ9jAvGmvR8vLT+jk3e8/Q3x8kECB9+R17pgpp2BulA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.2.tgz", + "integrity": "sha512-GZypeUY/IDJW3877KeM+O67vbXr3MBnbtEL4aYhNErv/JWZhye2vGSWWG9tB6iiqR2MqRNkY8IOUy4NdSZV26w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.2.tgz", + "integrity": "sha512-UIIzmefR6KO1sDU7MzRqAxC8iBpft/VhkGjTjnhoS6k7Z3rQ9wEgA1ODSiyH/tcSYssulNm4Ci3hOeK1jH7ccQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.2.tgz", + "integrity": "sha512-GN+uAmcI6DNspnCDwtOAZrTz6oukJnp337qZvxqCGLd3BHBzJpO0ZbTLRvJNdztOeAmTzewewGIMPb0tk2R4WA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.2.tgz", + "integrity": "sha512-4ABn7qSbdHRwTiDiuWNegCyb5+2FJ4vKIKc3DmKrvAFw7MU1Lm11dIkTPwUaFdTzc7IsOpDbqBrlh0x6y36U/w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.2.tgz", + "integrity": "sha512-wDgEIGwoM8w8pufh9LVt1PahDgNdKXrLC2qfAnV3vAmococ9RWbxeAw4pxPttd/TsJfwjyLf90Dg1y9y8I6Emw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.2.tgz", + "integrity": "sha512-J5Nuk0uZQIiMTJj3LEx4sAA9tMFUoXQZFv1J6An+QGYe53HKRJuFDi0rpq/tuouCZeAbOBY3kQ6g8qeD4TUjtA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.2.tgz", + "integrity": "sha512-kqCZpSKOBEJO4mz7OqWoofBZeXTAwaVGPj0ErAj7CojmhKpWVWVOnrt9dE8odoIraZq4oj3ausM37kXi+Tow8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.2.tgz", + "integrity": "sha512-cixpqbh2toJDmkuCRI68nXA8ZxNmdK9Y+9v5h3MC3ZQKy/0BO8AWzlkWyRM7JAFSGBlfig4YVTPsK6MVgqz1uw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.2.tgz", + "integrity": "sha512-4ec2Z/LOmRsAgU23CS4xeJfcJlmRg94A/XrbGRCF1gyU/zdDfRLYDVsS+ynSZCmGNxQ1jQriQOKMQeQxBA3Isw==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.11.1", + "@emnapi/runtime": "^1.11.1", + "@emnapi/wasi-threads": "^1.2.2", + "@napi-rs/wasm-runtime": "^1.1.4", + "@tybys/wasm-util": "^0.10.2", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.2.tgz", + "integrity": "sha512-Zyr/M0+XcYZu3bZrUytc7TXvrk0ftWfl8gN2MwekNDzhqhKRUucMPSeOzM0o0wH5AWOU49BsKRrfKxI2atCPMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.2.tgz", + "integrity": "sha512-QI9BO7KlNZsp2GuO0jwAAj5jCDABOKXRkCk2XuKTSaNEFSdfzqswYVTtCHBNKHLsqyjFyFkqlDiwkNbTYSssMQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.3.2.tgz", + "integrity": "sha512-rjVWYCa7Ngbi5AarT6k8TkxUG3Wl1QKzHdIZVsjZSzf36Jmo2IKZt/NHRAwly8oDkbBOH0YTu+CHuf9jPxMc+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.3.2", + "@tailwindcss/oxide": "4.3.2", + "postcss": "^8.5.15", + "tailwindcss": "4.3.2" + } + }, "node_modules/@tanstack/pacer": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@tanstack/pacer/-/pacer-0.2.0.tgz", @@ -3448,6 +3844,42 @@ "react-dom": ">=16.6.0" } }, + "node_modules/@tremor/react/node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/@tremor/react/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/@tremor/react/node_modules/recharts": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.4.tgz", + "integrity": "sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw==", + "deprecated": "1.x and 2.x branches are no longer active. Bump to Recharts v3 to receive latest features and bugfixes. See https://github.com/recharts/recharts/wiki/3.0-migration-guide", + "license": "MIT", + "dependencies": { + "clsx": "^2.0.0", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.21", + "react-is": "^18.3.1", + "react-smooth": "^4.0.4", + "recharts-scale": "^0.4.4", + "tiny-invariant": "^1.3.1", + "victory-vendor": "^36.6.8" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/@tremor/react/node_modules/tailwind-merge": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.1.tgz", @@ -3458,10 +3890,32 @@ "url": "https://github.com/sponsors/dcastil" } }, + "node_modules/@tremor/react/node_modules/victory-vendor": { + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", + "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", + "license": "MIT AND ISC", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, "node_modules/@tybys/wasm-util": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", - "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", "dev": true, "license": "MIT", "optional": true, @@ -3713,6 +4167,12 @@ "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", "license": "MIT" }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.60.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.60.1.tgz", @@ -4590,43 +5050,6 @@ "react-dom": ">=16.9.0" } }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "license": "MIT" - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "license": "MIT" - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -4868,43 +5291,6 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, - "node_modules/autoprefixer": { - "version": "10.4.24", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.24.tgz", - "integrity": "sha512-uHZg7N9ULTVbutaIsDRoUkoS8/h3bdsmVJYZ5l3wv8Cp/6UIIoRDm90hZ+BwxUj/hGBEzLxdHNSKuFpn8WOyZw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.28.1", - "caniuse-lite": "^1.0.30001766", - "fraction.js": "^5.3.4", - "picocolors": "^1.1.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -4983,18 +5369,6 @@ "require-from-string": "^2.0.2" } }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/brace-expansion": { "version": "5.0.6", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", @@ -5012,6 +5386,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -5123,15 +5498,6 @@ "node": ">=6" } }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/caniuse-lite": { "version": "1.0.30001791", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001791.tgz", @@ -5253,42 +5619,6 @@ "node": ">= 16" } }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/classnames": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", @@ -5359,15 +5689,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/compute-scroll-into-view": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.1.tgz", @@ -5426,18 +5747,6 @@ "dev": true, "license": "MIT" }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/cssstyle": { "version": "5.3.7", "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz", @@ -5687,9 +5996,9 @@ } }, "node_modules/date-fns": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", - "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.4.0.tgz", + "integrity": "sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w==", "license": "MIT", "funding": { "type": "github", @@ -5820,8 +6129,8 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "devOptional": true, "license": "Apache-2.0", - "optional": true, "engines": { "node": ">=8" } @@ -5839,18 +6148,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "license": "Apache-2.0" - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "license": "MIT" - }, "node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -5909,6 +6206,20 @@ "dev": true, "license": "MIT" }, + "node_modules/enhanced-resolve": { + "version": "5.21.6", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.6.tgz", + "integrity": "sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/entities": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", @@ -6102,6 +6413,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-toolkit": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.49.0.tgz", + "integrity": "sha512-G5iZ6Pc/FNRY/soKZHC+TxGDD83rHUDXxzaWhGCX44vAv/tMs56WMusnm/KMNK+luUPsgA9U28cGr4RDlSzL2g==", + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, "node_modules/esbuild": { "version": "0.28.1", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", @@ -6665,9 +6986,9 @@ } }, "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", "license": "MIT" }, "node_modules/expect-type": { @@ -6694,9 +7015,9 @@ "license": "MIT" }, "node_modules/fast-equals": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.4.0.tgz", - "integrity": "sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.4.1.tgz", + "integrity": "sha512-DjlFSM5Pk9cGcL0q5QXl66eGzx0N6szNgaswwc5ZphlBohjTVJSnGgI+rJVOgOi65qUoQnDZN4nDqi33udtydQ==", "license": "MIT", "engines": { "node": ">=6.0.0" @@ -6750,6 +7071,7 @@ "version": "1.20.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -6782,6 +7104,7 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, "license": "MIT", "engines": { "node": ">=12.0.0" @@ -6819,6 +7142,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -6940,24 +7264,11 @@ "node": ">= 12.20" } }, - "node_modules/fraction.js": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", - "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/rawify" - } - }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -7118,6 +7429,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -7168,6 +7480,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -7483,6 +7802,16 @@ "node": ">= 4" } }, + "node_modules/immer": { + "version": "11.1.11", + "resolved": "https://registry.npmjs.org/immer/-/immer-11.1.11.tgz", + "integrity": "sha512-qzXuyXAkPySAGYkfsAwodDPWT8Zm7/Uo5BNt4BjhMhG5WlWyZZ4wQqnWwdS8kjlQ1Cwu6gjw3A6+0gTQwlyYtw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -7641,18 +7970,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-boolean-object": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", @@ -7697,6 +8014,7 @@ "version": "2.16.2", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.3" @@ -7757,6 +8075,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -7802,6 +8121,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -7850,6 +8170,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -8123,10 +8444,10 @@ } }, "node_modules/jiti": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", - "devOptional": true, + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" @@ -8444,23 +8765,266 @@ "node": ">= 0.8.0" } }, - "node_modules/lilconfig": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", - "license": "MIT", + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, "engines": { - "node": ">=14" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/antonk52" + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "license": "MIT" + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, "node_modules/locate-path": { "version": "6.0.0", @@ -8535,9 +9099,9 @@ } }, "node_modules/lru-cache": { - "version": "11.3.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz", - "integrity": "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==", + "version": "11.5.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz", + "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -8913,6 +9477,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -9485,6 +10050,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -9498,6 +10064,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -9608,17 +10175,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, "node_modules/nanoid": { "version": "3.3.12", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", @@ -9713,15 +10269,6 @@ } } }, - "node_modules/next/node_modules/@swc/helpers": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", - "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.8.0" - } - }, "node_modules/node-domexception": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", @@ -9820,15 +10367,6 @@ "dev": true, "license": "MIT" }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -9838,15 +10376,6 @@ "node": ">=0.10.0" } }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -10238,6 +10767,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, "license": "MIT" }, "node_modules/path-scurry": { @@ -10281,9 +10811,10 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -10292,24 +10823,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pirates": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/playwright": { "version": "1.58.1", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.1.tgz", @@ -10390,155 +10903,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-import/node_modules/resolve": { - "version": "1.22.12", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", - "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/postcss-js": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz", - "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "camelcase-css": "^2.0.1" - }, - "engines": { - "node": "^12 || ^14 || >= 16" - }, - "peerDependencies": { - "postcss": "^8.4.21" - } - }, - "node_modules/postcss-load-config": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", - "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "lilconfig": "^3.1.1" - }, - "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "jiti": ">=1.21.0", - "postcss": ">=8.0.9", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - }, - "postcss": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/postcss-nested": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", - "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.1.1" - }, - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "license": "MIT" - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -10620,9 +10984,9 @@ "license": "MIT" }, "node_modules/property-information": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz", + "integrity": "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==", "license": "MIT", "funding": { "type": "github", @@ -10643,6 +11007,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, "funding": [ { "type": "github", @@ -11348,7 +11713,6 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, "license": "MIT" }, "node_modules/react-json-view-lite": { @@ -11390,6 +11754,29 @@ "react": ">=18" } }, + "node_modules/react-redux": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.3.0.tgz", + "integrity": "sha512-KQopgqFo/p/fgmAs5qz6p5RWaNAzq40WAu7fJIXnQpYxFPbJYtsJPWvGeF2rOBaY/kEuV77AVsX8TsQzKm+A/g==", + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, "node_modules/react-smooth": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz", @@ -11465,60 +11852,34 @@ "react-dom": ">=16.8.0" } }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "license": "MIT", - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/recharts": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.4.tgz", - "integrity": "sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.9.2.tgz", + "integrity": "sha512-G4fy+Pk46RaXgwWMh+Nzhyo/lbFAVqXo9gtetlyehe6Ehge9CsgDuOTwQDD+i1+llaLktNBiNq4bhnGlDRXFtw==", "license": "MIT", + "workspaces": [ + "www" + ], "dependencies": { - "clsx": "^2.0.0", - "eventemitter3": "^4.0.1", - "lodash": "^4.17.21", - "react-is": "^18.3.1", - "react-smooth": "^4.0.4", - "recharts-scale": "^0.4.4", - "tiny-invariant": "^1.3.1", - "victory-vendor": "^36.6.8" + "@reduxjs/toolkit": "^1.9.0 || 2.x.x", + "clsx": "^2.1.1", + "decimal.js-light": "^2.5.1", + "es-toolkit": "^1.39.3", + "eventemitter3": "^5.0.1", + "immer": "^11.1.8", + "react-redux": "8.x.x || 9.x.x", + "reselect": "5.2.0", + "tiny-invariant": "^1.3.3", + "use-sync-external-store": "^1.2.2", + "victory-vendor": "^37.0.2" }, "engines": { - "node": ">=14" + "node": ">=18" }, "peerDependencies": { - "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/recharts-scale": { @@ -11530,12 +11891,6 @@ "decimal.js-light": "^2.4.1" } }, - "node_modules/recharts/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT" - }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -11550,6 +11905,21 @@ "node": ">=8" } }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -11777,6 +12147,12 @@ "node": ">=0.10.0" } }, + "node_modules/reselect": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.2.0.tgz", + "integrity": "sha512-AgZ3UOZm3YndfrJ4OYjgrT7bmCm/1iqkjvEfH/oYjzh6PD2qw4QuT3jjnXIrpdt4MTpMXclMT3lXbmRY+XRakw==", + "license": "MIT" + }, "node_modules/resize-observer-polyfill": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", @@ -11831,6 +12207,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -11886,6 +12263,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, "funding": [ { "type": "github", @@ -11992,9 +12370,9 @@ } }, "node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "devOptional": true, "license": "ISC", "bin": { @@ -12522,28 +12900,6 @@ "integrity": "sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==", "license": "MIT" }, - "node_modules/sucrase": { - "version": "3.35.1", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", - "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "tinyglobby": "^0.2.11", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -12561,6 +12917,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -12593,98 +12950,23 @@ } }, "node_modules/tailwindcss": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz", - "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", - "license": "MIT", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.6.0", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.2", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.7", - "lilconfig": "^3.1.3", - "micromatch": "^4.0.8", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.1.1", - "postcss": "^8.4.47", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", - "postcss-nested": "^6.2.0", - "postcss-selector-parser": "^6.1.2", - "resolve": "^1.22.8", - "sucrase": "^3.35.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.2.tgz", + "integrity": "sha512-WtctNNSH8A9jlMIqxzuYumOHU5uGZyRv0Q5svQl+oEPy5w84YpBxdb7MdqyiSPQge5jTJ6zFQLq0PFygdccSBA==", + "license": "MIT" }, - "node_modules/tailwindcss/node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "dev": true, "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/tailwindcss/node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tailwindcss/node_modules/jiti": { - "version": "1.21.7", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", - "license": "MIT", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/tailwindcss/node_modules/resolve": { - "version": "1.22.12", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", - "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/test-exclude": { @@ -12702,27 +12984,6 @@ "node": ">=18" } }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "license": "MIT", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/throttle-debounce": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz", @@ -12756,6 +13017,7 @@ "version": "0.2.16", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", @@ -12822,6 +13084,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -12911,12 +13174,6 @@ "typescript": ">=4.8.4" } }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "license": "Apache-2.0" - }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", @@ -12936,6 +13193,16 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tw-animate-css": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz", + "integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Wombosvideo" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -13282,12 +13549,6 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, "node_modules/uuid": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz", @@ -13330,9 +13591,9 @@ } }, "node_modules/victory-vendor": { - "version": "36.9.2", - "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", - "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", + "version": "37.3.6", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz", + "integrity": "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==", "license": "MIT AND ISC", "dependencies": { "@types/d3-array": "^3.0.3", diff --git a/ui/litellm-dashboard/package.json b/ui/litellm-dashboard/package.json index a8948f4be34..ab01ec70cea 100644 --- a/ui/litellm-dashboard/package.json +++ b/ui/litellm-dashboard/package.json @@ -24,7 +24,10 @@ "gen:api": "node scripts/gen-api-types.mjs" }, "dependencies": { + "@ant-design/cssinjs": "1.24.0", + "@ant-design/icons": "5.6.1", "@anthropic-ai/sdk": "0.92.0", + "@base-ui/react": "^1.6.0", "@headlessui/tailwindcss": "0.2.2", "@heroicons/react": "1.0.6", "@tanstack/react-pacer": "0.2.0", @@ -34,6 +37,7 @@ "@types/papaparse": "5.5.2", "antd": "5.29.3", "cva": "1.0.0-beta.4", + "date-fns": "^4.4.0", "dayjs": "1.11.19", "jwt-decode": "4.0.0", "lucide-react": "0.513.0", @@ -47,6 +51,7 @@ "react-json-view-lite": "2.5.0", "react-markdown": "9.1.0", "react-syntax-highlighter": "15.6.6", + "recharts": "3.9.2", "remark-gfm": "4.0.1", "tailwind-merge": "3.4.0", "uuid": "14.0.0" @@ -55,6 +60,7 @@ "@eslint/js": "9.39.2", "@playwright/test": "1.58.1", "@tailwindcss/forms": "0.5.11", + "@tailwindcss/postcss": "4.3.2", "@testing-library/dom": "10.4.1", "@testing-library/jest-dom": "6.9.1", "@testing-library/react": "16.3.2", @@ -67,7 +73,6 @@ "@types/react-syntax-highlighter": "15.5.13", "@vitest/coverage-v8": "3.2.6", "@vitest/ui": "3.2.6", - "autoprefixer": "10.4.24", "eslint": "9.39.2", "eslint-config-next": "16.2.6", "eslint-config-prettier": "10.1.8", @@ -77,7 +82,8 @@ "openapi-typescript": "7.13.0", "postcss": "8.5.13", "prettier": "3.2.5", - "tailwindcss": "3.4.19", + "tailwindcss": "4.3.2", + "tw-animate-css": "1.4.0", "typescript": "5.9.3", "typescript-eslint": "8.60.1", "vitest": "3.2.6" @@ -92,7 +98,8 @@ "braces": "3.0.3", "axios": "1.13.6", "postcss": "8.5.13", - "esbuild": "0.28.1" + "esbuild": "0.28.1", + "date-fns": "^4.4.0" }, "engines": { "node": ">=20.9.0", diff --git a/ui/litellm-dashboard/postcss.config.js b/ui/litellm-dashboard/postcss.config.js index 12a703d900d..483f378543c 100644 --- a/ui/litellm-dashboard/postcss.config.js +++ b/ui/litellm-dashboard/postcss.config.js @@ -1,6 +1,5 @@ module.exports = { plugins: { - tailwindcss: {}, - autoprefixer: {}, + "@tailwindcss/postcss": {}, }, }; diff --git a/ui/litellm-dashboard/scripts/check-lint-budgets.mjs b/ui/litellm-dashboard/scripts/check-lint-budgets.mjs index a7aba18ae76..db0842fb2ec 100644 --- a/ui/litellm-dashboard/scripts/check-lint-budgets.mjs +++ b/ui/litellm-dashboard/scripts/check-lint-budgets.mjs @@ -1,4 +1,4 @@ -import { readFileSync } from "fs"; +import { readFileSync, writeFileSync } from "fs"; import { countBudgetViolations, findDrift } from "./lint-budget-lib.mjs"; const argv = process.argv.slice(2); @@ -7,6 +7,8 @@ const flags = {}; for (let i = 0; i < argv.length; i += 1) { if (argv[i] === "--check") { flags.check = argv[(i += 1)]; + } else if (argv[i] === "--write") { + flags.write = argv[(i += 1)]; } else { positional.push(argv[i]); } @@ -30,6 +32,11 @@ for (const [rule, { max, target }] of Object.entries(budgets)) { } } +if (flags.write) { + writeFileSync(flags.write, JSON.stringify(counts, null, 2) + "\n"); + console.log(`Wrote ${flags.write}.`); +} + if (flags.check) { const committed = JSON.parse(readFileSync(flags.check, "utf8")); const drift = findDrift(committed, counts); diff --git a/ui/litellm-dashboard/scripts/eslint-rules/index.mjs b/ui/litellm-dashboard/scripts/eslint-rules/index.mjs new file mode 100644 index 00000000000..150ba1d02e9 --- /dev/null +++ b/ui/litellm-dashboard/scripts/eslint-rules/index.mjs @@ -0,0 +1,11 @@ +import noLargeInlineObjectArg from "./no-large-inline-object-arg.mjs"; +import noLongConditionChain from "./no-long-condition-chain.mjs"; + +const plugin = { + rules: { + "no-large-inline-object-arg": noLargeInlineObjectArg, + "no-long-condition-chain": noLongConditionChain, + }, +}; + +export default plugin; diff --git a/ui/litellm-dashboard/scripts/eslint-rules/no-large-inline-object-arg.mjs b/ui/litellm-dashboard/scripts/eslint-rules/no-large-inline-object-arg.mjs new file mode 100644 index 00000000000..5c5ae170e23 --- /dev/null +++ b/ui/litellm-dashboard/scripts/eslint-rules/no-large-inline-object-arg.mjs @@ -0,0 +1,41 @@ +const DEFAULT_MIN_PROPERTIES = 4; + +const isArgumentOf = (node) => { + const parent = node.parent; + if (parent == null) return false; + if (parent.type !== "CallExpression" && parent.type !== "NewExpression") return false; + return parent.arguments.includes(node); +}; + +const rule = { + meta: { + type: "suggestion", + docs: { + description: + "Disallow passing a large object literal inline as a call argument; assign it to a named variable first.", + }, + schema: [ + { + type: "object", + properties: { minProperties: { type: "integer", minimum: 1 } }, + additionalProperties: false, + }, + ], + messages: { + tooLarge: + "Object literal with {{count}} properties passed inline as an argument; assign it to a named variable first.", + }, + }, + create(context) { + const minProperties = context.options[0]?.minProperties ?? DEFAULT_MIN_PROPERTIES; + return { + ObjectExpression(node) { + if (!isArgumentOf(node)) return; + if (node.properties.length < minProperties) return; + context.report({ node, messageId: "tooLarge", data: { count: node.properties.length } }); + }, + }; + }, +}; + +export default rule; diff --git a/ui/litellm-dashboard/scripts/eslint-rules/no-long-condition-chain.mjs b/ui/litellm-dashboard/scripts/eslint-rules/no-long-condition-chain.mjs new file mode 100644 index 00000000000..638e57442e2 --- /dev/null +++ b/ui/litellm-dashboard/scripts/eslint-rules/no-long-condition-chain.mjs @@ -0,0 +1,41 @@ +const DEFAULT_MIN_CONDITIONS = 4; + +const isBooleanLogical = (node) => + node?.type === "LogicalExpression" && (node.operator === "&&" || node.operator === "||"); + +const countConditions = (node) => + isBooleanLogical(node) ? countConditions(node.left) + countConditions(node.right) : 1; + +const rule = { + meta: { + type: "suggestion", + docs: { + description: + "Disallow logical expressions that combine many conditions; extract the condition into a named boolean.", + }, + schema: [ + { + type: "object", + properties: { minConditions: { type: "integer", minimum: 2 } }, + additionalProperties: false, + }, + ], + messages: { + tooMany: "Boolean expression combines {{count}} conditions; extract it into a named variable.", + }, + }, + create(context) { + const minConditions = context.options[0]?.minConditions ?? DEFAULT_MIN_CONDITIONS; + return { + LogicalExpression(node) { + if (!isBooleanLogical(node)) return; + if (isBooleanLogical(node.parent)) return; + const count = countConditions(node); + if (count < minConditions) return; + context.report({ node, messageId: "tooMany", data: { count } }); + }, + }; + }, +}; + +export default rule; diff --git a/ui/litellm-dashboard/scripts/gen-api-types.mjs b/ui/litellm-dashboard/scripts/gen-api-types.mjs index 3c9373ec547..6b9f8581292 100644 --- a/ui/litellm-dashboard/scripts/gen-api-types.mjs +++ b/ui/litellm-dashboard/scripts/gen-api-types.mjs @@ -26,15 +26,26 @@ const python = (process.env.LITELLM_PYTHON ?? "python3").split(" "); // The dashboard calls internal UI routes that the public /openapi.json hides via // include_in_schema=False. Force them in so they get typed here; this mutates a // throwaway interpreter, so the spec the proxy actually serves is unchanged. +// Python 3.13 strips a docstring's common leading indentation at compile time +// while 3.12 keeps it, so the same model yields differently-indented descriptions +// depending on the interpreter — enough to make this output non-reproducible +// across CI and contributors. inspect.cleandoc normalizes every description to one +// canonical form regardless of interpreter, so the generated file is stable. const dumpSpec = [ - "import json, sys", + "import inspect, json, sys", "from litellm.proxy.proxy_server import app", "from fastapi.routing import APIRoute", "for route in app.routes:", " if isinstance(route, APIRoute):", " route.include_in_schema = True", "app.openapi_schema = None", - "with open(sys.argv[1], 'w') as f: json.dump(app.openapi(), f, sort_keys=True)", + "def normalize(node):", + " if isinstance(node, dict):", + " return {k: inspect.cleandoc(v) if k == 'description' and isinstance(v, str) else normalize(v) for k, v in node.items()}", + " if isinstance(node, list):", + " return [normalize(v) for v in node]", + " return node", + "with open(sys.argv[1], 'w') as f: json.dump(normalize(app.openapi()), f, sort_keys=True)", ].join("\n"); try { diff --git a/ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsDetailsPage.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsDetailsPage.test.tsx similarity index 100% rename from ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsDetailsPage.test.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsDetailsPage.test.tsx diff --git a/ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsDetailsPage.tsx b/ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsDetailsPage.tsx similarity index 100% rename from ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsDetailsPage.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsDetailsPage.tsx diff --git a/ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsModal/AccessGroupBaseForm.tsx b/ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsModal/AccessGroupBaseForm.tsx similarity index 100% rename from ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsModal/AccessGroupBaseForm.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsModal/AccessGroupBaseForm.tsx diff --git a/ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsModal/AccessGroupCreateModal.tsx b/ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsModal/AccessGroupCreateModal.tsx similarity index 95% rename from ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsModal/AccessGroupCreateModal.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsModal/AccessGroupCreateModal.tsx index d0a15dbe975..2103701bb67 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsModal/AccessGroupCreateModal.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsModal/AccessGroupCreateModal.tsx @@ -38,9 +38,7 @@ export function AccessGroupCreateModal({ visible, onCancel, onSuccess }: AccessG }, }); }) - .catch((info) => { - console.log("Validate Failed:", info); - }); + .catch((info) => {}); }; return ( diff --git a/ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsModal/AccessGroupEditModal.tsx b/ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsModal/AccessGroupEditModal.tsx similarity index 96% rename from ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsModal/AccessGroupEditModal.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsModal/AccessGroupEditModal.tsx index 875dd75489a..ec557260aa5 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsModal/AccessGroupEditModal.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsModal/AccessGroupEditModal.tsx @@ -52,9 +52,7 @@ export function AccessGroupEditModal({ visible, accessGroup, onCancel, onSuccess }, ); }) - .catch((info) => { - console.log("Validate Failed:", info); - }); + .catch((info) => {}); }; return ( diff --git a/ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsPage.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsPage.test.tsx similarity index 100% rename from ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsPage.test.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsPage.test.tsx diff --git a/ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsPage.tsx b/ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsPage.tsx similarity index 94% rename from ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsPage.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsPage.tsx index c3dd1d54b32..dbbf4e35900 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/AccessGroupsPage.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/AccessGroupsPage.tsx @@ -19,6 +19,7 @@ import { SortState, TableHeaderSortDropdown, } from "@/components/common_components/TableHeaderSortDropdown/TableHeaderSortDropdown"; +import { DateCell, IdCell } from "@/components/shared/table_cells"; import { AccessGroupDetail } from "./AccessGroupsDetailsPage"; import { AccessGroupCreateModal } from "./AccessGroupsModal/AccessGroupCreateModal"; import { AccessGroup } from "./types"; @@ -143,21 +144,7 @@ export function AccessGroupsPage() { header: () => ID, enableSorting: false, size: 170, - cell: ({ row }) => { - const record = row.original; - return ( - - setSelectedGroupId(record.id)} - > - {record.id} - - - ); - }, + cell: ({ row }) => , }, { id: "name", @@ -211,7 +198,7 @@ export function AccessGroupsPage() { header: () => Created, enableSorting: true, sortingFn: "datetime", - cell: ({ getValue }) => new Date(getValue() as string).toLocaleDateString(), + cell: ({ getValue }) => , meta: { responsive: ["lg"] }, }, { @@ -219,7 +206,7 @@ export function AccessGroupsPage() { accessorKey: "updatedAt", header: () => Updated, enableSorting: false, - cell: ({ getValue }) => new Date(getValue() as string).toLocaleDateString(), + cell: ({ getValue }) => , meta: { responsive: ["xl"] }, }, ...(canModify diff --git a/ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/types.ts b/ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/types.ts similarity index 100% rename from ui/litellm-dashboard/src/app/(dashboard)/access-groups/components/types.ts rename to ui/litellm-dashboard/src/app/(dashboard)/access-groups/_components/types.ts diff --git a/ui/litellm-dashboard/src/app/(dashboard)/access-groups/page.tsx b/ui/litellm-dashboard/src/app/(dashboard)/access-groups/page.tsx index ae4712b826e..4e9f7031c6d 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/access-groups/page.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/access-groups/page.tsx @@ -1,6 +1,6 @@ "use client"; -import { AccessGroupsPage } from "./components/AccessGroupsPage"; +import { AccessGroupsPage } from "./_components/AccessGroupsPage"; import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; export default function AccessGroups() { diff --git a/ui/litellm-dashboard/src/components/AdminPanel.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/admin-panel/_components/AdminPanel.test.tsx similarity index 96% rename from ui/litellm-dashboard/src/components/AdminPanel.test.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/admin-panel/_components/AdminPanel.test.tsx index 7d1d2f46cf1..220db23338e 100644 --- a/ui/litellm-dashboard/src/components/AdminPanel.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/admin-panel/_components/AdminPanel.test.tsx @@ -8,34 +8,34 @@ const mockGetAllowedIPs = vi.fn(); const mockAddAllowedIP = vi.fn(); const mockDeleteAllowedIP = vi.fn(); -vi.mock("./networking", () => ({ +vi.mock("@/components/networking", () => ({ getSSOSettings: (...args: unknown[]) => mockGetSSOSettings(...args), getAllowedIPs: (...args: unknown[]) => mockGetAllowedIPs(...args), addAllowedIP: (...args: unknown[]) => mockAddAllowedIP(...args), deleteAllowedIP: (...args: unknown[]) => mockDeleteAllowedIP(...args), })); -vi.mock("./constants", () => ({ +vi.mock("@/components/constants", () => ({ useBaseUrl: () => "http://localhost:4000", })); -vi.mock("./Settings/AdminSettings/SSOSettings/SSOSettings", () => ({ +vi.mock("@/components/Settings/AdminSettings/SSOSettings/SSOSettings", () => ({ default: () =>
SSO Settings
, })); -vi.mock("./Settings/AdminSettings/UISettings/UISettings", () => ({ +vi.mock("@/components/Settings/AdminSettings/UISettings/UISettings", () => ({ default: () =>
UI Settings
, })); -vi.mock("./SCIM", () => ({ +vi.mock("@/components/SCIM", () => ({ default: () =>
SCIM Config
, })); -vi.mock("./SSOModals", () => ({ +vi.mock("@/components/SSOModals", () => ({ default: () =>
SSO Modals
, })); -vi.mock("./UIAccessControlForm", () => ({ +vi.mock("@/components/UIAccessControlForm", () => ({ default: () =>
UI Access Control Form
, })); diff --git a/ui/litellm-dashboard/src/components/AdminPanel.tsx b/ui/litellm-dashboard/src/app/(dashboard)/admin-panel/_components/AdminPanel.tsx similarity index 93% rename from ui/litellm-dashboard/src/components/AdminPanel.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/admin-panel/_components/AdminPanel.tsx index 7867c184ed2..611efd6a588 100644 --- a/ui/litellm-dashboard/src/components/AdminPanel.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/admin-panel/_components/AdminPanel.tsx @@ -16,18 +16,18 @@ import { } from "@tremor/react"; import { Alert, Button as Button2, Form, Input, Modal, Space, Tabs, Typography } from "antd"; import React, { useEffect, useState } from "react"; -import NewBadge from "./common_components/NewBadge"; -import { useBaseUrl } from "./constants"; -import NotificationsManager from "./molecules/notifications_manager"; -import { addAllowedIP, deleteAllowedIP, getAllowedIPs, getSSOSettings } from "./networking"; -import SCIMConfig from "./SCIM"; -import LoggingSettings from "./Settings/AdminSettings/LoggingSettings/LoggingSettings"; -import SSOSettings from "./Settings/AdminSettings/SSOSettings/SSOSettings"; -import UISettings from "./Settings/AdminSettings/UISettings/UISettings"; -import HashicorpVault from "./Settings/AdminSettings/HashicorpVault/HashicorpVault"; -import PluginSettings from "./Settings/AdminSettings/PluginSettings/PluginSettings"; -import SSOModals from "./SSOModals"; -import UIAccessControlForm from "./UIAccessControlForm"; +import NewBadge from "@/components/common_components/NewBadge"; +import { useBaseUrl } from "@/components/constants"; +import NotificationsManager from "@/components/molecules/notifications_manager"; +import { addAllowedIP, deleteAllowedIP, getAllowedIPs, getSSOSettings } from "@/components/networking"; +import SCIMConfig from "@/components/SCIM"; +import LoggingSettings from "@/components/Settings/AdminSettings/LoggingSettings/LoggingSettings"; +import SSOSettings from "@/components/Settings/AdminSettings/SSOSettings/SSOSettings"; +import UISettings from "@/components/Settings/AdminSettings/UISettings/UISettings"; +import HashicorpVault from "@/components/Settings/AdminSettings/HashicorpVault/HashicorpVault"; +import PluginSettings from "@/components/Settings/AdminSettings/PluginSettings/PluginSettings"; +import SSOModals from "@/components/SSOModals"; +import UIAccessControlForm from "@/components/UIAccessControlForm"; const { Title, Paragraph, Text } = Typography; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/admin-panel/page.tsx b/ui/litellm-dashboard/src/app/(dashboard)/admin-panel/page.tsx index aac835b02fc..47076acc9f0 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/admin-panel/page.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/admin-panel/page.tsx @@ -1,6 +1,6 @@ "use client"; -import AdminPanel from "@/components/AdminPanel"; +import AdminPanel from "./_components/AdminPanel"; import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; import useProxySettings from "@/app/(dashboard)/hooks/proxySettings/useProxySettings"; diff --git a/ui/litellm-dashboard/src/components/agents.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/AgentsPanel.test.tsx similarity index 95% rename from ui/litellm-dashboard/src/components/agents.test.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/agents/_components/AgentsPanel.test.tsx index 848b8d5e891..48674f21883 100644 --- a/ui/litellm-dashboard/src/components/agents.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/AgentsPanel.test.tsx @@ -1,19 +1,19 @@ import React from "react"; import { render, screen, waitFor, act, fireEvent, within } from "@testing-library/react"; import { describe, it, expect, vi, beforeEach } from "vitest"; -import AgentsPanel from "./agents"; -import * as networking from "./networking"; +import AgentsPanel from "./AgentsPanel"; +import * as networking from "@/components/networking"; -vi.mock("./networking", () => ({ +vi.mock("@/components/networking", () => ({ getAgentsList: vi.fn().mockResolvedValue({ agents: [] }), deleteAgentCall: vi.fn(), })); -vi.mock("./agents/add_agent_form", () => ({ +vi.mock("./add_agent_form", () => ({ default: () =>
, })); -vi.mock("./agents/agent_info", () => ({ +vi.mock("./agent_info", () => ({ default: () =>
, })); diff --git a/ui/litellm-dashboard/src/components/agents.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/AgentsPanel.tsx similarity index 84% rename from ui/litellm-dashboard/src/components/agents.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/agents/_components/AgentsPanel.tsx index 0d8916942da..84634620426 100644 --- a/ui/litellm-dashboard/src/components/agents.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/AgentsPanel.tsx @@ -13,15 +13,15 @@ import { } from "@tremor/react"; import { Modal, Alert, Tooltip, Skeleton, Switch } from "antd"; import { CheckCircleOutlined } from "@ant-design/icons"; -import { getAgentsList, deleteAgentCall } from "./networking"; -import AddAgentForm from "./agents/add_agent_form"; +import { getAgentsList, deleteAgentCall } from "@/components/networking"; +import AddAgentForm from "./add_agent_form"; import { isAdminRole } from "@/utils/roles"; -import AgentInfoView from "./agents/agent_info"; -import NotificationsManager from "./molecules/notifications_manager"; -import { Agent } from "./agents/types"; -import { Team } from "./key_team_helpers/key_list"; -import { formatNumberWithCommas } from "@/utils/dataUtils"; -import TableIconActionButton from "./common_components/IconActionButton/TableIconActionButtons/TableIconActionButton"; +import AgentInfoView from "./agent_info"; +import NotificationsManager from "@/components/molecules/notifications_manager"; +import { Agent } from "@/components/agents/types"; +import { Team } from "@/components/key_team_helpers/key_list"; +import { DateCell, IdCell, MoneyCell, StatusBadge } from "@/components/shared/table_cells"; +import TableIconActionButton from "@/components/common_components/IconActionButton/TableIconActionButtons/TableIconActionButton"; interface AgentsPanelProps { accessToken: string | null; @@ -193,19 +193,10 @@ const AgentsPanel: React.FC = ({ accessToken, userRole, teams {agent.agent_name} - - - + setSelectedAgentId(id)} /> - {formatNumberWithCommas(agent.spend, 4)} + @@ -213,13 +204,13 @@ const AgentsPanel: React.FC = ({ accessToken, userRole, teams - {agent.created_at ? new Date(agent.created_at).toLocaleDateString() : "N/A"} + {(agent.keys?.length ?? 0) > 0 ? ( - Active + ) : ( - Needs Setup + )} {isAdmin && ( diff --git a/ui/litellm-dashboard/src/components/agents/add_agent_form.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/add_agent_form.tsx similarity index 98% rename from ui/litellm-dashboard/src/components/agents/add_agent_form.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/agents/_components/add_agent_form.tsx index 77236c23a24..8ca2b5afe16 100644 --- a/ui/litellm-dashboard/src/components/agents/add_agent_form.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/add_agent_form.tsx @@ -4,7 +4,7 @@ import MessageManager from "@/components/molecules/message_manager"; import { resolveLogoSrc } from "@/lib/assetPaths"; import { Button } from "@tremor/react"; import { CheckCircleFilled, KeyOutlined, RobotOutlined, AppstoreOutlined, InfoCircleOutlined } from "@ant-design/icons"; -import CreatedKeyDisplay from "../shared/CreatedKeyDisplay"; +import CreatedKeyDisplay from "@/components/shared/CreatedKeyDisplay"; import { createAgentCall, getAgentCreateMetadata, @@ -14,19 +14,19 @@ import { keyUpdateCall, modelAvailableCall, AgentCreateInfo, -} from "../networking"; +} from "@/components/networking"; import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; -import { getModelDisplayName } from "../key_team_helpers/fetch_available_models_team_key"; -import { Team } from "../key_team_helpers/key_list"; -import TeamDropdown from "../common_components/team_dropdown"; +import { getModelDisplayName } from "@/components/key_team_helpers/fetch_available_models_team_key"; +import { Team } from "@/components/key_team_helpers/key_list"; +import TeamDropdown from "@/components/common_components/team_dropdown"; import AgentFormFields from "./agent_form_fields"; import AgentCardDiscovery, { DiscoveredAgentCardSelection } from "./agent_card_discovery"; import { buildDiscoveryRequest, overlayDiscoveredCardParams } from "./agent_discovery_utils"; import DynamicAgentFormFields, { buildDynamicAgentData } from "./dynamic_agent_form_fields"; import { getDefaultFormValues, buildAgentDataFromForm } from "./agent_config"; -import MCPServerSelector from "../mcp_server_management/MCPServerSelector"; -import MCPToolPermissions from "../mcp_server_management/MCPToolPermissions"; -import GuardrailSelector from "../guardrails/GuardrailSelector"; +import MCPServerSelector from "@/components/mcp_server_management/MCPServerSelector"; +import MCPToolPermissions from "@/components/mcp_server_management/MCPToolPermissions"; +import GuardrailSelector from "@/components/guardrails/GuardrailSelector"; const { Step } = Steps; @@ -1010,7 +1010,7 @@ const AddAgentForm: React.FC = ({ visible, onClose, accessTok diff --git a/ui/litellm-dashboard/src/components/agents/agent_card_discovery.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_card_discovery.test.tsx similarity index 97% rename from ui/litellm-dashboard/src/components/agents/agent_card_discovery.test.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_card_discovery.test.tsx index 3a9b7cbb41c..dc70aaa409b 100644 --- a/ui/litellm-dashboard/src/components/agents/agent_card_discovery.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_card_discovery.test.tsx @@ -2,18 +2,18 @@ import React from "react"; import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; import { screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; -import { renderWithProviders } from "../../../tests/test-utils"; +import { renderWithProviders } from "@/../tests/test-utils"; import AgentCardDiscovery from "./agent_card_discovery"; -vi.mock("../networking", async () => { - const actual = await vi.importActual("../networking"); +vi.mock("@/components/networking", async () => { + const actual = await vi.importActual("@/components/networking"); return { ...actual, discoverAgentCardCall: vi.fn(), }; }); -import { discoverAgentCardCall } from "../networking"; +import { discoverAgentCardCall } from "@/components/networking"; const mockDiscover = discoverAgentCardCall as unknown as ReturnType; diff --git a/ui/litellm-dashboard/src/components/agents/agent_card_discovery.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_card_discovery.tsx similarity index 98% rename from ui/litellm-dashboard/src/components/agents/agent_card_discovery.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_card_discovery.tsx index 3fa35419fde..5ea7458f643 100644 --- a/ui/litellm-dashboard/src/components/agents/agent_card_discovery.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_card_discovery.tsx @@ -11,7 +11,7 @@ import { SearchOutlined, } from "@ant-design/icons"; -import { DiscoveredAgentCard, discoverAgentCardCall } from "../networking"; +import { DiscoveredAgentCard, discoverAgentCardCall } from "@/components/networking"; import { ALLOWED_CAPABILITY_KEYS, selectionsFromSavedAgentCard, @@ -249,7 +249,7 @@ const AgentCardDiscovery: React.FC = ({ Using the connection details you entered above. We'll fetch: -
+
{discoveryRequest!.display_url || effectiveUrl || ( Fill in the fields above first )} @@ -409,7 +409,7 @@ const AgentCardDiscovery: React.FC = ({ return (
diff --git a/ui/litellm-dashboard/src/components/agents/agent_config.ts b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_config.ts similarity index 100% rename from ui/litellm-dashboard/src/components/agents/agent_config.ts rename to ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_config.ts diff --git a/ui/litellm-dashboard/src/components/agents/agent_cost_view.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_cost_view.tsx similarity index 95% rename from ui/litellm-dashboard/src/components/agents/agent_cost_view.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_cost_view.tsx index 04837fe823f..e5d88ecc721 100644 --- a/ui/litellm-dashboard/src/components/agents/agent_cost_view.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_cost_view.tsx @@ -1,7 +1,7 @@ import React from "react"; import { Title } from "@tremor/react"; import { Descriptions } from "antd"; -import { Agent } from "./types"; +import { Agent } from "@/components/agents/types"; interface AgentCostViewProps { agent: Agent; diff --git a/ui/litellm-dashboard/src/components/agents/agent_discovery_utils.test.ts b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_discovery_utils.test.ts similarity index 100% rename from ui/litellm-dashboard/src/components/agents/agent_discovery_utils.test.ts rename to ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_discovery_utils.test.ts diff --git a/ui/litellm-dashboard/src/components/agents/agent_discovery_utils.ts b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_discovery_utils.ts similarity index 99% rename from ui/litellm-dashboard/src/components/agents/agent_discovery_utils.ts rename to ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_discovery_utils.ts index 8040bb3089b..fd34ec471eb 100644 --- a/ui/litellm-dashboard/src/components/agents/agent_discovery_utils.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_discovery_utils.ts @@ -1,4 +1,4 @@ -import { AgentCreateInfo, DiscoveredAgentCard, DiscoveryMode } from "../networking"; +import { AgentCreateInfo, DiscoveredAgentCard, DiscoveryMode } from "@/components/networking"; export interface DiscoveryRequestPlan { url: string; diff --git a/ui/litellm-dashboard/src/components/agents/agent_form_fields.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_form_fields.tsx similarity index 100% rename from ui/litellm-dashboard/src/components/agents/agent_form_fields.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_form_fields.tsx diff --git a/ui/litellm-dashboard/src/components/agents/agent_info.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_info.tsx similarity index 98% rename from ui/litellm-dashboard/src/components/agents/agent_info.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_info.tsx index 46ffa9b5ccf..d82ef82df8c 100644 --- a/ui/litellm-dashboard/src/components/agents/agent_info.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_info.tsx @@ -3,11 +3,11 @@ import { Card, Title, Text, Button as TremorButton, Tab, TabGroup, TabList, TabP import { Form, Input, InputNumber, Button as AntButton, Spin, Descriptions, Divider } from "antd"; import MessageManager from "@/components/molecules/message_manager"; import { ArrowLeftIcon } from "@heroicons/react/outline"; -import { getAgentInfo, patchAgentCall, getAgentCreateMetadata, AgentCreateInfo } from "../networking"; -import { Agent } from "./types"; -import { KeyResponse } from "../key_team_helpers/key_list"; +import { getAgentInfo, patchAgentCall, getAgentCreateMetadata, AgentCreateInfo } from "@/components/networking"; +import { Agent } from "@/components/agents/types"; +import { KeyResponse } from "@/components/key_team_helpers/key_list"; import { useKeys } from "@/app/(dashboard)/hooks/keys/useKeys"; -import KeyInfoView from "../templates/key_info_view"; +import KeyInfoView from "@/components/templates/key_info_view"; import AgentVirtualKeys from "./agent_virtual_keys"; import AgentFormFields from "./agent_form_fields"; import DynamicAgentFormFields, { buildDynamicAgentData } from "./dynamic_agent_form_fields"; diff --git a/ui/litellm-dashboard/src/components/agents/agent_type_utils.ts b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_type_utils.ts similarity index 95% rename from ui/litellm-dashboard/src/components/agents/agent_type_utils.ts rename to ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_type_utils.ts index 5bcdd0abe64..f91590c5732 100644 --- a/ui/litellm-dashboard/src/components/agents/agent_type_utils.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_type_utils.ts @@ -1,5 +1,5 @@ -import { Agent } from "./types"; -import { AgentCreateInfo } from "../networking"; +import { Agent } from "@/components/agents/types"; +import { AgentCreateInfo } from "@/components/networking"; /** * Detects the agent type from an agent's litellm_params. diff --git a/ui/litellm-dashboard/src/components/agents/agent_virtual_keys.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_virtual_keys.test.tsx similarity index 93% rename from ui/litellm-dashboard/src/components/agents/agent_virtual_keys.test.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_virtual_keys.test.tsx index 9a58ad557a2..ce13c22dfbf 100644 --- a/ui/litellm-dashboard/src/components/agents/agent_virtual_keys.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_virtual_keys.test.tsx @@ -2,9 +2,9 @@ import React from "react"; import { describe, it, expect, vi } from "vitest"; import { screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; -import { renderWithProviders } from "../../../tests/test-utils"; +import { renderWithProviders } from "@/../tests/test-utils"; import AgentVirtualKeys from "./agent_virtual_keys"; -import type { KeyResponse } from "../key_team_helpers/key_list"; +import type { KeyResponse } from "@/components/key_team_helpers/key_list"; const makeKey = (overrides: Partial): KeyResponse => ({ diff --git a/ui/litellm-dashboard/src/components/agents/agent_virtual_keys.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_virtual_keys.tsx similarity index 92% rename from ui/litellm-dashboard/src/components/agents/agent_virtual_keys.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_virtual_keys.tsx index afc6344c2ef..9a7001ae941 100644 --- a/ui/litellm-dashboard/src/components/agents/agent_virtual_keys.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/agent_virtual_keys.tsx @@ -1,7 +1,7 @@ import React from "react"; import { Button, Tooltip, Typography } from "antd"; import { KeyOutlined } from "@ant-design/icons"; -import { KeyResponse } from "../key_team_helpers/key_list"; +import { KeyResponse } from "@/components/key_team_helpers/key_list"; const { Title, Text } = Typography; @@ -22,7 +22,7 @@ const AgentVirtualKeys: React.FC = ({ keys, isLoading, on ) : (
{keys.map((key) => ( -
+
{key.key_alias || "Unnamed key"} {key.key_name && {key.key_name}} diff --git a/ui/litellm-dashboard/src/components/agents/cost_config_fields.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/cost_config_fields.tsx similarity index 100% rename from ui/litellm-dashboard/src/components/agents/cost_config_fields.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/agents/_components/cost_config_fields.tsx diff --git a/ui/litellm-dashboard/src/components/agents/dynamic_agent_form_fields.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/dynamic_agent_form_fields.tsx similarity index 98% rename from ui/litellm-dashboard/src/components/agents/dynamic_agent_form_fields.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/agents/_components/dynamic_agent_form_fields.tsx index 3edea4362c9..435e628bfc0 100644 --- a/ui/litellm-dashboard/src/components/agents/dynamic_agent_form_fields.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/dynamic_agent_form_fields.tsx @@ -1,6 +1,6 @@ import React from "react"; import { Form, Input, Select, Collapse } from "antd"; -import { AgentCreateInfo, AgentCredentialFieldMetadata } from "../networking"; +import { AgentCreateInfo, AgentCredentialFieldMetadata } from "@/components/networking"; import { AGENT_FORM_CONFIG } from "./agent_config"; import CostConfigFields from "./cost_config_fields"; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/agents/page.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/page.tsx index d60daae13a7..885c9a36f30 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/agents/page.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/page.tsx @@ -1,6 +1,6 @@ "use client"; -import AgentsPanel from "@/components/agents"; +import AgentsPanel from "./_components/AgentsPanel"; import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; import { useTeams } from "@/app/(dashboard)/hooks/teams/useTeams"; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/APIReferenceView.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/APIReferenceView.test.tsx similarity index 97% rename from ui/litellm-dashboard/src/app/(dashboard)/api-reference/APIReferenceView.test.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/APIReferenceView.test.tsx index a73973bd742..66fa0dfa63f 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/APIReferenceView.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/APIReferenceView.test.tsx @@ -2,7 +2,7 @@ import { render } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; import APIReferenceView from "./APIReferenceView"; -vi.mock("./components/CodeBlock", () => ({ +vi.mock("@/components/CodeBlock", () => ({ __esModule: true, default: ({ code }: { code: string }) =>
{code}
, })); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/APIReferenceView.tsx b/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/APIReferenceView.tsx similarity index 97% rename from ui/litellm-dashboard/src/app/(dashboard)/api-reference/APIReferenceView.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/APIReferenceView.tsx index 5861cc87e5b..333bd1cad13 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/APIReferenceView.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/APIReferenceView.tsx @@ -1,8 +1,8 @@ "use client"; import React from "react"; import { Text, Tab, TabGroup, TabList, TabPanel, TabPanels, Grid } from "@tremor/react"; -import CodeBlock from "./components/CodeBlock"; -import DocLink from "@/app/(dashboard)/api-reference/components/DocLink"; +import CodeBlock from "@/components/CodeBlock"; +import DocLink from "./DocLink"; interface ApiRefProps { proxySettings: { diff --git a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/components/DocLink.tsx b/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/DocLink.tsx similarity index 75% rename from ui/litellm-dashboard/src/app/(dashboard)/api-reference/components/DocLink.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/DocLink.tsx index a3d0416053e..a3b34360246 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/components/DocLink.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/api-reference/_components/DocLink.tsx @@ -1,9 +1,7 @@ import React from "react"; import { ExternalLink } from "lucide-react"; -function cn(...parts: Array) { - return parts.filter(Boolean).join(" "); -} +import { cn } from "@/lib/cva.config"; export type DocLinkProps = { href?: string; @@ -18,8 +16,8 @@ const DocLink = ({ href, className }: DocLinkProps) => { rel="noopener noreferrer" title="Open documentation in a new tab" className={cn( - "inline-flex items-center gap-2 rounded-xl border border-zinc-200 bg-white/80 px-3.5 py-2 text-sm font-medium text-zinc-700 shadow-sm", - "hover:bg-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 active:translate-y-[0.5px]", + "inline-flex items-center gap-2 rounded-xl border border-zinc-200 bg-white/80 px-3.5 py-2 text-sm font-medium text-zinc-700 shadow-xs", + "hover:bg-white focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-blue-500 active:translate-y-[0.5px]", className, )} > diff --git a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/page.tsx b/ui/litellm-dashboard/src/app/(dashboard)/api-reference/page.tsx index a4a4d3d0f43..d7c977b0870 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/api-reference/page.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/api-reference/page.tsx @@ -1,6 +1,7 @@ "use client"; -import APIReferenceView from "@/app/(dashboard)/api-reference/APIReferenceView"; +import APIReferenceView from "./_components/APIReferenceView"; +import { DeprecationBanner } from "@/components/DeprecationBanner"; import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; import useProxySettings from "@/app/(dashboard)/hooks/proxySettings/useProxySettings"; @@ -8,7 +9,12 @@ const APIReferencePage = () => { const { accessToken } = useAuthorized(); const proxySettings = useProxySettings(accessToken); - return ; + return ( + <> + + + + ); }; export default APIReferencePage; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/budgets/components/budget_modal.tsx b/ui/litellm-dashboard/src/app/(dashboard)/budgets/_components/budget_modal.tsx similarity index 100% rename from ui/litellm-dashboard/src/app/(dashboard)/budgets/components/budget_modal.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/budgets/_components/budget_modal.tsx diff --git a/ui/litellm-dashboard/src/app/(dashboard)/budgets/components/budget_panel.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/budgets/_components/budget_panel.test.tsx similarity index 100% rename from ui/litellm-dashboard/src/app/(dashboard)/budgets/components/budget_panel.test.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/budgets/_components/budget_panel.test.tsx diff --git a/ui/litellm-dashboard/src/app/(dashboard)/budgets/components/budget_panel.tsx b/ui/litellm-dashboard/src/app/(dashboard)/budgets/_components/budget_panel.tsx similarity index 96% rename from ui/litellm-dashboard/src/app/(dashboard)/budgets/components/budget_panel.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/budgets/_components/budget_panel.tsx index 0e601645c20..af15a99f0b4 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/budgets/components/budget_panel.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/budgets/_components/budget_panel.tsx @@ -25,6 +25,7 @@ import DeleteResourceModal from "@/components/common_components/DeleteResourceMo import TableIconActionButton from "@/components/common_components/IconActionButton/TableIconActionButtons/TableIconActionButton"; import NotificationsManager from "@/components/molecules/notifications_manager"; import { useBudgets, useDeleteBudget, budgetItem } from "@/app/(dashboard)/hooks/budgets/useBudgets"; +import { MoneyCell } from "@/components/shared/table_cells"; import BudgetModal from "./budget_modal"; import EditBudgetModal from "./edit_budget_modal"; import { CREATE_END_USER_CURL_COMMAND, CHAT_COMPLETIONS_CURL_COMMAND, OPENAI_SDK_PYTHON_CODE } from "./constants"; @@ -127,7 +128,9 @@ const BudgetPanel: React.FC = ({ accessToken }) => { .map((value: budgetItem) => ( {value.budget_id} - {value.max_budget ? value.max_budget : "n/a"} + + + {value.tpm_limit ? value.tpm_limit : "n/a"} {value.rpm_limit ? value.rpm_limit : "n/a"} {canModify && ( diff --git a/ui/litellm-dashboard/src/app/(dashboard)/budgets/components/constants.ts b/ui/litellm-dashboard/src/app/(dashboard)/budgets/_components/constants.ts similarity index 100% rename from ui/litellm-dashboard/src/app/(dashboard)/budgets/components/constants.ts rename to ui/litellm-dashboard/src/app/(dashboard)/budgets/_components/constants.ts diff --git a/ui/litellm-dashboard/src/app/(dashboard)/budgets/components/edit_budget_modal.tsx b/ui/litellm-dashboard/src/app/(dashboard)/budgets/_components/edit_budget_modal.tsx similarity index 100% rename from ui/litellm-dashboard/src/app/(dashboard)/budgets/components/edit_budget_modal.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/budgets/_components/edit_budget_modal.tsx diff --git a/ui/litellm-dashboard/src/app/(dashboard)/budgets/page.tsx b/ui/litellm-dashboard/src/app/(dashboard)/budgets/page.tsx index 547699411e7..ca34589a679 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/budgets/page.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/budgets/page.tsx @@ -1,6 +1,6 @@ "use client"; -import BudgetPanel from "./components/budget_panel"; +import BudgetPanel from "./_components/budget_panel"; import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; export default function Budgets() { diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_dashboard.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_dashboard.test.tsx new file mode 100644 index 00000000000..17d14cd7fac --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_dashboard.test.tsx @@ -0,0 +1,135 @@ +import React from "react"; +import { describe, it, expect, vi, beforeEach } from "vitest"; +import { screen, waitFor, within } from "@testing-library/react"; +import { renderWithProviders } from "../../../../../tests/test-utils"; +import CacheDashboard from "./cache_dashboard"; + +const { adminGlobalCacheActivity, cachingHealthCheckCall } = vi.hoisted(() => ({ + adminGlobalCacheActivity: vi.fn(), + cachingHealthCheckCall: vi.fn(), +})); + +vi.mock("@/components/networking", () => ({ + adminGlobalCacheActivity, + cachingHealthCheckCall, +})); + +const cacheActivity = [ + { + api_key: "sk-1", + model: "gpt-5.1", + call_type: "acompletion", + total_rows: 1500, + cache_hit_true_rows: 300, + cached_completion_tokens: 12000, + generated_completion_tokens: 48000, + }, + { + api_key: "sk-2", + model: "text-embedding-3-large", + call_type: "aembedding", + total_rows: 700, + cache_hit_true_rows: 100, + cached_completion_tokens: 2000, + generated_completion_tokens: 9000, + }, +]; + +const renderDashboard = () => + renderWithProviders( + , + ); + +const findChartCards = async () => { + await screen.findByText("Cache Hits vs API Requests"); + await waitFor(() => { + expect(document.querySelectorAll("path.recharts-rectangle").length).toBeGreaterThan(0); + }); + const cards = Array.from(document.querySelectorAll('[data-slot="card"]')); + expect(cards).toHaveLength(2); + return { requestsCard: cards[0] as HTMLElement, tokensCard: cards[1] as HTMLElement }; +}; + +const barFills = (card: HTMLElement) => + Array.from(card.querySelectorAll(".recharts-bar")).map((bar) => + bar.querySelector("path.recharts-rectangle")?.getAttribute("fill"), + ); + +const legendFillByCategory = (card: HTMLElement) => + Object.fromEntries( + Array.from(card.querySelectorAll('.recharts-legend-wrapper [style*="background-color"]')).map((swatch) => [ + swatch.parentElement?.textContent, + swatch.getAttribute("style")?.match(/background-color:\s*([^;]+);?/)?.[1], + ]), + ); + +describe("CacheDashboard cache analytics charts", () => { + beforeEach(() => { + vi.clearAllMocks(); + adminGlobalCacheActivity.mockResolvedValue(cacheActivity); + }); + + it("renders both chart card titles", async () => { + renderDashboard(); + + expect(await screen.findByText("Cache Hits vs API Requests")).toBeInTheDocument(); + expect(screen.getByText("Cached Completion Tokens vs Generated Completion Tokens")).toBeInTheDocument(); + }); + + it("renders the requests chart with each category legend-bound to its fill and stacked in order", async () => { + renderDashboard(); + const { requestsCard } = await findChartCards(); + + expect(legendFillByCategory(requestsCard)).toEqual({ + "LLM API requests": "var(--color-sky-500, #0ea5e9)", + "Cache hit": "var(--color-teal-500, #14b8a6)", + }); + expect(barFills(requestsCard)).toEqual(["var(--color-sky-500, #0ea5e9)", "var(--color-teal-500, #14b8a6)"]); + }); + + it("renders the tokens chart with each category legend-bound to its fill and stacked in order", async () => { + renderDashboard(); + const { tokensCard } = await findChartCards(); + + expect(legendFillByCategory(tokensCard)).toEqual({ + "Generated Completion Tokens": "var(--color-sky-500, #0ea5e9)", + "Cached Completion Tokens": "var(--color-teal-500, #14b8a6)", + }); + expect(barFills(tokensCard)).toEqual(["var(--color-sky-500, #0ea5e9)", "var(--color-teal-500, #14b8a6)"]); + }); + + it("indexes bars by call_type name on the x axis", async () => { + renderDashboard(); + const { requestsCard, tokensCard } = await findChartCards(); + + for (const card of [requestsCard, tokensCard]) { + expect(within(card).getAllByText("acompletion").length).toBeGreaterThan(0); + expect(within(card).getAllByText("aembedding").length).toBeGreaterThan(0); + } + }); + + it("stacks the two categories into one column per call_type", async () => { + renderDashboard(); + const { requestsCard, tokensCard } = await findChartCards(); + + for (const card of [requestsCard, tokensCard]) { + const rects = Array.from(card.querySelectorAll("path.recharts-rectangle")); + expect(rects).toHaveLength(4); + const xPositions = rects.map((rect) => rect.getAttribute("d")?.split(",")[0]); + expect(new Set(xPositions).size).toBe(2); + } + }); + + it("formats y-axis ticks with compact notation", async () => { + renderDashboard(); + const { requestsCard, tokensCard } = await findChartCards(); + + const compactTicks = (card: HTMLElement) => + within(card) + .getAllByText(/^\d+(\.\d+)?K$/) + .map((tick) => tick.textContent); + + expect(compactTicks(requestsCard).length).toBeGreaterThan(0); + expect(compactTicks(tokensCard)).toContain("60K"); + }); +}); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/components/cache_dashboard.tsx b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_dashboard.tsx similarity index 88% rename from ui/litellm-dashboard/src/app/(dashboard)/caching/components/cache_dashboard.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_dashboard.tsx index 99656f0db4a..b8e8dc8adb1 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/caching/components/cache_dashboard.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_dashboard.tsx @@ -1,5 +1,4 @@ import { - BarChart, Card, Col, DateRangePickerValue, @@ -7,7 +6,6 @@ import { Icon, MultiSelect, MultiSelectItem, - Subtitle, Tab, TabGroup, TabList, @@ -18,6 +16,8 @@ import { import React, { useEffect, useState } from "react"; import NotificationsManager from "@/components/molecules/notifications_manager"; import UsageDatePicker from "@/components/shared/usage_date_picker"; +import { BarChart } from "@/components/shared/charts"; +import { Card as ChartCard, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { RefreshIcon } from "@heroicons/react/outline"; import { adminGlobalCacheActivity, cachingHealthCheckCall } from "@/components/networking"; @@ -25,6 +25,7 @@ import { adminGlobalCacheActivity, cachingHealthCheckCall } from "@/components/n // Import the new component import { CacheHealthTab } from "./cache_health"; import CacheSettings from "./cache_settings"; +import CoordinationRedisSettings from "./coordination_redis_settings"; const formatDateWithoutTZ = (date: Date | undefined) => { if (!date) return undefined; @@ -61,13 +62,13 @@ interface cacheDataItem { // Add other properties as needed } -interface uiData { +type uiData = { name: string; "LLM API requests": number; "Cache hit": number; "Cached Completion Tokens": number; "Generated Completion Tokens": number; -} +}; interface CacheHealthResponse { status?: string; @@ -150,7 +151,6 @@ const CacheDashboard: React.FC = ({ accessToken, token, userRole }; useEffect(() => { - console.log("DATA IN CACHE DASHBOARD", data); let newData: cacheDataItem[] = data; if (selectedApiKeys.length > 0) { newData = newData.filter((item) => selectedApiKeys.includes(item.api_key)); @@ -180,16 +180,11 @@ const CacheDashboard: React.FC = ({ accessToken, token, userRole // } // ] - console.log("before processed data in cache dashboard", newData); - let llm_api_requests = 0; let cache_hits = 0; let cached_tokens = 0; const processedData = newData.reduce((acc: uiData[], item) => { - console.log("Processing item:", item); - if (!item.call_type) { - console.log("Item has no call_type:", item); item.call_type = "Unknown"; } @@ -227,8 +222,6 @@ const CacheDashboard: React.FC = ({ accessToken, token, userRole } setFilteredData(processedData); - - console.log("PROCESSED DATA IN CACHE DASHBOARD", processedData); }, [selectedApiKeys, selectedModels, dateValue, data]); const handleRefreshClick = () => { @@ -242,7 +235,6 @@ const CacheDashboard: React.FC = ({ accessToken, token, userRole NotificationsManager.info("Running cache health check..."); setHealthCheckResponse(""); const response = await cachingHealthCheckCall(accessToken !== null ? accessToken : ""); - console.log("CACHING HEALTH CHECK RESPONSE", response); setHealthCheckResponse(response); } catch (error: any) { console.error("Error running health check:", error); @@ -273,6 +265,7 @@ const CacheDashboard: React.FC = ({ accessToken, token, userRole Cache Analytics Cache Health Cache Settings + Coordination Redis
@@ -357,29 +350,41 @@ const CacheDashboard: React.FC = ({ accessToken, token, userRole
- Cache Hits vs API Requests - + + + Cache Hits vs API Requests + + + + + - Cached Completion Tokens vs Generated Completion Tokens - + + + + Cached Completion Tokens vs Generated Completion Tokens + + + + + + @@ -392,6 +397,9 @@ const CacheDashboard: React.FC = ({ accessToken, token, userRole + + + ); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/components/cache_health.tsx b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_health.tsx similarity index 98% rename from ui/litellm-dashboard/src/app/(dashboard)/caching/components/cache_health.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_health.tsx index 92bbc14846f..887c12a4f3d 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/caching/components/cache_health.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_health.tsx @@ -151,7 +151,7 @@ const HealthCheckDetails: React.FC<{ response: any }> = ({ response }) => { }; return ( -
+
Summary @@ -225,7 +225,7 @@ const HealthCheckDetails: React.FC<{ response: any }> = ({ response }) => {
-
+              
                 {(() => {
                   try {
                     const data = {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/CacheFieldSection.tsx b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/CacheFieldSection.tsx
new file mode 100644
index 00000000000..ced822cd796
--- /dev/null
+++ b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/CacheFieldSection.tsx
@@ -0,0 +1,42 @@
+import React from "react";
+import CacheFormField, { EmbeddingModelOption } from "./CacheFormField";
+import { fieldsForSection } from "./cacheSettingsUtils";
+import { CacheSection, RedisType } from "./cacheSettingsFields";
+
+interface CacheFieldSectionProps {
+  title: string;
+  section: CacheSection;
+  redisType: RedisType;
+  embeddingModels: EmbeddingModelOption[];
+  gridCols?: string;
+  headingLevel?: "h4" | "h5";
+}
+
+const CacheFieldSection: React.FC = ({
+  title,
+  section,
+  redisType,
+  embeddingModels,
+  gridCols = "grid-cols-1 gap-6 sm:grid-cols-2",
+  headingLevel = "h4",
+}) => {
+  const fields = fieldsForSection(section, redisType);
+  if (fields.length === 0) {
+    return null;
+  }
+
+  const Heading = headingLevel;
+
+  return (
+    
+ {title} +
+ {fields.map((field) => ( + + ))} +
+
+ ); +}; + +export default CacheFieldSection; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/CacheFormField.tsx b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/CacheFormField.tsx new file mode 100644 index 00000000000..d92ca302901 --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/CacheFormField.tsx @@ -0,0 +1,54 @@ +import { Form, Input, Select, Switch } from "antd"; +import React from "react"; +import { CacheField } from "./cacheSettingsFields"; + +export interface EmbeddingModelOption { + value: string; + label: string; +} + +interface CacheFormFieldProps { + field: CacheField; + embeddingModels: EmbeddingModelOption[]; +} + +const renderControl = (field: CacheField, embeddingModels: EmbeddingModelOption[]): React.ReactNode => { + switch (field.type) { + case "boolean": + return ; + case "password": + return ; + case "integer": + case "float": + return ; + case "list": + return ; + case "model-select": + return ( + ; + } +}; + +const CacheFormField: React.FC = ({ field, embeddingModels }) => ( + + {renderControl(field, embeddingModels)} + +); + +export default CacheFormField; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/components/cache_settings/RedisTypeSelector.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/RedisTypeSelector.test.tsx similarity index 100% rename from ui/litellm-dashboard/src/app/(dashboard)/caching/components/cache_settings/RedisTypeSelector.test.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/RedisTypeSelector.test.tsx diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/components/cache_settings/RedisTypeSelector.tsx b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/RedisTypeSelector.tsx similarity index 94% rename from ui/litellm-dashboard/src/app/(dashboard)/caching/components/cache_settings/RedisTypeSelector.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/RedisTypeSelector.tsx index a94d44dd4e0..fbca7ab5a97 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/caching/components/cache_settings/RedisTypeSelector.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/RedisTypeSelector.tsx @@ -3,7 +3,7 @@ import { Select, SelectItem } from "@tremor/react"; interface RedisTypeSelectorProps { redisType: string; - redisTypeDescriptions: { [key: string]: string }; + redisTypeDescriptions: Readonly>; onTypeChange: (type: string) => void; } diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/cacheSettingsFields.ts b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/cacheSettingsFields.ts new file mode 100644 index 00000000000..1f5b566fc5f --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/cacheSettingsFields.ts @@ -0,0 +1,261 @@ +import type { FormItemProps } from "antd"; + +export type CacheFieldType = "string" | "password" | "integer" | "float" | "boolean" | "list" | "model-select"; + +export type RedisType = "node" | "cluster" | "sentinel" | "semantic"; + +export type CacheSection = "connection" | "cluster" | "sentinel" | "semantic" | "ssl" | "cacheManagement" | "gcp"; + +export type CacheFieldRule = NonNullable[number]; + +export interface CacheField { + readonly name: string; + readonly label: string; + readonly type: CacheFieldType; + readonly section: CacheSection; + readonly helpText: string; + readonly redisType: RedisType | null; + readonly defaultValue?: string | number | boolean; + readonly rules?: CacheFieldRule[]; +} + +export const REDIS_TYPES: readonly RedisType[] = ["node", "cluster", "sentinel", "semantic"]; + +export const REDIS_TYPE_DESCRIPTIONS: Readonly> = { + node: "Standard Redis node/single instance", + cluster: "Redis Cluster mode for high availability and horizontal scaling", + sentinel: "Redis Sentinel mode for high availability with automatic failover", + semantic: "Semantic caching that reuses responses for similar prompts", +}; + +const portRule: CacheFieldRule = { + validator: (_rule, value) => { + if (value === undefined || value === null || String(value).trim() === "") { + return Promise.resolve(); + } + const port = Number(value); + if (!Number.isInteger(port) || port < 1 || port > 65535) { + return Promise.reject(new Error("Port must be an integer between 1 and 65535")); + } + return Promise.resolve(); + }, +}; + +const jsonListRule: CacheFieldRule = { + validator: (_rule, value) => { + if (value === undefined || value === null || String(value).trim() === "") { + return Promise.resolve(); + } + let parsed: unknown; + try { + parsed = JSON.parse(String(value)); + } catch { + return Promise.reject(new Error("Must be a valid JSON array (use double quotes)")); + } + if (!Array.isArray(parsed)) { + return Promise.reject(new Error("Must be a JSON array")); + } + return Promise.resolve(); + }, +}; + +const nonNegativeIntegerRule: CacheFieldRule = { + validator: (_rule, value) => { + if (value === undefined || value === null || String(value).trim() === "") { + return Promise.resolve(); + } + const parsed = Number(value); + if (!Number.isInteger(parsed) || parsed < 0) { + return Promise.reject(new Error("Must be a non-negative integer")); + } + return Promise.resolve(); + }, +}; + +const numberRule: CacheFieldRule = { + validator: (_rule, value) => { + if (value === undefined || value === null || String(value).trim() === "") { + return Promise.resolve(); + } + if (Number.isNaN(Number(value))) { + return Promise.reject(new Error("Must be a number")); + } + return Promise.resolve(); + }, +}; + +export const CACHE_FIELDS: readonly CacheField[] = [ + { + name: "url", + label: "Redis URL", + type: "string", + section: "connection", + helpText: + "Full Redis/Valkey connection URL (e.g. redis://:password@host:6379/1). When set, it takes precedence over Host, Port, Password, and Database Index.", + redisType: null, + }, + { + name: "host", + label: "Host", + type: "string", + section: "connection", + helpText: "Redis server hostname or IP address", + redisType: null, + }, + { + name: "port", + label: "Port", + type: "string", + section: "connection", + helpText: "Redis server port number", + redisType: null, + defaultValue: "6379", + rules: [portRule], + }, + { + name: "db", + label: "Database Index", + type: "integer", + section: "connection", + helpText: "Logical database index to isolate the cache (e.g. 1 for redis://host:6379/1)", + redisType: null, + rules: [nonNegativeIntegerRule], + }, + { + name: "password", + label: "Password", + type: "password", + section: "connection", + helpText: "Redis server password", + redisType: null, + }, + { + name: "username", + label: "Username", + type: "string", + section: "connection", + helpText: "Redis server username (if required)", + redisType: null, + }, + { + name: "redis_startup_nodes", + label: "Startup Nodes", + type: "list", + section: "cluster", + helpText: 'List of startup nodes for Redis Cluster (e.g., [{"host": "127.0.0.1", "port": "7001"}])', + redisType: "cluster", + rules: [jsonListRule], + }, + { + name: "sentinel_nodes", + label: "Sentinel Nodes", + type: "list", + section: "sentinel", + helpText: 'List of Sentinel nodes (e.g., [["localhost", 26379]])', + redisType: "sentinel", + rules: [jsonListRule], + }, + { + name: "service_name", + label: "Service Name", + type: "string", + section: "sentinel", + helpText: "Master service name for Redis Sentinel", + redisType: "sentinel", + }, + { + name: "sentinel_password", + label: "Sentinel Password", + type: "password", + section: "sentinel", + helpText: "Password for Redis Sentinel authentication", + redisType: "sentinel", + }, + { + name: "similarity_threshold", + label: "Similarity Threshold", + type: "float", + section: "semantic", + helpText: "Similarity threshold for semantic cache", + redisType: "semantic", + defaultValue: 0.8, + rules: [numberRule], + }, + { + name: "redis_semantic_cache_embedding_model", + label: "Embedding Model", + type: "model-select", + section: "semantic", + helpText: "Embedding model for semantic cache", + redisType: "semantic", + }, + { + name: "ssl", + label: "SSL", + type: "boolean", + section: "ssl", + helpText: "Enable SSL/TLS connection", + redisType: null, + defaultValue: false, + }, + { + name: "ssl_cert_reqs", + label: "SSL Cert Reqs", + type: "string", + section: "ssl", + helpText: "SSL certificate requirements (None, CERT_REQUIRED, CERT_OPTIONAL)", + redisType: null, + }, + { + name: "ssl_check_hostname", + label: "SSL Check Hostname", + type: "boolean", + section: "ssl", + helpText: "Enable SSL hostname verification", + redisType: null, + defaultValue: false, + }, + { + name: "namespace", + label: "Namespace", + type: "string", + section: "cacheManagement", + helpText: "Namespace prefix for cache keys", + redisType: null, + }, + { + name: "ttl", + label: "TTL (seconds)", + type: "float", + section: "cacheManagement", + helpText: "Time-to-live for cached items in seconds", + redisType: null, + rules: [numberRule], + }, + { + name: "max_connections", + label: "Max Connections", + type: "integer", + section: "cacheManagement", + helpText: "Maximum number of connections in the connection pool", + redisType: null, + rules: [nonNegativeIntegerRule], + }, + { + name: "gcp_service_account", + label: "GCP Service Account", + type: "string", + section: "gcp", + helpText: + "GCP service account for IAM authentication (e.g., projects/-/serviceAccounts/your-sa@project.iam.gserviceaccount.com)", + redisType: null, + }, + { + name: "gcp_ssl_ca_certs", + label: "GCP SSL CA Certs", + type: "string", + section: "gcp", + helpText: "Path to SSL CA certificate file for GCP Memorystore Redis", + redisType: null, + }, +]; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/cacheSettingsUtils.test.ts b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/cacheSettingsUtils.test.ts new file mode 100644 index 00000000000..79f28a97842 --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/cacheSettingsUtils.test.ts @@ -0,0 +1,86 @@ +import { describe, it, expect } from "vitest"; +import { buildCachePayload, buildInitialValues, fieldsForSection } from "./cacheSettingsUtils"; + +describe("fieldsForSection", () => { + it("should only include a redis-type-specific field when that type is selected", () => { + expect(fieldsForSection("cluster", "cluster").map((f) => f.name)).toEqual(["redis_startup_nodes"]); + expect(fieldsForSection("cluster", "node")).toEqual([]); + }); + + it("should include connection fields for every redis type in schema order", () => { + expect(fieldsForSection("connection", "node").map((f) => f.name)).toEqual([ + "url", + "host", + "port", + "db", + "password", + "username", + ]); + }); +}); + +describe("buildInitialValues", () => { + it("should apply defaults as strings for text inputs and coerce booleans", () => { + const values = buildInitialValues({}); + expect(values.port).toBe("6379"); + expect(values.similarity_threshold).toBe("0.8"); + expect(values.ssl).toBe(false); + expect(values.db).toBe(""); + }); + + it("should stringify list values so they render in a textarea", () => { + const nodes = [{ host: "127.0.0.1", port: "7001" }]; + const values = buildInitialValues({ redis_startup_nodes: nodes }); + expect(values.redis_startup_nodes).toBe(JSON.stringify(nodes, null, 2)); + }); + + it("should render numeric current values as strings for their text inputs", () => { + const values = buildInitialValues({ max_connections: 10 }); + expect(values.max_connections).toBe("10"); + }); +}); + +describe("buildCachePayload", () => { + it("should tag the payload as redis and drop empty fields and the UI-only redis_type", () => { + const payload = buildCachePayload("node", { host: "localhost", port: "6379", username: "" }, { forTesting: false }); + expect(payload).toEqual({ + type: "redis", + host: "localhost", + port: "6379", + ssl: false, + ssl_check_hostname: false, + }); + expect(payload).not.toHaveProperty("redis_type"); + expect(payload).not.toHaveProperty("username"); + }); + + it("should parse list fields from their textarea string into arrays", () => { + const payload = buildCachePayload( + "cluster", + { redis_startup_nodes: '[{"host":"127.0.0.1","port":"7001"}]' }, + { forTesting: false }, + ); + expect(payload.redis_startup_nodes).toEqual([{ host: "127.0.0.1", port: "7001" }]); + }); + + it("should omit a list field whose textarea holds invalid JSON", () => { + const payload = buildCachePayload("cluster", { redis_startup_nodes: "not json" }, { forTesting: false }); + expect(payload).not.toHaveProperty("redis_startup_nodes"); + }); + + it("should send type redis-semantic when saving a semantic cache", () => { + const payload = buildCachePayload("semantic", { similarity_threshold: 0.9 }, { forTesting: false }); + expect(payload.type).toBe("redis-semantic"); + expect(payload.similarity_threshold).toBe(0.9); + }); + + it("should keep type redis when testing a semantic cache so the test endpoint accepts it", () => { + const payload = buildCachePayload("semantic", { similarity_threshold: 0.9 }, { forTesting: true }); + expect(payload.type).toBe("redis"); + }); + + it("should exclude fields that do not belong to the selected redis type", () => { + const payload = buildCachePayload("node", { sentinel_nodes: '[["localhost",26379]]' }, { forTesting: false }); + expect(payload).not.toHaveProperty("sentinel_nodes"); + }); +}); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/cacheSettingsUtils.ts b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/cacheSettingsUtils.ts new file mode 100644 index 00000000000..088da21961c --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/cacheSettingsUtils.ts @@ -0,0 +1,81 @@ +import { CACHE_FIELDS, CacheField, CacheSection, RedisType } from "./cacheSettingsFields"; + +export type CacheFormValue = string | number | boolean | undefined; +export type CacheFormValues = Record; +export type CacheSavePayloadValue = string | number | boolean | unknown[]; +export type CacheSavePayload = Record; + +export const isFieldVisible = (field: CacheField, redisType: RedisType): boolean => + field.redisType === null || field.redisType === redisType; + +export const fieldsForSection = (section: CacheSection, redisType: RedisType): CacheField[] => + CACHE_FIELDS.filter((field) => field.section === section && isFieldVisible(field, redisType)); + +const initialValueForField = (field: CacheField, raw: unknown): CacheFormValue => { + const source = raw ?? field.defaultValue; + + if (field.type === "boolean") { + return source === true || source === "true"; + } + + if (field.type === "list") { + if (source === undefined || source === null || source === "") { + return ""; + } + return typeof source === "string" ? source : JSON.stringify(source, null, 2); + } + + if (source === undefined || source === null) { + return ""; + } + return String(source); +}; + +export const buildInitialValues = (currentValues: Record): CacheFormValues => + Object.fromEntries(CACHE_FIELDS.map((field) => [field.name, initialValueForField(field, currentValues[field.name])])); + +const saveValueForField = (field: CacheField, raw: CacheFormValue): CacheSavePayloadValue | undefined => { + if (field.type === "boolean") { + return Boolean(raw); + } + + if (field.type === "list") { + if (typeof raw !== "string" || raw.trim() === "") { + return undefined; + } + try { + return JSON.parse(raw) as unknown[]; + } catch { + return undefined; + } + } + + if (field.type === "integer" || field.type === "float") { + if (raw === undefined || raw === null || raw === "") { + return undefined; + } + const parsed = Number(raw); + return Number.isNaN(parsed) ? undefined : parsed; + } + + if (typeof raw !== "string") { + return raw === undefined ? undefined : String(raw); + } + const trimmed = raw.trim(); + return trimmed === "" ? undefined : trimmed; +}; + +export const buildCachePayload = ( + redisType: RedisType, + values: CacheFormValues, + { forTesting }: { forTesting: boolean }, +): CacheSavePayload => { + const type = !forTesting && redisType === "semantic" ? "redis-semantic" : "redis"; + + const entries = CACHE_FIELDS.filter((field) => isFieldVisible(field, redisType)).flatMap((field) => { + const value = saveValueForField(field, values[field.name]); + return value === undefined ? [] : [[field.name, value] as const]; + }); + + return { type, ...Object.fromEntries(entries) }; +}; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/index.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/index.test.tsx new file mode 100644 index 00000000000..0f768372ad9 --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/index.test.tsx @@ -0,0 +1,147 @@ +import { describe, it, expect, vi, beforeEach } from "vitest"; +import { render, screen, waitFor } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import CacheSettings from "./index"; + +const { getCacheSettingsCall, testCacheConnectionCall, updateCacheSettingsCall } = vi.hoisted(() => ({ + getCacheSettingsCall: vi.fn(), + testCacheConnectionCall: vi.fn(), + updateCacheSettingsCall: vi.fn(), +})); + +vi.mock("@/components/networking", () => ({ + getCacheSettingsCall, + testCacheConnectionCall, + updateCacheSettingsCall, +})); + +vi.mock("@/components/llm_calls/fetch_models", () => ({ + fetchAvailableModels: vi.fn().mockResolvedValue([]), +})); + +const renderSettings = () => render(); + +describe("CacheSettings", () => { + beforeEach(() => { + vi.clearAllMocks(); + getCacheSettingsCall.mockResolvedValue({ current_values: {} }); + updateCacheSettingsCall.mockResolvedValue({ status: "success" }); + testCacheConnectionCall.mockResolvedValue({ status: "success" }); + }); + + it("should render the connection fields once current values load", async () => { + renderSettings(); + expect(await screen.findByText("Connection Settings")).toBeInTheDocument(); + }); + + describe("when the redis type is node", () => { + it("should show the connection fields and hide cluster/sentinel/semantic fields", async () => { + renderSettings(); + + expect(await screen.findByText("Redis URL")).toBeInTheDocument(); + expect(screen.getByText("Database Index")).toBeInTheDocument(); + expect(screen.queryByText("Startup Nodes")).not.toBeInTheDocument(); + expect(screen.queryByText("Sentinel Nodes")).not.toBeInTheDocument(); + expect(screen.queryByText("Embedding Model")).not.toBeInTheDocument(); + }); + }); + + describe("when the redis type is cluster", () => { + it("should reveal the cluster startup nodes field", async () => { + getCacheSettingsCall.mockResolvedValue({ current_values: { redis_type: "cluster" } }); + renderSettings(); + expect(await screen.findByText("Startup Nodes")).toBeInTheDocument(); + }); + }); + + describe("when the redis type is sentinel", () => { + it("should reveal the sentinel fields", async () => { + getCacheSettingsCall.mockResolvedValue({ current_values: { redis_type: "sentinel" } }); + renderSettings(); + expect(await screen.findByText("Sentinel Nodes")).toBeInTheDocument(); + expect(screen.getByText("Service Name")).toBeInTheDocument(); + }); + }); + + describe("when the redis type is semantic", () => { + it("should reveal the semantic fields", async () => { + getCacheSettingsCall.mockResolvedValue({ current_values: { redis_type: "semantic" } }); + renderSettings(); + expect(await screen.findByText("Similarity Threshold")).toBeInTheDocument(); + expect(screen.getByText("Embedding Model")).toBeInTheDocument(); + }); + }); + + describe("when a field fails inline validation", () => { + it("should block save and surface the validation message", async () => { + const user = userEvent.setup(); + renderSettings(); + + const port = await screen.findByLabelText("Port"); + await user.clear(port); + await user.type(port, "99999"); + await user.click(screen.getByRole("button", { name: /save changes/i })); + + expect(await screen.findByText(/Port must be an integer between 1 and 65535/i)).toBeInTheDocument(); + expect(updateCacheSettingsCall).not.toHaveBeenCalled(); + }); + + it("should block save when a list field holds malformed JSON instead of silently dropping it", async () => { + const user = userEvent.setup(); + getCacheSettingsCall.mockResolvedValue({ current_values: { redis_type: "cluster" } }); + renderSettings(); + + const startupNodes = await screen.findByLabelText("Startup Nodes"); + await user.type(startupNodes, "not json"); + await user.click(screen.getByRole("button", { name: /save changes/i })); + + expect(await screen.findByText(/Must be a valid JSON array/i)).toBeInTheDocument(); + expect(updateCacheSettingsCall).not.toHaveBeenCalled(); + }); + + it("should block save with an error when a non-numeric value is entered into a numeric field", async () => { + const user = userEvent.setup(); + renderSettings(); + + const db = await screen.findByLabelText("Database Index"); + await user.type(db, "redis://host:6379/1"); + await user.click(screen.getByRole("button", { name: /save changes/i })); + + expect(await screen.findByText(/Must be a non-negative integer/i)).toBeInTheDocument(); + expect(updateCacheSettingsCall).not.toHaveBeenCalled(); + }); + }); + + describe("when saving a valid node configuration", () => { + it("should send the backend payload shape with type redis and no UI-only fields", async () => { + const user = userEvent.setup(); + renderSettings(); + + const host = await screen.findByLabelText("Host"); + await user.type(host, "localhost"); + await user.click(screen.getByRole("button", { name: /save changes/i })); + + await waitFor(() => + expect(updateCacheSettingsCall).toHaveBeenCalledWith("sk-test", { + type: "redis", + host: "localhost", + port: "6379", + ssl: false, + ssl_check_hostname: false, + }), + ); + }); + + it("should include a numeric field like Database Index in the save payload", async () => { + const user = userEvent.setup(); + renderSettings(); + + await user.type(await screen.findByLabelText("Redis URL"), "redis://host:6379/1"); + await user.type(await screen.findByLabelText("Database Index"), "2"); + await user.click(screen.getByRole("button", { name: /save changes/i })); + + await waitFor(() => expect(updateCacheSettingsCall).toHaveBeenCalled()); + expect(updateCacheSettingsCall.mock.calls[0][1]).toMatchObject({ db: 2, url: "redis://host:6379/1" }); + }); + }); +}); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/index.tsx b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/index.tsx new file mode 100644 index 00000000000..4382769ae9c --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/cache_settings/index.tsx @@ -0,0 +1,228 @@ +import React, { useState, useEffect, useCallback } from "react"; +import { Button, Accordion, AccordionHeader, AccordionBody } from "@tremor/react"; +import { Form } from "antd"; +import { getCacheSettingsCall, testCacheConnectionCall, updateCacheSettingsCall } from "@/components/networking"; +import { fetchAvailableModels, ModelGroup } from "@/components/llm_calls/fetch_models"; +import NotificationsManager from "@/components/molecules/notifications_manager"; +import RedisTypeSelector from "./RedisTypeSelector"; +import CacheFieldSection from "./CacheFieldSection"; +import { EmbeddingModelOption } from "./CacheFormField"; +import { REDIS_TYPES, REDIS_TYPE_DESCRIPTIONS, RedisType } from "./cacheSettingsFields"; +import { buildCachePayload, buildInitialValues, CacheFormValues } from "./cacheSettingsUtils"; + +interface CacheSettingsProps { + accessToken: string | null; + userRole: string | null; + userID: string | null; +} + +const toRedisType = (value: unknown): RedisType => + REDIS_TYPES.includes(value as RedisType) ? (value as RedisType) : "node"; + +const CacheSettings: React.FC = ({ accessToken }) => { + const [form] = Form.useForm(); + const [redisType, setRedisType] = useState("node"); + const [embeddingModels, setEmbeddingModels] = useState([]); + const [isTesting, setIsTesting] = useState(false); + const [isSaving, setIsSaving] = useState(false); + + const loadCacheSettings = useCallback(async () => { + if (!accessToken) { + return; + } + try { + const data = (await getCacheSettingsCall(accessToken)) as { current_values?: Record }; + const currentValues = data.current_values ?? {}; + form.setFieldsValue(buildInitialValues(currentValues)); + setRedisType(toRedisType(currentValues.redis_type)); + } catch (error) { + console.error("Failed to load cache settings:", error); + NotificationsManager.fromBackend("Failed to load cache settings"); + } + }, [accessToken, form]); + + useEffect(() => { + loadCacheSettings(); + }, [loadCacheSettings]); + + useEffect(() => { + if (!accessToken) { + return; + } + fetchAvailableModels(accessToken) + .then((models: ModelGroup[]) => + setEmbeddingModels( + models + .filter((model) => model.mode === "embedding") + .map((model) => ({ value: model.model_group, label: model.model_group })), + ), + ) + .catch((error) => console.error("Error fetching embedding models:", error)); + }, [accessToken]); + + const validate = async (): Promise => { + try { + return await form.validateFields(); + } catch { + return null; + } + }; + + const handleTestConnection = async () => { + if (!accessToken) { + return; + } + const values = await validate(); + if (values === null) { + return; + } + + setIsTesting(true); + try { + const result = await testCacheConnectionCall( + accessToken, + buildCachePayload(redisType, values, { forTesting: true }), + ); + if (result.status === "success") { + NotificationsManager.success("Cache connection test successful!"); + } else { + NotificationsManager.fromBackend(`Connection test failed: ${result.message || result.error}`); + } + } catch (error) { + console.error("Test connection error:", error); + NotificationsManager.fromBackend( + `Connection test failed: ${error instanceof Error ? error.message : "Unknown error"}`, + ); + } finally { + setIsTesting(false); + } + }; + + const handleSaveChanges = async () => { + if (!accessToken) { + return; + } + const values = await validate(); + if (values === null) { + return; + } + + setIsSaving(true); + try { + await updateCacheSettingsCall(accessToken, buildCachePayload(redisType, values, { forTesting: false })); + NotificationsManager.success("Cache settings updated successfully"); + await loadCacheSettings(); + } catch (error) { + console.error("Failed to save cache settings:", error); + NotificationsManager.fromBackend("Failed to update cache settings"); + } finally { + setIsSaving(false); + } + }; + + if (!accessToken) { + return null; + } + + return ( +
+
+
+

Cache Settings

+

Configure Redis cache for LiteLLM

+
+ + setRedisType(toRedisType(type))} + /> + +
+ +
+ + {redisType === "cluster" && ( +
+ +
+ )} + + {redisType === "sentinel" && ( +
+ +
+ )} + + {redisType === "semantic" && ( +
+ +
+ )} + + + + Advanced Settings + + +
+ + + +
+
+
+ + +
+ + +
+
+ ); +}; + +export default CacheSettings; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/coordination_redis_settings/CoordinationRedisFieldSection.tsx b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/coordination_redis_settings/CoordinationRedisFieldSection.tsx new file mode 100644 index 00000000000..af807926ed5 --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/coordination_redis_settings/CoordinationRedisFieldSection.tsx @@ -0,0 +1,46 @@ +import React from "react"; +import CoordinationRedisFormField from "./CoordinationRedisFormField"; +import { fieldsForSection } from "./coordinationRedisUtils"; +import { CoordinationRedisType, CoordinationSection } from "./coordinationRedisFields"; + +interface CoordinationRedisFieldSectionProps { + title: string; + section: CoordinationSection; + redisType: CoordinationRedisType; + configuredSecrets: ReadonlySet; + gridCols?: string; + headingLevel?: "h4" | "h5"; +} + +const CoordinationRedisFieldSection: React.FC = ({ + title, + section, + redisType, + configuredSecrets, + gridCols = "grid-cols-1 gap-6 sm:grid-cols-2", + headingLevel = "h4", +}) => { + const fields = fieldsForSection(section, redisType); + if (fields.length === 0) { + return null; + } + + const Heading = headingLevel; + + return ( +
+ {title} +
+ {fields.map((field) => ( + + ))} +
+
+ ); +}; + +export default CoordinationRedisFieldSection; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/coordination_redis_settings/CoordinationRedisFormField.tsx b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/coordination_redis_settings/CoordinationRedisFormField.tsx new file mode 100644 index 00000000000..50c2a39567a --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/coordination_redis_settings/CoordinationRedisFormField.tsx @@ -0,0 +1,39 @@ +import { Form, Input, Switch } from "antd"; +import React from "react"; +import { CoordinationField } from "./coordinationRedisFields"; + +export const SECRET_ALREADY_SET_PLACEHOLDER = "Already set. Enter a new value to replace it."; + +interface CoordinationRedisFormFieldProps { + field: CoordinationField; + isSecretConfigured: boolean; +} + +const renderControl = (field: CoordinationField, placeholder: string): React.ReactNode => { + switch (field.type) { + case "boolean": + return ; + case "password": + return ; + case "integer": + return ; + case "list": + return ; + default: + return ; + } +}; + +const CoordinationRedisFormField: React.FC = ({ field, isSecretConfigured }) => ( + + {renderControl(field, isSecretConfigured ? SECRET_ALREADY_SET_PLACEHOLDER : field.helpText)} + +); + +export default CoordinationRedisFormField; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/coordination_redis_settings/CoordinationRedisTypeSelector.tsx b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/coordination_redis_settings/CoordinationRedisTypeSelector.tsx new file mode 100644 index 00000000000..daab8505890 --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/caching/_components/coordination_redis_settings/CoordinationRedisTypeSelector.tsx @@ -0,0 +1,33 @@ +import React from "react"; +import { Select } from "antd"; +import { + COORDINATION_REDIS_TYPES, + COORDINATION_REDIS_TYPE_DESCRIPTIONS, + COORDINATION_REDIS_TYPE_LABELS, + CoordinationRedisType, +} from "./coordinationRedisFields"; + +interface CoordinationRedisTypeSelectorProps { + redisType: CoordinationRedisType; + onTypeChange: (type: CoordinationRedisType) => void; +} + +const OPTIONS = COORDINATION_REDIS_TYPES.map((type) => ({ value: type, label: COORDINATION_REDIS_TYPE_LABELS[type] })); + +const CoordinationRedisTypeSelector: React.FC = ({ redisType, onTypeChange }) => ( +
+ + - {field.field_description} -
-
- ); - } - - if (field.field_type === "Integer" || field.field_type === "Float") { - return ( -
- - -

{field.field_description}

-
- ); - } - - if (field.field_type === "List") { - return ( -
- -